Skip to content

Commit

Permalink
FEAT: Add rule: git rm staged (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
luizvbo authored Apr 29, 2024
1 parent 462ca77 commit dcc6931
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 9 deletions.
9 changes: 6 additions & 3 deletions src/rules/git_add.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::{
cli::command::CrabCommand, rules::utils::git::match_rule_with_git_support, shell::Shell,
cli::command::CrabCommand,
rules::{
utils::git::{get_new_command_with_git_support, match_rule_with_git_support},
Rule,
},
shell::Shell,
};
use regex::Regex;
use std::path::Path;

use super::{utils::git::get_new_command_with_git_support, Rule};

fn get_missing_file(command: &CrabCommand, path_exists: Option<bool>) -> Option<String> {
if let Some(stdout) = &command.output {
let re = Regex::new(r"error: pathspec '([^']*)' did not match any file\(s\) known to git.")
Expand Down
10 changes: 7 additions & 3 deletions src/rules/git_commit_add.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::{
cli::command::CrabCommand, rules::utils::git::match_rule_with_git_support, shell::Shell,
cli::command::CrabCommand,
rules::{
utils::git::{get_new_command_with_git_support, match_rule_with_git_support},
Rule,
},
shell::Shell,
};

use super::{utils::git::get_new_command_with_git_support, Rule};

use crate::utils::replace_argument;

fn auxiliary_match_rule(command: &CrabCommand) -> bool {
if let Some(stdout) = &command.output {
stdout.contains("no changes added to commit")
Expand Down
9 changes: 6 additions & 3 deletions src/rules/git_commit_amend.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::{utils::git::get_new_command_with_git_support, Rule};

use crate::{
cli::command::CrabCommand, rules::utils::git::match_rule_with_git_support, shell::Shell,
cli::command::CrabCommand,
rules::{
utils::git::{get_new_command_with_git_support, match_rule_with_git_support},
Rule,
},
shell::Shell,
};

fn auxiliary_match_rule(command: &CrabCommand) -> bool {
Expand Down
88 changes: 88 additions & 0 deletions src/rules/git_rm_staged.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::{
cli::command::CrabCommand,
rules::{
utils::git::{get_new_command_with_git_support, match_rule_with_git_support},
Rule,
},
shell::Shell,
};

fn auxiliary_match_rule(command: &CrabCommand) -> bool {
if let Some(output) = &command.output {
return command.script.contains(" rm ")
&& output.contains("error: the following file has changes staged in the index")
&& output.contains("use --cached to keep the file, or -f to force removal");
}
false
}

pub fn match_rule(command: &mut CrabCommand, system_shell: Option<&dyn Shell>) -> bool {
match_rule_with_git_support(auxiliary_match_rule, command)
}

fn auxiliary_get_new_command(
command: &CrabCommand,
system_shell: Option<&dyn Shell>,
) -> Vec<String> {
let mut command_parts = command.script_parts.clone();
if let Some(index) = command_parts.iter().position(|r| r == "rm") {
command_parts.insert(index + 1, "--cached".to_string());
let mut command_list = vec![command_parts.join(" ")];
command_parts[index + 1] = "-f".to_string();
command_list.push(command_parts.join(" "));
return command_list;
}
vec![]
}

pub fn get_new_command(command: &mut CrabCommand, system_shell: Option<&dyn Shell>) -> Vec<String> {
get_new_command_with_git_support(auxiliary_get_new_command, command, system_shell)
}

pub fn get_rule() -> Rule {
Rule::new(
"git_rm_staged".to_owned(),
None,
None,
None,
match_rule,
get_new_command,
None,
)
}

#[cfg(test)]
mod tests {
use super::{get_new_command, match_rule};
use crate::cli::command::CrabCommand;
use crate::shell::Bash;
use rstest::rstest;

fn output(target: &str) -> String {
format!("error: the following file has changes staged in the index:\n {}\n(use --cached to keep the file, or -f to force removal)", target)
}

#[rstest]
#[case("git rm foo", &output("foo"), true)]
#[case("git rm foo bar", &output("bar"), true)]
#[case("git rm foo", "", false)]
#[case("git rm foo bar", "", false)]
#[case("git rm", "", false)]
fn test_match(#[case] command: &str, #[case] stdout: &str, #[case] is_match: bool) {
let mut command = CrabCommand::new(command.to_owned(), Some(stdout.to_owned()), None);
assert_eq!(match_rule(&mut command, None), is_match);
}

#[rstest]
#[case("git rm foo", &output("foo"), vec!["git rm --cached foo", "git rm -f foo"])]
#[case("git rm foo bar", &output("bar"), vec!["git rm --cached foo bar", "git rm -f foo bar"])]
fn test_get_new_command(
#[case] command: &str,
#[case] stdout: &str,
#[case] expected: Vec<&str>,
) {
let system_shell = Bash {};
let mut command = CrabCommand::new(command.to_owned(), Some(stdout.to_owned()), None);
assert_eq!(get_new_command(&mut command, Some(&system_shell)), expected);
}
}
2 changes: 2 additions & 0 deletions src/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ mod git_remote_delete;
mod git_remote_seturl_add;
mod git_rm_local_modifications;
mod git_rm_recursive;
mod git_rm_staged;
mod git_stash;
mod git_stash_pop;
mod git_two_dashes;
Expand Down Expand Up @@ -190,6 +191,7 @@ pub fn get_rules() -> Vec<Rule> {
git_lfs_mistype::get_rule(),
git_push_pull::get_rule(),
git_push_without_commits::get_rule(),
git_rm_staged::get_rule(),
git_rm_recursive::get_rule(),
git_rebase_merge_dir::get_rule(),
git_rebase_no_changes::get_rule(),
Expand Down

0 comments on commit dcc6931

Please sign in to comment.