made the program

main
michal 3 years ago
parent 26c9c93a99
commit a9175a392f

@ -12,3 +12,6 @@ path = "src/main.rs"
[dependencies] [dependencies]
clap = { version = "2.34.0", default-features = false } clap = { version = "2.34.0", default-features = false }
toml = "0.5.8"
serde = "1.0.134"
serde_derive = "1.0.134"

@ -0,0 +1,2 @@
pub mod strings;
pub mod structs;

@ -0,0 +1,8 @@
use serde_derive::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Config {
pub mode: String,
pub name: Option<String>,
pub repo: Vec<String>,
}

@ -1,5 +1,14 @@
use std::env;
use std::process::Command;
use clap::{App, AppSettings, Arg, ArgSettings, SubCommand}; use clap::{App, AppSettings, Arg, ArgSettings, SubCommand};
use crate::workspace::read_cfg;
mod internal;
mod repository;
mod workspace;
fn main() { fn main() {
fn build_app() -> App<'static, 'static> { fn build_app() -> App<'static, 'static> {
let app = App::new("Malachite") let app = App::new("Malachite")
@ -11,7 +20,7 @@ fn main() {
.long("verbose") .long("verbose")
.multiple(true) .multiple(true)
.set(ArgSettings::Global) .set(ArgSettings::Global)
.help("Sets the level of verbosity") .help("Sets the level of verbosity"),
) )
.arg( .arg(
Arg::with_name("exclude") Arg::with_name("exclude")
@ -19,13 +28,13 @@ fn main() {
.long("exclude") .long("exclude")
.multiple(true) .multiple(true)
.set(ArgSettings::Global) .set(ArgSettings::Global)
.help("Excludes packages from given operation") .help("Excludes packages from given operation"),
) )
.arg( .arg(
Arg::with_name("all") Arg::with_name("all")
.long("all") .long("all")
.set(ArgSettings::Global) .set(ArgSettings::Global)
.help("Operates on every possible package") .help("Operates on every possible package"),
) )
.subcommand( .subcommand(
SubCommand::with_name("build") SubCommand::with_name("build")
@ -36,7 +45,11 @@ fn main() {
.required(true) .required(true)
.multiple(true) .multiple(true)
.index(1), .index(1),
) ),
)
.subcommand(
SubCommand::with_name("repo-gen")
.about("Generates repository from build packages")
) )
.subcommand( .subcommand(
SubCommand::with_name("prune") SubCommand::with_name("prune")
@ -45,18 +58,133 @@ fn main() {
Arg::with_name("days") Arg::with_name("days")
.help("How old a duplicate package needs to be (in days) to be pruned") .help("How old a duplicate package needs to be (in days) to be pruned")
.required(true) .required(true)
.index(1) .index(1),
) ),
)
.subcommand(SubCommand::with_name("init").about(
"Clones all git repositories from mlc.toml branching from current directory",
))
.subcommand(
SubCommand::with_name("pull").alias("update").about(
"Pulls all git repositories from mlc.toml branching from current directory",
),
) )
.settings(&[ .settings(&[
AppSettings::GlobalVersion, AppSettings::GlobalVersion,
AppSettings::VersionlessSubcommands, AppSettings::VersionlessSubcommands,
AppSettings::ArgRequiredElseHelp, AppSettings::ArgRequiredElseHelp,
AppSettings::InferSubcommands AppSettings::InferSubcommands,
]); ]);
app app
} }
let matches = build_app().get_matches(); let matches = build_app().get_matches();
if let true = matches.is_present("init") {
let config = workspace::read_cfg();
if config.mode == "workspace" {
for r in config.repo {
println!("Cloning (workspace mode): {}", r);
Command::new("git")
.args(&["clone", &r])
.spawn()
.unwrap()
.wait()
.unwrap();
}
} else if config.mode == "repository" {
for r in config.repo {
println!("Cloning (repository mode): {}", r);
Command::new("git")
.args(&["clone", "--no-checkout", &r])
.spawn()
.unwrap()
.wait()
.unwrap();
println!("Entering working directory: {}", r);
let dir = format!(
"{}/{}",
env::current_dir().unwrap().display(),
r.split('/').collect::<Vec<&str>>().last().unwrap()
);
env::set_current_dir(dir).unwrap();
println!("Resetting unstaged files: {}", r);
Command::new("git")
.arg("reset")
.spawn()
.unwrap()
.wait()
.unwrap();
println!("Checking out PKGBUILD: {}", r);
Command::new("git")
.args(&["checkout", "HEAD", "PKGBUILD"])
.spawn()
.unwrap()
.wait()
.unwrap();
}
} else {
panic!("Invalid mode in mlc.toml");
}
}
if let true = matches.is_present("build") {
let config = workspace::read_cfg();
if config.mode != "repository" {
panic!("Cannot build packages in workspace mode")
}
let packages: Vec<String> = matches
.subcommand()
.1
.unwrap()
.values_of("package(s)")
.unwrap()
.into_iter()
.map(|s| s.to_string())
.collect();
let mut repos: Vec<String> = vec![];
for r in config.repo {
let split = r.split('/').collect::<Vec<&str>>();
let a = split.last().unwrap();
repos.push(a.parse().unwrap());
}
for pkg in packages {
if !repos.contains(&pkg) {
panic!("Package {} not found in repos in mlc.toml", pkg);
} else {
repository::build(pkg);
}
}
}
if let true = matches.is_present("pull") {
let config = workspace::read_cfg();
for r in config.repo {
println!("Entering working directory: {}", r);
let dir = format!(
"{}/{}",
env::current_dir().unwrap().display(),
r.split('/').collect::<Vec<&str>>().last().unwrap()
);
env::set_current_dir(dir).unwrap();
Command::new("git")
.args(&["pull", &r])
.spawn()
.unwrap()
.wait()
.unwrap();
}
}
if let true = matches.is_present("repo-gen") {
let config = read_cfg();
if config.mode != "repository" {
panic!("Cannot build packages in workspace mode")
}
repository::generate();
}
} }

