diff --git a/README.md b/README.md index 1b51350..20035e8 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ ## Basic usage -| Action | Command | -|--------------------------------------------------------|-----------------------| +| Action | Command | +|--------------------------------------------------------|--------------| | Build a package | mlc build \ | -| Generate local repository | mlc repo-gen | -| Update local repos/PKGBUILDs | mlc pull/update | -| Create and/or open config file | mlc conf | -| Initialises repo/workspace based on config in mlc.toml | mlc init | -| Prunes old, duplicate packages from repository | mlc prune \ | +| Generate local repository | mlc repo-gen | +| Update local repos/PKGBUILDs | mlc pull/update | +| Create and/or open config file | mlc conf | +| Initialises repo/workspace based on config in mlc.toml | mlc init | +| Prunes old duplicate packages from repository | mlc prune | ### Pacman Repository Creation diff --git a/src/internal/structs.rs b/src/internal/structs.rs index 973dd82..0bedb11 100755 --- a/src/internal/structs.rs +++ b/src/internal/structs.rs @@ -18,5 +18,5 @@ pub struct UnexpandedConfig { #[derive(Debug)] pub struct SplitRepo { pub indx: usize, - pub name: String -} \ No newline at end of file + pub name: String, +} diff --git a/src/main.rs b/src/main.rs index 7cad5ec..55137d4 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ -use std::env; use std::path::Path; use std::process::Command; +use std::{env, fs}; use crate::internal::{crash, info}; -use clap::{App, AppSettings, Arg, ArgSettings, SubCommand}; use crate::repository::create_config; +use clap::{App, AppSettings, Arg, ArgSettings, SubCommand}; use crate::workspace::read_cfg; @@ -49,7 +49,7 @@ fn main() { Arg::with_name("all") .long("all") .help("Builds all packages in mlc.toml (except if -x is specified)") - .conflicts_with("package(s)") + .conflicts_with("package(s)"), ) .arg( Arg::with_name("exclude") @@ -57,21 +57,21 @@ fn main() { .long("exclude") .multiple(true) .takes_value(true) - .help("Excludes packages from given operation") + .help("Excludes packages from given operation"), ) + .arg( + Arg::with_name("regen") + .short("r") + .long("regen") + .help("Regenerates repository after building give package(s)"), + ), ) .subcommand( SubCommand::with_name("repo-gen").about("Generates repository from built packages"), ) .subcommand( SubCommand::with_name("prune") - .about("Prunes duplicate packages older than X days from the repository") - .arg( - Arg::with_name("days") - .help("How old a duplicate package needs to be (in days) to be pruned") - .required(true) - .index(1), - ), + .about("Prunes duplicate packages from the repository"), ) .subcommand(SubCommand::with_name("init").about( "Clones all git repositories from mlc.toml branching from current directory", @@ -95,7 +95,6 @@ fn main() { let matches = build_app().get_matches(); - if let true = matches.is_present("init") { let config = workspace::read_cfg(); if config.mode == "workspace" { @@ -156,14 +155,12 @@ fn main() { let mut packages: Vec = matches .subcommand_matches("build") .unwrap() - .values_of_lossy("package(s)") - .unwrap_or(vec![]); + .values_of_lossy("package(s)").unwrap_or_default(); let exclude: Vec = matches .subcommand_matches("build") .unwrap() - .values_of_lossy("exclude") - .unwrap_or(vec![]); + .values_of_lossy("exclude").unwrap_or_default(); for pkg in &exclude { packages.retain(|x| &*x != pkg); @@ -180,7 +177,11 @@ fn main() { repos.push(a.parse().unwrap()); } - if matches.subcommand_matches("build").unwrap().is_present("exclude") { + if matches + .subcommand_matches("build") + .unwrap() + .is_present("exclude") + { for ex in exclude { repos.retain(|x| *x != ex); } @@ -194,11 +195,23 @@ fn main() { } } - if matches.subcommand_matches("build").unwrap().is_present("all") { + if matches + .subcommand_matches("build") + .unwrap() + .is_present("all") + { for pkg in repos { repository::build(pkg); } } + + if matches + .subcommand_matches("build") + .unwrap() + .is_present("regen") + { + repository::generate(); + } } if let true = matches.is_present("pull") { @@ -227,9 +240,61 @@ fn main() { if config.mode != "repository" { panic!("Cannot build packages in workspace mode") } + info(format!("Generating repository: {}", config.name.unwrap())); repository::generate(); } + if let true = matches.is_present("prune") { + let config = read_cfg(); + if &config.mode != "repository" { + panic!("Cannot build packages in workspace mode") + } + let mut packages = vec![]; + for untrimmed_repo in &config.repo { + pub fn trim_repo(a: String) -> String { + (a.split('/') + .map(|s| s.to_string()) + .collect::>() + .last() + .unwrap()) + .to_string() + } + packages.push(trim_repo(untrimmed_repo.to_string())); + } + + let mut packages_to_del = vec![]; + + for pkg in packages { + let dups = Command::new("bash") + .args(&["-c", &format!("ls out/{}*.tar.zst -w 1 | sort -r", pkg)]) + .output() + .unwrap() + .stdout + .to_ascii_lowercase(); + + let duplicates = String::from_utf8_lossy(&dups); + let duplicates_lines = duplicates.lines().collect::>(); + let variable_hell = duplicates_lines.iter().skip(1).collect::>(); + + if !variable_hell.is_empty() { + for var in variable_hell { + packages_to_del.push(var.to_string()); + } + } + } + + if !packages_to_del.is_empty() { + info(format!( + "Pruning duplicates: {}", + packages_to_del.join(", ") + )); + } + + for pkg in packages_to_del { + fs::remove_file(pkg).unwrap(); + } + } + if let true = matches.is_present("config") { if !Path::exists("mlc.toml".as_ref()) { create_config(); diff --git a/src/repository/config.rs b/src/repository/config.rs index c62fc76..dab8a1f 100644 --- a/src/repository/config.rs +++ b/src/repository/config.rs @@ -1,8 +1,8 @@ +use crate::crash; use std::env; use std::fs::File; use std::io::Write; use std::path::Path; -use crate::crash; const DEFAULT_CONFIG: &str = r#"mode = "" # either "repository" or "workspace" name = "" # only required when in repository mode, decides what to call the repository and relevant files @@ -10,11 +10,21 @@ repo = [""] # an array of git repos to clone from, formatted url_index::repo_nam urls = [""] # an array of urls to clone from, in the format https://example.com/%repo% (the %repo% is NOT optional)"#; pub fn create_config() { - if env::current_dir().unwrap().read_dir().unwrap().next().is_some() { - crash("Directory is not empty, please only create a repository in an empty directory".to_string(), 6); + if env::current_dir() + .unwrap() + .read_dir() + .unwrap() + .next() + .is_some() + { + crash( + "Directory is not empty, please only create a repository in an empty directory" + .to_string(), + 6, + ); } if !Path::exists("mlc.toml".as_ref()) { let mut file = File::create("mlc.toml").unwrap(); file.write_all(DEFAULT_CONFIG.as_ref()).unwrap(); } -} \ No newline at end of file +} diff --git a/src/repository/mod.rs b/src/repository/mod.rs index ecb4ec3..cadf498 100755 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -1,6 +1,6 @@ +mod config; mod package; mod repo; -mod config; pub fn build(pkg: String) { package::build(pkg); @@ -12,4 +12,4 @@ pub fn generate() { pub fn create_config() { config::create_config(); -} \ No newline at end of file +} diff --git a/src/repository/repo.rs b/src/repository/repo.rs index 0aab7cc..1064e0c 100644 --- a/src/repository/repo.rs +++ b/src/repository/repo.rs @@ -8,10 +8,12 @@ pub fn generate() { let config = read_cfg(); let name = config.name.unwrap(); - if !Path::exists(name.as_ref()) { - fs::create_dir_all(&name).unwrap(); + if Path::exists(name.as_ref()) { + fs::remove_dir_all(&name).unwrap(); } + fs::create_dir_all(&name).unwrap(); + Command::new("bash") .args(&["-c", &format!("cp -v out/* {}/", &name)]) .spawn() diff --git a/src/workspace/read.rs b/src/workspace/read.rs index 165f8d0..a47b921 100755 --- a/src/workspace/read.rs +++ b/src/workspace/read.rs @@ -23,21 +23,19 @@ pub fn read_cfg() -> Config { let config_repos = config.repo; for x in config_repos { - let split: Vec<&str> = x.split("::").collect(); - let sr_struct = SplitRepo { - indx: (&split[0]).parse().unwrap(), - name: (&split[1]).parse().unwrap() - }; - let index = sr_struct.indx; - let expanded = format!("{}{}", trimmed_urls[index-1], sr_struct.name); - println!("{}", expanded); - expanded_repos.push(expanded); + let split: Vec<&str> = x.split("::").collect(); + let sr_struct = SplitRepo { + indx: split[0].parse().unwrap(), + name: split[1].parse().unwrap(), + }; + let index = sr_struct.indx; + let expanded = format!("{}{}", trimmed_urls[index - 1], sr_struct.name); + expanded_repos.push(expanded); } Config { mode: config.mode, name: config.name, - repo: expanded_repos + repo: expanded_repos, } - } \ No newline at end of file