implemented prune and some other stuff i think

main
michal 3 years ago
parent ec1aeee779
commit 9deac085e1

@ -13,13 +13,13 @@
## Basic usage ## Basic usage
| Action | Command | | Action | Command |
|--------------------------------------------------------|-----------------------| |--------------------------------------------------------|--------------|
| Build a package | mlc build \<package\> | | Build a package | mlc build \<package\> |
| Generate local repository | mlc repo-gen | | Generate local repository | mlc repo-gen |
| Update local repos/PKGBUILDs | mlc pull/update | | Update local repos/PKGBUILDs | mlc pull/update |
| Create and/or open config file | mlc conf | | Create and/or open config file | mlc conf |
| Initialises repo/workspace based on config in mlc.toml | mlc init | | Initialises repo/workspace based on config in mlc.toml | mlc init |
| Prunes old, duplicate packages from repository | mlc prune \<days\> | | Prunes old duplicate packages from repository | mlc prune |
### Pacman Repository Creation ### Pacman Repository Creation

@ -18,5 +18,5 @@ pub struct UnexpandedConfig {
#[derive(Debug)] #[derive(Debug)]
pub struct SplitRepo { pub struct SplitRepo {
pub indx: usize, pub indx: usize,
pub name: String pub name: String,
} }

@ -1,10 +1,10 @@
use std::env;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::{env, fs};
use crate::internal::{crash, info}; use crate::internal::{crash, info};
use clap::{App, AppSettings, Arg, ArgSettings, SubCommand};
use crate::repository::create_config; use crate::repository::create_config;
use clap::{App, AppSettings, Arg, ArgSettings, SubCommand};
use crate::workspace::read_cfg; use crate::workspace::read_cfg;
@ -49,7 +49,7 @@ fn main() {
Arg::with_name("all") Arg::with_name("all")
.long("all") .long("all")
.help("Builds all packages in mlc.toml (except if -x is specified)") .help("Builds all packages in mlc.toml (except if -x is specified)")
.conflicts_with("package(s)") .conflicts_with("package(s)"),
) )
.arg( .arg(
Arg::with_name("exclude") Arg::with_name("exclude")
@ -57,21 +57,21 @@ fn main() {
.long("exclude") .long("exclude")
.multiple(true) .multiple(true)
.takes_value(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(
SubCommand::with_name("repo-gen").about("Generates repository from built packages"), SubCommand::with_name("repo-gen").about("Generates repository from built packages"),
) )
.subcommand( .subcommand(
SubCommand::with_name("prune") SubCommand::with_name("prune")
.about("Prunes duplicate packages older than X days from the repository") .about("Prunes duplicate packages 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),
),
) )
.subcommand(SubCommand::with_name("init").about( .subcommand(SubCommand::with_name("init").about(
"Clones all git repositories from mlc.toml branching from current directory", "Clones all git repositories from mlc.toml branching from current directory",
@ -95,7 +95,6 @@ fn main() {
let matches = build_app().get_matches(); let matches = build_app().get_matches();
if let true = matches.is_present("init") { if let true = matches.is_present("init") {
let config = workspace::read_cfg(); let config = workspace::read_cfg();
if config.mode == "workspace" { if config.mode == "workspace" {
@ -156,14 +155,12 @@ fn main() {
let mut packages: Vec<String> = matches let mut packages: Vec<String> = matches
.subcommand_matches("build") .subcommand_matches("build")
.unwrap() .unwrap()
.values_of_lossy("package(s)") .values_of_lossy("package(s)").unwrap_or_default();
.unwrap_or(vec![]);
let exclude: Vec<String> = matches let exclude: Vec<String> = matches
.subcommand_matches("build") .subcommand_matches("build")
.unwrap() .unwrap()
.values_of_lossy("exclude") .values_of_lossy("exclude").unwrap_or_default();
.unwrap_or(vec![]);
for pkg in &exclude { for pkg in &exclude {
packages.retain(|x| &*x != pkg); packages.retain(|x| &*x != pkg);
@ -180,7 +177,11 @@ fn main() {
repos.push(a.parse().unwrap()); 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 { for ex in exclude {
repos.retain(|x| *x != ex); 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 { for pkg in repos {
repository::build(pkg); repository::build(pkg);
} }
} }
if matches
.subcommand_matches("build")
.unwrap()
.is_present("regen")
{
repository::generate();
}
} }
if let true = matches.is_present("pull") { if let true = matches.is_present("pull") {
@ -227,9 +240,61 @@ fn main() {
if config.mode != "repository" { if config.mode != "repository" {
panic!("Cannot build packages in workspace mode") panic!("Cannot build packages in workspace mode")
} }
info(format!("Generating repository: {}", config.name.unwrap()));
repository::generate(); 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::<Vec<String>>()
.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::<Vec<&str>>();
let variable_hell = duplicates_lines.iter().skip(1).collect::<Vec<&&str>>();
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 let true = matches.is_present("config") {
if !Path::exists("mlc.toml".as_ref()) { if !Path::exists("mlc.toml".as_ref()) {
create_config(); create_config();

@ -1,8 +1,8 @@
use crate::crash;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use std::path::Path; use std::path::Path;
use crate::crash;
const DEFAULT_CONFIG: &str = r#"mode = "" # either "repository" or "workspace" 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 name = "" # only required when in repository mode, decides what to call the repository and relevant files
@ -10,8 +10,18 @@ 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)"#; urls = [""] # an array of urls to clone from, in the format https://example.com/%repo% (the %repo% is NOT optional)"#;
pub fn create_config() { pub fn create_config() {
if env::current_dir().unwrap().read_dir().unwrap().next().is_some() { if env::current_dir()
crash("Directory is not empty, please only create a repository in an empty directory".to_string(), 6); .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()) { if !Path::exists("mlc.toml".as_ref()) {
let mut file = File::create("mlc.toml").unwrap(); let mut file = File::create("mlc.toml").unwrap();

@ -1,6 +1,6 @@
mod config;
mod package; mod package;
mod repo; mod repo;
mod config;
pub fn build(pkg: String) { pub fn build(pkg: String) {
package::build(pkg); package::build(pkg);

@ -8,10 +8,12 @@ pub fn generate() {
let config = read_cfg(); let config = read_cfg();
let name = config.name.unwrap(); let name = config.name.unwrap();
if !Path::exists(name.as_ref()) { if Path::exists(name.as_ref()) {
fs::create_dir_all(&name).unwrap(); fs::remove_dir_all(&name).unwrap();
} }
fs::create_dir_all(&name).unwrap();
Command::new("bash") Command::new("bash")
.args(&["-c", &format!("cp -v out/* {}/", &name)]) .args(&["-c", &format!("cp -v out/* {}/", &name)])
.spawn() .spawn()

@ -25,19 +25,17 @@ pub fn read_cfg() -> Config {
for x in config_repos { for x in config_repos {
let split: Vec<&str> = x.split("::").collect(); let split: Vec<&str> = x.split("::").collect();
let sr_struct = SplitRepo { let sr_struct = SplitRepo {
indx: (&split[0]).parse().unwrap(), indx: split[0].parse().unwrap(),
name: (&split[1]).parse().unwrap() name: split[1].parse().unwrap(),
}; };
let index = sr_struct.indx; let index = sr_struct.indx;
let expanded = format!("{}{}", trimmed_urls[index-1], sr_struct.name); let expanded = format!("{}{}", trimmed_urls[index - 1], sr_struct.name);
println!("{}", expanded);
expanded_repos.push(expanded); expanded_repos.push(expanded);
} }
Config { Config {
mode: config.mode, mode: config.mode,
name: config.name, name: config.name,
repo: expanded_repos repo: expanded_repos,
} }
} }
Loading…
Cancel
Save