@ -0,0 +1,8 @@
mod package;
mod repo;
pub fn build(pkg: String) {
package::build(pkg);
}
pub fn generate() { repo::generate(); }

@ -0,0 +1,32 @@
use std::{env, fs};
use std::path::Path;
use std::process::Command;
pub fn build(pkg: String) {
let dir = env::current_dir().unwrap();
if !Path::exists("out".as_ref()) {
fs::create_dir_all("out").unwrap();
}
if !Path::exists(pkg.as_ref()) {
panic!("Git directory for {} not found, aborting", pkg);
}
env::set_current_dir(pkg).unwrap();
Command::new("updpkgsums").spawn().unwrap().wait().unwrap();
Command::new("makepkg")
.args(&["-sf", "--skippgpcheck", "--sign", "--noconfirm"])
.spawn()
.unwrap()
.wait()
.unwrap();
Command::new("bash")
.args(&["-c", "cp *.pkg.tar.zst* ../out/"])
.spawn()
.unwrap()
.wait()
.unwrap();
env::set_current_dir(dir).unwrap();
}

@ -0,0 +1,50 @@
use std::{env, fs};
use std::path::Path;
use std::process::Command;
use crate::workspace::read_cfg;
pub fn generate() {
let config = read_cfg();
let name = config.name.unwrap();
if !Path::exists(name.as_ref()) {
fs::create_dir_all(&name).unwrap();
}
Command::new("bash")
.args(&["-c", &format!("cp -v out/* {}/", &name)])
.spawn()
.unwrap()
.wait()
.unwrap();
env::set_current_dir(&name).unwrap();
let db = format!("{}.db", &name);
let files = format!("{}.files", &name);
Command::new("bash")
.args(&["-c", &format!("repo-add {}.tar.gz *.pkg.tar.zst", db)])
.spawn()
.unwrap()
.wait()
.unwrap();
Command::new("bash")
.args(&["-c", &format!("rm {}.{{db,files}}", &name)])
.spawn()
.unwrap()
.wait()
.unwrap();
Command::new("bash")
.args(&[
"-c",
&format!("mv {}.tar.gz {}; mv {}.tar.gz {}", db, db, files, files),
])
.spawn()
.unwrap()
.wait()
.unwrap();
}

@ -0,0 +1,7 @@
use crate::internal::structs::Config;
mod read;
pub fn read_cfg() -> Config {
read::read_cfg()
}

@ -0,0 +1,15 @@
use std::fs;
use std::path::Path;
use crate::internal::structs::Config;
pub fn read_cfg() -> Config {
if !Path::exists("mlc.toml".as_ref()) {
panic!("mlc.toml file not found")
}
let file = fs::read_to_string("mlc.toml").unwrap();
let config: Config = toml::from_str(&file).unwrap();
config
}
Loading…
Cancel
Save