diff --git a/src/args.rs b/src/args.rs index 081ff16..42b6ed9 100644 --- a/src/args.rs +++ b/src/args.rs @@ -7,8 +7,8 @@ pub struct Args { pub subcommand: Option, /// Sets the level of verbosity - #[clap(long, short, global(true), action = ArgAction::Count)] - pub verbose: u8, + #[clap(long, short, global(true), action = ArgAction::SetTrue)] + pub verbose: bool, /// Complete operations without prompting user #[clap(long = "noconfirm", global(true), action = ArgAction::SetTrue)] diff --git a/src/internal/strings.rs b/src/internal/strings.rs index 737678d..287f027 100755 --- a/src/internal/strings.rs +++ b/src/internal/strings.rs @@ -10,14 +10,14 @@ const ERR_SYMBOL: &str = "❌"; #[macro_export] macro_rules! info { ($($arg:tt)+) => { - $crate::internal::strings::info_fn(format!($($arg)+)) + $crate::internal::strings::info_fn(format!($($arg)+)); } } #[macro_export] macro_rules! log { - ($($arg:tt)+) => { - $crate::internal::strings::log_fn(format!($($arg)+)) + ($verbose:expr, $($arg:tt)+) => { + $crate::internal::strings::log_fn(format!($($arg)+), $verbose); } } @@ -28,15 +28,23 @@ macro_rules! crash { } } - pub fn info_fn(msg: S) { let msg = msg.to_string(); println!("{} {}", LOGO_SYMBOL.black(), msg.bold()) } -pub fn log_fn(msg: S) { +pub fn log_fn(msg: S, verbose: bool) { let msg = msg.to_string(); - eprintln!("{} {}", std::time::SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(), msg) + if verbose { + eprintln!( + "{} {}", + std::time::SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs(), + msg + ); + } } pub fn crash_fn(msg: S, exit_code: AppExitCode) { diff --git a/src/main.rs b/src/main.rs index 47e8879..97e1297 100755 --- a/src/main.rs +++ b/src/main.rs @@ -37,6 +37,7 @@ fn main() { } let exclude = &args.exclude; + let verbose = args.verbose; if Path::exists("../.git".as_ref()) { info!("Parent directory is a git directory, pulling latest mlc.toml. It is advised you run mlc pull/update in all malachite directories"); @@ -52,13 +53,13 @@ fn main() { } match args.subcommand.unwrap_or(Operation::Clone) { - Operation::Clone => operations::clone(), + Operation::Clone => operations::clone(verbose), Operation::Build { packages, no_regen, .. - } => operations::build(packages, exclude.to_vec(), no_regen), - Operation::Pull { packages, .. } => operations::pull(packages, exclude.to_vec()), + } => operations::build(packages, exclude.to_vec(), no_regen, verbose), + Operation::Pull { packages, .. } => operations::pull(packages, exclude.to_vec(), verbose), Operation::RepoGen => { - let config = read_cfg(); + let config = read_cfg(verbose); if config.mode != "repository" { crash!( AppExitCode::BuildInWorkspace, @@ -66,9 +67,9 @@ fn main() { ) } info!("Generating repository: {}", config.name.unwrap()); - repository::generate(); + repository::generate(verbose); } - Operation::Config => operations::config(), - Operation::Clean => operations::clean(), + Operation::Config => operations::config(verbose), + Operation::Clean => operations::clean(verbose), } } diff --git a/src/operations/build.rs b/src/operations/build.rs index b16e68b..d7a5015 100644 --- a/src/operations/build.rs +++ b/src/operations/build.rs @@ -1,31 +1,36 @@ -use crate::internal::structs::{ErroredPackage, Repo}; -use crate::internal::AppExitCode; use crate::{crash, info, log, repository, workspace}; +use crate::internal::AppExitCode; +use crate::internal::structs::{ErroredPackage, Repo}; -pub fn build(packages: Vec, exclude: Vec, no_regen: bool) { +pub fn build(packages: Vec, exclude: Vec, no_regen: bool, verbose: bool) { // Read config struct from mlc.toml - let config = workspace::read_cfg(); - log!("Config: {:?}", config); + let config = workspace::read_cfg(verbose); + log!(verbose, "Config: {:?}", config); let all = packages.is_empty(); - log!("All: {:?}", all); - log!("Signing: {:?}", config.sign); + log!(verbose, "All: {:?}", all); + log!(verbose, "Signing: {:?}", config.sign); // Get list of repos and subtract exclude let mut repos: Vec = config.repo; - log!("{} Repos: {:?}", repos.len(), repos ); + log!(verbose, "{} Repos: {:?}", repos.len(), repos); if !exclude.is_empty() { - log!("Exclude not empty: {:?}", exclude); + log!(verbose, "Exclude not empty: {:?}", exclude); for ex in exclude { repos.retain(|x| *x.name != ex); } } - log!("Exclusions parsed. Now {} Repos: {:?}", repos.len(), repos); + log!( + verbose, + "Exclusions parsed. Now {} Repos: {:?}", + repos.len(), + repos + ); // If packages is not empty and all isn't specified, build specified packages let mut errored: Vec = vec![]; if !packages.is_empty() && !all { - log!("Packages not empty: {:?}", packages); + log!(verbose, "Packages not empty: {:?}", packages); for pkg in &packages { // If repo is not in config, crash if !repos.iter().map(|x| x.name.clone()).any(|x| x == *pkg) { @@ -36,9 +41,14 @@ pub fn build(packages: Vec, exclude: Vec, no_regen: bool) { ); } else { // Otherwise, build - log!("Building {}", pkg); - let code = repository::build(pkg, config.sign); - log!("Package {} finished with exit code: {:?}", pkg, code); + log!(verbose, "Building {}", pkg); + let code = repository::build(pkg, config.sign, verbose); + log!( + verbose, + "Package {} finished with exit code: {:?}", + pkg, + code + ); if code != 0 { let error = ErroredPackage { name: pkg.to_string(), @@ -52,16 +62,21 @@ pub fn build(packages: Vec, exclude: Vec, no_regen: bool) { // If all is specified, attempt to build a package from all repos if all { - log!("Proceeding to build all"); + log!(verbose, "Proceeding to build all"); // Sort by package priority - log!("Sorting by priority: {:?}", repos); + log!(verbose, "Sorting by priority: {:?}", repos); repos.sort_by(|a, b| b.priority.cmp(&a.priority)); - log!("Sorted: {:?}", repos); + log!(verbose, "Sorted: {:?}", repos); for pkg in repos { - log!("Building {}", pkg.name); - let code = repository::build(&pkg.name, config.sign); - log!("Package {} finished with exit code: {:?}", pkg.name, code); + log!(verbose, "Building {}", pkg.name); + let code = repository::build(&pkg.name, config.sign, verbose); + log!( + verbose, + "Package {} finished with exit code: {:?}", + pkg.name, + code + ); if code != 0 { let error = ErroredPackage { name: pkg.name, @@ -74,14 +89,14 @@ pub fn build(packages: Vec, exclude: Vec, no_regen: bool) { // If all is not specified, but packages is empty, crash if !all && packages.is_empty() { - log!("Packages empty. Crashing"); + log!(verbose, "Packages empty. Crashing"); crash!(AppExitCode::NoPkgs, "No packages specified"); } // If no_regen is passed, do not generate a repository if !no_regen { - log!("Generating repository"); - repository::generate(); + log!(verbose, "Generating repository"); + repository::generate(verbose); } // Map errored packages to a string for display @@ -92,10 +107,10 @@ pub fn build(packages: Vec, exclude: Vec, no_regen: bool) { // If errored is not empty, let the user know which packages failed if !errored.is_empty() { - log!("Errored packages: \n{:?}", error_strings); + log!(verbose, "Errored packages: \n{:?}", error_strings); info!( "The following packages build jobs returned a non-zero exit code: {}", error_strings.join("\n") - ) + ); } } diff --git a/src/operations/clean.rs b/src/operations/clean.rs index a2d4c9f..f454ada 100644 --- a/src/operations/clean.rs +++ b/src/operations/clean.rs @@ -1,17 +1,17 @@ use crate::{info, log}; -pub fn clean() { +pub fn clean(verbose: bool) { info!("Resetting mlc repo, deleting all directories"); // Get a vec of all files/dirs in the current directory let dir_paths = std::fs::read_dir("./").unwrap(); - log!("Paths: {:?}", dir_paths); + log!(verbose, "Paths: {:?}", dir_paths); let mut dirs = dir_paths .map(|x| x.unwrap().path().display().to_string()) .collect::>(); // Remove all files/dirs in the current directory, excluding ./mlc.toml dirs.retain(|x| *x != "./mlc.toml"); - log!("Paths with mlc.toml excluded: {:?}", dirs); + log!(verbose, "Paths with mlc.toml excluded: {:?}", dirs); for dir in dirs { std::fs::remove_dir_all(dir).unwrap(); } diff --git a/src/operations/clone.rs b/src/operations/clone.rs index 12bc803..837909e 100644 --- a/src/operations/clone.rs +++ b/src/operations/clone.rs @@ -1,13 +1,13 @@ use std::process::Command; -use crate::{info, workspace, log}; +use crate::{info, log, workspace}; -pub fn clone() { +pub fn clone(verbose: bool) { // Read config struct from mlc.toml - let config = workspace::read_cfg(); - log!("Config: {:?}", config); + let config = workspace::read_cfg(verbose); + log!(verbose, "Config: {:?}", config); let repos = &config.repo; - log!("Repos: {:?}", repos); + log!(verbose, "Repos: {:?}", repos); // Get a vector of all files/dirs in the current directory, excluding config file let dir_paths = std::fs::read_dir("./").unwrap(); @@ -15,7 +15,7 @@ pub fn clone() { .map(|x| x.unwrap().path().display().to_string()) .collect::>(); dirs.retain(|x| *x != "./mlc.toml"); - log!("Paths with mlc.toml excluded: {:?}", dirs); + log!(verbose, "Paths with mlc.toml excluded: {:?}", dirs); // Creates a vector of the difference between cloned repos and repos defined in config let mut repo_diff = vec![]; @@ -29,10 +29,10 @@ pub fn clone() { // Diff logic if repo_diff.is_empty() { // No diff, do nothing - log!("No diff"); + log!(verbose, "No diff"); info!("All repos are already cloned"); } else { - log!("Diff: {:?}", repo_diff); + log!(verbose, "Diff: {:?}", repo_diff); // This is just for pretty display purposes let display = repo_diff .iter() @@ -43,7 +43,7 @@ pub fn clone() { // Clone all diff repos for r in repo_diff { - log!("Cloning {}", r.name); + log!(verbose, "Cloning {}", r.name); info!("Cloning ({} mode): {}", config.mode, r.name); Command::new("git") .args(&["clone", &r.url, &r.name]) diff --git a/src/operations/config.rs b/src/operations/config.rs index e06b9de..ea8f701 100644 --- a/src/operations/config.rs +++ b/src/operations/config.rs @@ -4,16 +4,16 @@ use std::process::Command; use crate::{create_config, log}; -pub fn config() { +pub fn config(verbose: bool) { // Generate new config file if not already present if !Path::exists("mlc.toml".as_ref()) { - log!("Creating mlc.toml"); - create_config(); + log!(verbose, "Creating mlc.toml"); + create_config(verbose); } // Open config file in user's editor of choice let editor = env::var("EDITOR").unwrap_or_else(|_| "nano".to_string()); - log!("Opening mlc.toml in {}", editor); + log!(verbose, "Opening mlc.toml in {}", editor); Command::new(editor) .arg("mlc.toml") .spawn() diff --git a/src/operations/pull.rs b/src/operations/pull.rs index 004313c..cdab0fa 100644 --- a/src/operations/pull.rs +++ b/src/operations/pull.rs @@ -1,18 +1,18 @@ use std::env; use std::process::Command; -use crate::info; use crate::{crash, internal::AppExitCode, log}; +use crate::info; -fn do_the_pulling(repos: Vec) { +fn do_the_pulling(repos: Vec, verbose: bool) { for repo in repos { // Set root dir to return after each git pull let root_dir = env::current_dir().unwrap(); - log!("Root dir: {:?}", root_dir); + log!(verbose, "Root dir: {:?}", root_dir); info!("Entering working directory: {}", &repo); env::set_current_dir(repo).unwrap(); - log!("Current dir: {:?}", env::current_dir().unwrap()); - log!("Pulling"); + log!(verbose, "Current dir: {:?}", env::current_dir().unwrap()); + log!(verbose, "Pulling"); Command::new("git") .arg("pull") .spawn() @@ -22,26 +22,30 @@ fn do_the_pulling(repos: Vec) { // Return to root dir env::set_current_dir(root_dir).unwrap(); - log!("Returned to root dir: {:?}", env::current_dir().unwrap()); + log!( + verbose, + "Returned to root dir: {:?}", + env::current_dir().unwrap() + ); } } -pub fn pull(packages: Vec, exclude: Vec) { +pub fn pull(packages: Vec, exclude: Vec, verbose: bool) { // If no packages are specified, imply all let all = packages.is_empty(); - log!("All: {}", all); + log!(verbose, "All: {}", all); // Read repos from config file - let repos = crate::workspace::read_cfg() + let repos = crate::workspace::read_cfg(verbose) .repo .iter() .map(|x| x.name.clone()) .collect::>(); - log!("Repos: {:?}", repos); + log!(verbose, "Repos: {:?}", repos); // Set repos_applicable for next function let mut repos_applicable = if all { repos } else { packages }; - log!("Repos applicable: {:?}", repos_applicable); + log!(verbose, "Repos applicable: {:?}", repos_applicable); // Subtract exclude from repos_applicable if !exclude.is_empty() { @@ -49,8 +53,8 @@ pub fn pull(packages: Vec, exclude: Vec) { repos_applicable.retain(|x| *x != *ex); } } - log!("Exclude: {:?}", exclude); - log!("Repos applicable excluded: {:?}", repos_applicable); + log!(verbose, "Exclude: {:?}", exclude); + log!(verbose, "Repos applicable excluded: {:?}", repos_applicable); // If all is not specified and packages is empty, crash if repos_applicable.is_empty() { @@ -58,6 +62,6 @@ pub fn pull(packages: Vec, exclude: Vec) { } // Pull! - log!("Pulling {:?}", repos_applicable); - do_the_pulling(repos_applicable); + log!(verbose, "Pulling {:?}", repos_applicable); + do_the_pulling(repos_applicable, verbose); } diff --git a/src/repository/config.rs b/src/repository/config.rs index 7ac3b2a..29a1c3a 100644 --- a/src/repository/config.rs +++ b/src/repository/config.rs @@ -29,7 +29,7 @@ urls = [ "" ]"#; -pub fn create_config() { +pub fn create_config(verbose: bool) { // Ensure current directory is empty if env::current_dir() .unwrap() @@ -43,12 +43,12 @@ pub fn create_config() { "Directory is not empty, please only create a repository in an empty directory" ); } - log!("Creating config file"); + log!(verbose, "Creating config file"); // If config file exists, create it if !Path::exists("mlc.toml".as_ref()) { let mut file = File::create("mlc.toml").unwrap(); file.write_all(DEFAULT_CONFIG.as_ref()).unwrap(); } - log!("Config file created"); + log!(verbose, "Config file created"); } diff --git a/src/repository/package.rs b/src/repository/package.rs index 1ae02df..73d8c9e 100755 --- a/src/repository/package.rs +++ b/src/repository/package.rs @@ -1,20 +1,20 @@ +use std::{env, fs}; use std::path::Path; use std::process::Command; -use std::{env, fs}; use crate::{crash, log}; use crate::internal::AppExitCode; -pub fn build(pkg: &str, sign: bool) -> i32 { - log!("Building {}", pkg); - log!("Signing: {}", sign); +pub fn build(pkg: &str, sign: bool, verbose: bool) -> i32 { + log!(verbose, "Building {}", pkg); + log!(verbose, "Signing: {}", sign); // Set root dir to return after build let dir = env::current_dir().unwrap(); - log!("Root dir: {:?}", dir); + log!(verbose, "Root dir: {:?}", dir); // Create out dir if not already present if !Path::exists("out".as_ref()) { - log!("Creating out dir"); + log!(verbose, "Creating out dir"); fs::create_dir_all("out").unwrap(); } @@ -29,7 +29,7 @@ pub fn build(pkg: &str, sign: bool) -> i32 { // Enter build directory env::set_current_dir(pkg).unwrap(); - log!("Current dir: {:?}", env::current_dir().unwrap()); + log!(verbose, "Current dir: {:?}", env::current_dir().unwrap()); // Build each package let a = Command::new("makepkg") @@ -43,7 +43,7 @@ pub fn build(pkg: &str, sign: bool) -> i32 { .unwrap() .wait() .unwrap(); - log!("{} Build job returned: {:?}", pkg, a); + log!(verbose, "{} Build job returned: {:?}", pkg, a); // Copy built package to out dir Command::new("bash") @@ -52,11 +52,15 @@ pub fn build(pkg: &str, sign: bool) -> i32 { .unwrap() .wait() .unwrap(); - log!("Copied built package to out dir"); + log!(verbose, "Copied built package to out dir"); // Return to root dir env::set_current_dir(dir).unwrap(); - log!("Returned to root dir: {:?}", env::current_dir().unwrap()); + log!( + verbose, + "Returned to root dir: {:?}", + env::current_dir().unwrap() + ); // Return exit code a.code().unwrap() diff --git a/src/repository/repo.rs b/src/repository/repo.rs index 9fcb254..fe5b629 100644 --- a/src/repository/repo.rs +++ b/src/repository/repo.rs @@ -1,27 +1,27 @@ +use std::{env, fs}; use std::path::Path; use std::process::Command; -use std::{env, fs}; -use crate::{workspace::read_cfg, log}; +use crate::{log, workspace::read_cfg}; -pub fn generate() { +pub fn generate(verbose: bool) { // Read config struct from mlc.toml - let config = read_cfg(); - log!("Config: {:?}", config); + let config = read_cfg(verbose); + log!(verbose, "Config: {:?}", config); // Get repository name from config let name = config.name.unwrap(); - log!("Name: {}", name); + log!(verbose, "Name: {}", name); // If repository exists, delete it if Path::exists(name.as_ref()) { - log!("Deleting {}", name); + log!(verbose, "Deleting {}", name); fs::remove_dir_all(&name).unwrap(); } // Create or recreate repository directory fs::create_dir_all(&name).unwrap(); - log!("Created {}", name); + log!(verbose, "Created {}", name); // Copy out packages to repository directory Command::new("bash") @@ -30,11 +30,11 @@ pub fn generate() { .unwrap() .wait() .unwrap(); - log!("Copied out packages to {}", name); + log!(verbose, "Copied out packages to {}", name); // Enter repository directory env::set_current_dir(&name).unwrap(); - log!("Current dir: {:?}", env::current_dir().unwrap()); + log!(verbose, "Current dir: {:?}", env::current_dir().unwrap()); let db = format!("{}.db", &name); let files = format!("{}.files", &name); @@ -49,7 +49,7 @@ pub fn generate() { .unwrap() .wait() .unwrap(); - log!("Created {} and {}", db, files); + log!(verbose, "Created {} and {}", db, files); // Replace repo.{db,files}.tar.gz with just repo.{db,files} Command::new("bash") @@ -61,5 +61,12 @@ pub fn generate() { .unwrap() .wait() .unwrap(); - log!("Renamed {}.tar.gz to {} and {}.tar.gz to {}", db, db, files, files); + log!( + verbose, + "Renamed {}.tar.gz to {} and {}.tar.gz to {}", + db, + db, + files, + files + ); } diff --git a/src/workspace/read.rs b/src/workspace/read.rs index 0a144f2..681aeb9 100755 --- a/src/workspace/read.rs +++ b/src/workspace/read.rs @@ -1,11 +1,11 @@ use std::fs; use std::path::Path; -use crate::crash; -use crate::internal::structs::{Config, Repo, SplitRepo, UnexpandedConfig}; +use crate::{crash, log}; use crate::internal::AppExitCode; +use crate::internal::structs::{Config, Repo, SplitRepo, UnexpandedConfig}; -pub fn read_cfg() -> Config { +pub fn read_cfg(verbose: bool) -> Config { // Crash if mlc.toml doesn't exist if !Path::exists("mlc.toml".as_ref()) { crash!( @@ -17,6 +17,7 @@ pub fn read_cfg() -> Config { // Reading the config file to an UnexpandedConfig struct let file = fs::read_to_string("mlc.toml").unwrap(); let config: UnexpandedConfig = toml::from_str(&file).unwrap(); + log!(verbose, "Config file read: {:?}", config); // Crash if incorrect mode is set if config.mode != "workspace" && config.mode != "repository" { @@ -30,12 +31,14 @@ pub fn read_cfg() -> Config { // Parsing repos from the config file for x in config.repo { + log!(verbose, "Parsing repo: {:?}", x); // Splits the repo name and index inta a SplitRepo struct let split: Vec<&str> = x.split("::").collect(); let split_struct = SplitRepo { indx: split[0].parse().unwrap(), name: split[1].parse().unwrap(), }; + log!(verbose, "Split repo: {:?}", split_struct); // Parses all necessary values for expanding the repo to a Repo struct let index = split_struct.indx; @@ -49,14 +52,17 @@ pub fn read_cfg() -> Config { url, priority: *priority, }; + log!(verbose, "Expanded repo: {:?}", repo); expanded_repos.push(repo); } // Returns parsed config file - Config { + let conf = Config { mode: config.mode, sign: config.sign, name: config.name, repo: expanded_repos, - } + }; + log!(verbose, "Config: {:?}", conf); + conf }