From 236c16d824a15c3e8bd81612d7006943ecf96c44 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 Jul 2022 17:58:38 +0100 Subject: [PATCH] Added dirty checking to `mlc clean` and `--force` arg to counteract it --- docs/USAGE.md | 17 ++++++++-------- examples/workspace/mlc.toml | 2 +- src/args.rs | 6 +++++- src/internal/exit_codes.rs | 1 + src/main.rs | 2 +- src/operations/clean.rs | 39 ++++++++++++++++++++++++++++++++++--- 6 files changed, 53 insertions(+), 14 deletions(-) diff --git a/docs/USAGE.md b/docs/USAGE.md index 66a9f03..4a714e8 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -10,14 +10,15 @@ Work it harder, make it better! ### Basic Commands -| Action | Command | Extra Flags | -|--------------------------------------------------------|-------------------------------------------|------------------------------------------------------------------------------------------------------------------| -| Build a package/packages. | `mlc build ` [all if left empty] | `--no-regen`: Doesn't regenerate repository after build | -| Generate pacman repository | `mlc repo-gen` | | -| Update local repos/PKGBUILDs | `mlc pull/update` [all if left empty] | `--no-regen`: If `mode.repository.build_on_update` is `true`, Do not regenerate repository after package rebuild | -| Create and/or open config file | `mlc conf` | | -| Initialises repo/workspace based on config in mlc.toml | `mlc clone/init` | | -| Displays an info panel/overview of the current repo | `mlc info/status` | | +| Action | Command | Extra Flags | +|-----------------------------------------------------------------------------------------|-------------------------------------------|------------------------------------------------------------------------------------------------------------------| +| Build a package/packages. | `mlc build ` [all if left empty] | `--no-regen`: Doesn't regenerate repository after build | +| Generate pacman repository | `mlc repo-gen` | | +| Update local repos/PKGBUILDs | `mlc pull/update` [all if left empty] | `--no-regen`: If `mode.repository.build_on_update` is `true`, Do not regenerate repository after package rebuild | +| Create and/or open config file | `mlc conf` | | +| Initialises repo/workspace based on config in mlc.toml | `mlc clone/init` | | +| Displays an info panel/overview of the current repo | `mlc info/status` | | +| Resets Malachite repository by deleting all directories, omitting `mlc.toml` and `.git` | `mlc clean/reset` | `--force`: Remove dirty directories (unstaged, untracked, etc) | ### Exit Codes diff --git a/examples/workspace/mlc.toml b/examples/workspace/mlc.toml index db0466f..6ddb633 100644 --- a/examples/workspace/mlc.toml +++ b/examples/workspace/mlc.toml @@ -4,7 +4,7 @@ smart_pull = true [mode.workspace] git_info = true -colorblind = true +colorblind = false [repositories] repos = [ diff --git a/src/args.rs b/src/args.rs index 3601042..170f297 100644 --- a/src/args.rs +++ b/src/args.rs @@ -39,7 +39,11 @@ pub enum Operation { /// Removes everything in directory except for mlc.toml #[clap(name = "clean", aliases = & ["clean", "cl", "reset"])] - Clean, + Clean { + /// Force removes everything, even if git directory is dirty or has unpushed changes or changes at remote + #[clap(short = 'f', long = "force", action = ArgAction::SetTrue)] + force: bool, + }, /// Removes all but the latest 3 versions of each package in a repository #[clap(name = "prune", aliases = & ["prune", "p"])] diff --git a/src/internal/exit_codes.rs b/src/internal/exit_codes.rs index 9e7ddb3..ba53a67 100644 --- a/src/internal/exit_codes.rs +++ b/src/internal/exit_codes.rs @@ -9,4 +9,5 @@ pub enum AppExitCode { ConfigParseError = 8, InvalidRepo = 9, NotInit = 10, + NotClean = 11, } diff --git a/src/main.rs b/src/main.rs index 193fd4d..445f459 100755 --- a/src/main.rs +++ b/src/main.rs @@ -72,7 +72,7 @@ fn main() { } operations::prune(verbose); } - Operation::Clean => operations::clean(verbose), + Operation::Clean { force, .. } => operations::clean(verbose, force), Operation::Info => operations::info(verbose), } } diff --git a/src/operations/clean.rs b/src/operations/clean.rs index 5a463dc..acb667c 100644 --- a/src/operations/clean.rs +++ b/src/operations/clean.rs @@ -1,6 +1,6 @@ -use crate::{info, log}; +use crate::{info, log, crash, internal::AppExitCode}; -pub fn clean(verbose: bool) { +pub fn clean(verbose: bool, force: 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(); @@ -9,9 +9,42 @@ pub fn clean(verbose: bool) { .map(|x| x.unwrap().path().display().to_string()) .collect::>(); - // Remove all files/dirs in the current directory, excluding ./mlc.toml and .git + // Remove mlc.toml and .git from output dirs.retain(|x| *x != "./mlc.toml"); dirs.retain(|x| *x != "./.git"); + + // Enter each directory and check git status + + let mut unclean_dirs = vec![]; + + for dir in &dirs { + let root_dir = std::env::current_dir().unwrap(); + log!(verbose, "Entering directory: {}", dir); + std::env::set_current_dir(dir).unwrap(); + let status = std::process::Command::new("git") + .arg("status") + .output() + .unwrap(); + let output = std::string::String::from_utf8(status.stdout).unwrap(); + log!(verbose, "Git status: {}", output); + if output.contains("Your branch is up to date with") && !output.contains("Untracked files") && !output.contains("Changes not staged for commit") { + log!(verbose, "Directory {} is clean", dir); + } else { + unclean_dirs.push(dir); + } + std::env::set_current_dir(&root_dir).unwrap(); + log!(verbose, "Current directory: {}", root_dir.display()); + } + + if unclean_dirs.len() > 0 && !force{ + crash!( + AppExitCode::NotClean, + "The following directories are not clean: \n {}\n\ + If you are sure no important changes are staged, run `mlc clean` with the `--force` flag to delete them.", + unclean_dirs.iter().map(|x| x.to_string().replace("./", "")).collect::>().join(", ") + ); + } + log!(verbose, "Paths with mlc.toml excluded: {:?}", dirs); for dir in &dirs { std::fs::remove_dir_all(dir).unwrap();