Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: Add rule: pip install #134

Merged
merged 2 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ mod no_such_file;
mod npm_missing_script;
mod npm_run_script;
mod php_s;
mod pip_install;
mod python_command;
mod python_execute;
mod quotation_marks;
Expand Down Expand Up @@ -180,6 +181,7 @@ pub fn get_rules() -> Vec<Rule> {
npm_run_script::get_rule(),
no_such_file::get_rule(),
php_s::get_rule(),
pip_install::get_rule(),
python_command::get_rule(),
python_execute::get_rule(),
quotation_marks::get_rule(),
Expand Down
70 changes: 70 additions & 0 deletions src/rules/pip_install.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use super::{match_rule_without_sudo, utils::match_rule_with_is_app, Rule};
use crate::{cli::command::CrabCommand, shell::Shell};

fn auxiliary_match_rule(command: &CrabCommand) -> bool {
if let Some(output) = &command.output {
command.script.contains("pip install") && output.contains("Permission denied")
} else {
false
}
}

pub fn match_rule(command: &mut CrabCommand, system_shell: Option<&dyn Shell>) -> bool {
match_rule_without_sudo(
|command| match_rule_with_is_app(auxiliary_match_rule, command, vec!["pip"], None),
command,
)
}

pub fn get_new_command(command: &mut CrabCommand, system_shell: Option<&dyn Shell>) -> Vec<String> {
if !command.script.contains("--user") {
vec![command.script.replace(" install ", " install --user ")]
} else {
vec![format!("sudo {}", command.script.replace(" --user", ""))]
}
}

pub fn get_rule() -> Rule {
Rule::new(
"pip_install".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;

const ERROR_PERMISSION_DENIED: &str = "\nCould not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/Library/Python/2.7/site-packages/entrypoints.pyc'\nConsider using the `--user` option or check the permissions.\n";
const SUCCESS_INSTALL: &str = "\nCollecting bacon\n Downloading https://files.pythonhosted.org/packages/b2/81/19fb79139ee71c8bc4e5a444546f318e2b87253b8939ec8a7e10d63b7341/bacon-0.3.1.zip (11.0MB)\n 100% |████████████████████████████████| 11.0MB 3.0MB/s\nInstalling collected packages: bacon\n Running setup.py install for bacon ... done\nSuccessfully installed bacon-0.3.1\n";

#[rstest]
#[case("pip install -r requirements.txt", ERROR_PERMISSION_DENIED, true)]
#[case("pip install bacon", SUCCESS_INSTALL, 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("pip install -r requirements.txt", "", vec!["pip install --user -r requirements.txt"])]
#[case("pip install bacon", "", vec!["pip install --user bacon"])]
#[case("pip install --user -r requirements.txt", "", vec!["sudo pip install -r requirements.txt"])]
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, None), expected);
}
}
Loading