From b64c2855c2eed14b136618aa1a1ea0c5e77a3b12 Mon Sep 17 00:00:00 2001 From: Christian Ravn Date: Mon, 11 Oct 2021 16:45:44 +0200 Subject: [PATCH 1/3] ci: fix clippy warnings --- src/config.rs | 5 +---- src/config_test.rs | 12 ++++++------ src/git.rs | 8 ++++---- src/git_test.rs | 10 +++++----- src/hooks.rs | 2 +- src/hooks_test.rs | 14 +++++++------- src/main.rs | 2 +- src/rusty_hook.rs | 2 +- 8 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/config.rs b/src/config.rs index 86b57b3..d2576d8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -145,10 +145,7 @@ fn get_table_key_value_from_config( pub fn get_log_setting(config_contents: &str) -> bool { match get_table_key_value_from_config(config_contents, "logging", "verbose") { Err(_) => true, - Ok(value) => match value.as_bool() { - Some(setting) => setting, - None => true, - }, + Ok(value) => value.as_bool().unwrap_or(true), } } diff --git a/src/config_test.rs b/src/config_test.rs index 5301277..8e77517 100644 --- a/src/config_test.rs +++ b/src/config_test.rs @@ -47,7 +47,7 @@ mod create_default_config_file_tests { let write_file = |file_path: &str, contents: &str, make_executable: bool| { assert_eq!(&exp_path, file_path); assert_eq!(CONFIG_FILE_TEMPLATE, contents); - assert_eq!(false, make_executable); + assert!(!make_executable); Ok(()) }; let file_exists = |_path: &str| Ok(false); @@ -92,7 +92,7 @@ mod create_config_file_tests { let write_file = |file_path: &str, contents: &str, make_executable: bool| { assert_eq!(&exp_path, file_path); assert_eq!(CONFIG_FILE_TEMPLATE, contents); - assert_eq!(false, make_executable); + assert!(!make_executable); Ok(()) }; let file_exists = |_path: &str| Ok(false); @@ -108,7 +108,7 @@ mod create_config_file_tests { let write_file = |file_path: &str, contents: &str, make_executable: bool| { assert_eq!(&exp_path, file_path); assert_eq!(CONFIG_FILE_TEMPLATE, contents); - assert_eq!(false, make_executable); + assert!(!make_executable); Ok(()) }; let file_exists = |_path: &str| Ok(false); @@ -218,7 +218,7 @@ mod get_log_setting_tests { fn returns_true_when_content_not_found() { let invalid_contents = "90827342089734"; let result = get_log_setting(invalid_contents); - assert_eq!(result, true); + assert!(result); } #[test] @@ -227,7 +227,7 @@ mod get_log_setting_tests { verbose = "cargo test" "#; let result = get_log_setting(contents); - assert_eq!(result, true); + assert!(result); } #[test] @@ -236,7 +236,7 @@ mod get_log_setting_tests { verbose = false "; let result = get_log_setting(contents); - assert_eq!(result, false); + assert!(!result); } } diff --git a/src/git.rs b/src/git.rs index 0b2559d..181253e 100644 --- a/src/git.rs +++ b/src/git.rs @@ -37,7 +37,7 @@ where { run_command( "git rev-parse --git-path hooks", - Some(&root_directory), + Some(root_directory), false, None, ) @@ -47,7 +47,7 @@ pub fn setup_hooks( run_command: F, write_file: G, root_directory_path: &str, - hook_file_skip_list: &Vec<&str>, + hook_file_skip_list: &[&str], ) -> Result<(), String> where F: Fn( @@ -58,13 +58,13 @@ where ) -> Result, Option>, G: Fn(&str, &str, bool) -> Result<(), String>, { - let hooks_directory = match get_hooks_directory(&run_command, &root_directory_path) { + let hooks_directory = match get_hooks_directory(&run_command, root_directory_path) { Ok(Some(path)) => path, _ => return Err(String::from("Failure determining git hooks directory")), }; hooks::create_hook_files( write_file, - &root_directory_path, + root_directory_path, &hooks_directory, hook_file_skip_list, ) diff --git a/src/git_test.rs b/src/git_test.rs index dd8b950..a1c28bb 100644 --- a/src/git_test.rs +++ b/src/git_test.rs @@ -20,7 +20,7 @@ mod get_root_directory_path_tests { Ok(None) } }; - let act = get_root_directory_path(run_command, Some(&target_dir)); + let act = get_root_directory_path(run_command, Some(target_dir)); assert_eq!(act.unwrap(), Some(String::from(exp))); } @@ -51,7 +51,7 @@ mod get_hooks_directory_tests { Ok(None) } }; - let act = get_hooks_directory(run_command, &target_dir); + let act = get_hooks_directory(run_command, target_dir); assert_eq!(act.unwrap(), Some(String::from(exp))); } @@ -73,7 +73,7 @@ mod setup_hooks_tests { let exp_err = "Failure determining git hooks directory"; let run_command = build_simple_command_runner(Err(None)); let write_file = |_path: &str, _contents: &str, _x: bool| Ok(()); - let result = setup_hooks(run_command, write_file, "", &vec![]); + let result = setup_hooks(run_command, write_file, "", &[]); assert_eq!(result, Err(String::from(exp_err))); } @@ -82,7 +82,7 @@ mod setup_hooks_tests { let run_command = build_simple_command_runner(Ok(Some(String::from("/usr/repos/foo/.git/hooks")))); let write_file = |_path: &str, _contents: &str, _x: bool| Err(String::from("")); - let result = setup_hooks(run_command, write_file, "", &vec![]); + let result = setup_hooks(run_command, write_file, "", &[]); assert_eq!(result, Err(String::from(hooks::HOOK_CREATION_ERROR))); } @@ -92,7 +92,7 @@ mod setup_hooks_tests { let git_hooks = ".git/hooks"; let run_command = build_simple_command_runner(Ok(Some(String::from(git_hooks)))); let write_file = |_p: &str, _c: &str, _x: bool| Ok(()); - let result = setup_hooks(run_command, write_file, root_dir, &vec![]); + let result = setup_hooks(run_command, write_file, root_dir, &[]); assert_eq!(result, Ok(())); } } diff --git a/src/hooks.rs b/src/hooks.rs index 1089194..735f155 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -67,7 +67,7 @@ pub fn create_hook_files( write_file: F, root_directory_path: &str, hooks_directory: &str, - hook_file_skip_list: &Vec<&str>, + hook_file_skip_list: &[&str], ) -> Result<(), String> where F: Fn(&str, &str, bool) -> Result<(), String>, diff --git a/src/hooks_test.rs b/src/hooks_test.rs index 4050c9b..2aab990 100644 --- a/src/hooks_test.rs +++ b/src/hooks_test.rs @@ -124,7 +124,7 @@ mod create_hook_files_tests { _ => Err(String::from("")), } }; - let result = create_hook_files(write_file, "", "", &vec![]); + let result = create_hook_files(write_file, "", "", &[]); assert_eq!(result, Err(String::from(EXP_HOOK_CREATION_ERROR))); } @@ -138,7 +138,7 @@ mod create_hook_files_tests { _ => Ok(()), } }; - let result = create_hook_files(write_file, "", "", &vec![]); + let result = create_hook_files(write_file, "", "", &[]); assert_eq!(result, Err(String::from(EXP_HOOK_CREATION_ERROR))); } @@ -152,7 +152,7 @@ mod create_hook_files_tests { _ => Ok(()), } }; - let result = create_hook_files(write_file, "", "", &vec![]); + let result = create_hook_files(write_file, "", "", &[]); assert_eq!(result, Err(String::from(EXP_HOOK_CREATION_ERROR))); } @@ -183,10 +183,10 @@ mod create_hook_files_tests { assert_eq!(exp_contents, contents); } } - assert_eq!(true, make_executable); + assert!(make_executable); Ok(()) }; - let result = create_hook_files(write_file, root_dir, git_hooks, &vec![]); + let result = create_hook_files(write_file, root_dir, git_hooks, &[]); assert_eq!(result, Ok(())); } @@ -218,10 +218,10 @@ mod create_hook_files_tests { assert_eq!(exp_contents, contents); } } - assert_eq!(true, make_executable); + assert!(make_executable); Ok(()) }; - let result = create_hook_files(write_file, root_dir, git_hooks, &vec![EXP_SKIPPED_HOOK]); + let result = create_hook_files(write_file, root_dir, git_hooks, &[EXP_SKIPPED_HOOK]); assert_eq!(result, Ok(())); } } diff --git a/src/main.rs b/src/main.rs index d0788de..a90a145 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,7 @@ fn init(skip_hook_list: Option) { let skip_hook_list = skip_hook_list .as_deref() - .map_or(vec![], |s| s.split(",").collect()); + .map_or(vec![], |s| s.split(',').collect()); if let Err(err) = rusty_hook::init( nias::get_command_runner(), diff --git a/src/rusty_hook.rs b/src/rusty_hook.rs index 893b5f7..0e1b94c 100644 --- a/src/rusty_hook.rs +++ b/src/rusty_hook.rs @@ -114,7 +114,7 @@ where let log_details = config::get_log_setting(&config_file_contents); let (script, env_vars) = match ( - config::get_hook_script(&config_file_contents, &hook_name), + config::get_hook_script(&config_file_contents, hook_name), args, ) { (Ok(script), None) => (script, None), From 3d8f2dbb869e0f1d41cdfc07dbe825bde37152c8 Mon Sep 17 00:00:00 2001 From: Christian Ravn Date: Tue, 12 Oct 2021 11:49:05 +0200 Subject: [PATCH 2/3] ci: switch to latest vm image in linux pipelines --- .azure-pipelines/build/pr.hook-scripts.yml | 34 +++++------ .azure-pipelines/build/pr.mac.yml | 58 +++++++++---------- .azure-pipelines/build/pr.windows.yml | 66 +++++++++++----------- .azure-pipelines/pull-requests/clippy.yml | 28 ++++----- .azure-pipelines/pull-requests/rustfmt.yml | 29 +++++----- 5 files changed, 107 insertions(+), 108 deletions(-) diff --git a/.azure-pipelines/build/pr.hook-scripts.yml b/.azure-pipelines/build/pr.hook-scripts.yml index 5d140b4..60975fc 100644 --- a/.azure-pipelines/build/pr.hook-scripts.yml +++ b/.azure-pipelines/build/pr.hook-scripts.yml @@ -1,26 +1,26 @@ trigger: -- master + - master pr: -- master + - master pool: - vmImage: 'Ubuntu-16.04' + vmImage: "ubuntu-latest" steps: -- script: ./tests/hook_files/run_tests.sh - displayName: 'Run unit tests' + - script: ./tests/hook_files/run_tests.sh + displayName: "Run unit tests" -- task: swellaby.shellcheck.install-shellcheck.install-shellcheck@0 - displayName: 'Install ShellCheck' - inputs: - version: latest + - task: swellaby.shellcheck.install-shellcheck.install-shellcheck@0 + displayName: "Install ShellCheck" + inputs: + version: latest -- task: swellaby.shellcheck.shellcheck.shellcheck@0 - displayName: 'Run ShellCheck analysis' - inputs: - targetFiles: '**/!(shunit2).sh' - followSourcedFiles: true - checkSourcedFiles: false - ignoredErrorCodes: | - SC2039 + - task: swellaby.shellcheck.shellcheck.shellcheck@0 + displayName: "Run ShellCheck analysis" + inputs: + targetFiles: "**/!(shunit2).sh" + followSourcedFiles: true + checkSourcedFiles: false + ignoredErrorCodes: | + SC2039 diff --git a/.azure-pipelines/build/pr.mac.yml b/.azure-pipelines/build/pr.mac.yml index 94cfb07..b30198a 100644 --- a/.azure-pipelines/build/pr.mac.yml +++ b/.azure-pipelines/build/pr.mac.yml @@ -1,41 +1,41 @@ trigger: -- master + - master pr: -- master + - master pool: vmImage: macos-10.14 steps: -- script: | - curl https://sh.rustup.rs -sSf | sh -s -- -y - echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" - echo "##vso[task.setvariable variable=cargoBinPath;]$HOME/.cargo/bin" - displayName: 'Install Rust' + - script: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" + echo "##vso[task.setvariable variable=cargoBinPath;]$HOME/.cargo/bin" + displayName: "Install Rust" -- task: DownloadPipelineArtifact@0 - displayName: 'Download cargo-junit executable' - inputs: - pipelineId: 1447 - artifactName: 'cargo-junit' - targetPath: '$(cargoBinPath)' + - task: DownloadPipelineArtifact@0 + displayName: "Download cargo-junit executable" + inputs: + pipelineId: 1447 + artifactName: "cargo-junit" + targetPath: "$(cargoBinPath)" -- script: | - sudo chmod +rwx $(cargoBinPath)/cargo-junit - mkdir -p .testresults/unit - displayName: 'Prep test tools' + - script: | + sudo chmod +rwx $(cargoBinPath)/cargo-junit + mkdir -p .testresults/unit + displayName: "Prep test tools" -- script: | - set -eo pipefail - cargo test --no-run - cargo junit --name .testresults/unit/junit.xml - displayName: 'Run tests' + - script: | + set -eo pipefail + cargo test --no-run + cargo junit --name .testresults/unit/junit.xml + displayName: "Run tests" -- task: PublishTestResults@2 - displayName: 'Publish unit test results' - inputs: - testResultsFormat: JUnit - testResultsFiles: 'junit.xml' - searchFolder: $(Build.SourcesDirectory)/.testresults/unit - testRunTitle: 'rusty-hook::Unit Tests::Mac PR - Build $(Build.BuildId)' + - task: PublishTestResults@2 + displayName: "Publish unit test results" + inputs: + testResultsFormat: JUnit + testResultsFiles: "junit.xml" + searchFolder: $(Build.SourcesDirectory)/.testresults/unit + testRunTitle: "rusty-hook::Unit Tests::Mac PR - Build $(Build.BuildId)" diff --git a/.azure-pipelines/build/pr.windows.yml b/.azure-pipelines/build/pr.windows.yml index 33f37b7..2221dad 100644 --- a/.azure-pipelines/build/pr.windows.yml +++ b/.azure-pipelines/build/pr.windows.yml @@ -1,45 +1,45 @@ trigger: -- master + - master pr: -- master + - master pool: vmImage: windows-2019 steps: -- powershell: | - $ProgressPreference = "SilentlyContinue" - Invoke-WebRequest https://win.rustup.rs/ -OutFile rustup-init.exe - .\rustup-init.exe -y --default-host=x86_64-pc-windows-msvc --profile=minimal - del rustup-init.exe - echo "##vso[task.setvariable variable=PATH;]$env:USERPROFILE\.cargo\bin;$env:PATH" - echo "##vso[task.setvariable variable=cargoBinPath;]$env:USERPROFILE\.cargo\bin" - displayName: 'Install Rust' + - powershell: | + $ProgressPreference = "SilentlyContinue" + Invoke-WebRequest https://win.rustup.rs/ -OutFile rustup-init.exe + .\rustup-init.exe -y --default-host=x86_64-pc-windows-msvc --profile=minimal + del rustup-init.exe + echo "##vso[task.setvariable variable=PATH;]$env:USERPROFILE\.cargo\bin;$env:PATH" + echo "##vso[task.setvariable variable=cargoBinPath;]$env:USERPROFILE\.cargo\bin" + displayName: "Install Rust" -- script: | - where rustup - rustup component remove rust-docs - rustup update stable - displayName: 'Setup' + - script: | + where rustup + rustup component remove rust-docs + rustup update stable + displayName: "Setup" -- task: DownloadPipelineArtifact@0 - displayName: 'Download cargo-junit executable' - inputs: - pipelineId: 1448 - artifactName: 'cargo-junit' - targetPath: '$(cargoBinPath)' + - task: DownloadPipelineArtifact@0 + displayName: "Download cargo-junit executable" + inputs: + pipelineId: 1448 + artifactName: "cargo-junit" + targetPath: "$(cargoBinPath)" -- script: | - cargo test --no-run - mkdir $(Build.SourcesDirectory)\.testresults\unit - cargo junit --name $(Build.SourcesDirectory)\.testresults\unit\junit.xml - displayName: 'Run tests' + - script: | + cargo test --no-run + mkdir $(Build.SourcesDirectory)\.testresults\unit + cargo junit --name $(Build.SourcesDirectory)\.testresults\unit\junit.xml + displayName: "Run tests" -- task: PublishTestResults@2 - displayName: 'Publish unit test results' - inputs: - testResultsFormat: JUnit - testResultsFiles: 'junit.xml' - searchFolder: $(Build.SourcesDirectory)/.testresults/unit - testRunTitle: 'rusty-hook::Unit Tests::Windows PR - Build $(Build.BuildId)' + - task: PublishTestResults@2 + displayName: "Publish unit test results" + inputs: + testResultsFormat: JUnit + testResultsFiles: "junit.xml" + searchFolder: $(Build.SourcesDirectory)/.testresults/unit + testRunTitle: "rusty-hook::Unit Tests::Windows PR - Build $(Build.BuildId)" diff --git a/.azure-pipelines/pull-requests/clippy.yml b/.azure-pipelines/pull-requests/clippy.yml index 34a903b..5c93ab1 100644 --- a/.azure-pipelines/pull-requests/clippy.yml +++ b/.azure-pipelines/pull-requests/clippy.yml @@ -1,23 +1,23 @@ trigger: none pr: -- master + - master pool: - vmImage: 'Ubuntu-16.04' + vmImage: "ubuntu-latest" steps: -- script: | - curl https://sh.rustup.rs -sSf | sh -s -- -y - echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" - echo "##vso[task.setvariable variable=cargoBinPath;]$HOME/.cargo/bin" - displayName: 'Install Rust' + - script: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" + echo "##vso[task.setvariable variable=cargoBinPath;]$HOME/.cargo/bin" + displayName: "Install Rust" -- script: | - rustup component add clippy - displayName: 'Install clippy' + - script: | + rustup component add clippy + displayName: "Install clippy" -- script: | - set -eo pipefail - cargo clippy --all-targets -- -D warnings - displayName: 'Run clippy' + - script: | + set -eo pipefail + cargo clippy --all-targets -- -D warnings + displayName: "Run clippy" diff --git a/.azure-pipelines/pull-requests/rustfmt.yml b/.azure-pipelines/pull-requests/rustfmt.yml index 73276c5..4c87bd3 100644 --- a/.azure-pipelines/pull-requests/rustfmt.yml +++ b/.azure-pipelines/pull-requests/rustfmt.yml @@ -1,24 +1,23 @@ trigger: none pr: -- master + - master pool: - vmImage: 'Ubuntu-16.04' + vmImage: "ubuntu-latest" steps: -- script: | - curl https://sh.rustup.rs -sSf | sh -s -- -y - echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" - echo "##vso[task.setvariable variable=cargoBinPath;]$HOME/.cargo/bin" - displayName: 'Install Rust' + - script: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" + echo "##vso[task.setvariable variable=cargoBinPath;]$HOME/.cargo/bin" + displayName: "Install Rust" -- script: | - rustup component add rustfmt - displayName: 'Install rustfmt' - -- script: | - set -eo pipefail - cargo fmt -- --check - displayName: 'Run rustfmt' + - script: | + rustup component add rustfmt + displayName: "Install rustfmt" + - script: | + set -eo pipefail + cargo fmt -- --check + displayName: "Run rustfmt" From 21c7e96fb714f9e9040975cdcda038ab15055545 Mon Sep 17 00:00:00 2001 From: Christian Ravn Date: Sun, 17 Oct 2021 13:13:29 +0200 Subject: [PATCH 3/3] chore: revert to getopts for argument parsing --- Cargo.lock | 250 ++++------------------------------ Cargo.toml | 10 +- build.rs | 4 +- src/git.rs | 2 +- src/hook_files/hook_script.sh | 2 +- src/hooks.rs | 4 +- src/hooks_test.rs | 7 +- src/main.rs | 137 ++++++++++++++----- src/rusty_hook.rs | 6 +- src/rusty_hook_test.rs | 10 +- 10 files changed, 155 insertions(+), 277 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0dbddc5..60b0c95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,15 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] +version = 3 [[package]] name = "autocfg" @@ -17,57 +8,26 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - [[package]] name = "ci_info" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98f1c9ee4939df5d42c01815f1fb783ab203c1dea7cee5e051ede261c4049b1f" +checksum = "1f0e2864372242f01b92c1b882a904f6fb8b57f16e81e148a35b6368b1ea7323" dependencies = [ "envmnt", ] [[package]] -name = "clap" -version = "3.0.0-beta.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" -dependencies = [ - "atty", - "bitflags", - "clap_derive", - "indexmap", - "lazy_static", - "os_str_bytes", - "strsim", - "termcolor", - "textwrap", - "vec_map", -] - -[[package]] -name = "clap_derive" -version = "3.0.0-beta.4" +name = "dunce" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] +checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" [[package]] name = "envmnt" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfac51e9996e41d78a943227b7f313efcebf545b21584a0e213b956a062e11e" +checksum = "0f96dd862f12fac698dec3932dff0e6fb34bffeb5515ae5932d620cfe076571e" dependencies = [ "fsio", "indexmap", @@ -75,160 +35,59 @@ dependencies = [ [[package]] name = "fsio" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50045aa8931ae01afbc5d72439e8f57f326becb8c70d07dfc816778eff3d167" - -[[package]] -name = "hashbrown" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7" +checksum = "09e87827efaf94c7a44b562ff57de06930712fe21b530c3797cdede26e6377eb" +dependencies = [ + "dunce", +] [[package]] -name = "heck" -version = "0.3.1" +name = "getopts" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" dependencies = [ - "unicode-segmentation", + "unicode-width", ] [[package]] -name = "hermit-abi" -version = "0.1.16" +name = "hashbrown" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" -dependencies = [ - "libc", -] +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "indexmap" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", "hashbrown", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" - [[package]] name = "nias" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0135fd396265547ac8bd1aa38616bd1b39d9e8e9d5c9c7d8ef72fc945ba5b122" -[[package]] -name = "os_str_bytes" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - [[package]] name = "rusty-hook" version = "0.12.0" dependencies = [ "ci_info", - "clap", + "getopts", "nias", "toml", ] [[package]] name = "serde" -version = "1.0.116" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "termcolor" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" -dependencies = [ - "unicode-width", -] +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" [[package]] name = "toml" @@ -239,63 +98,8 @@ dependencies = [ "serde", ] -[[package]] -name = "unicode-segmentation" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" - [[package]] name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" diff --git a/Cargo.toml b/Cargo.toml index 9e7429f..54767cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,8 @@ license = "MIT" repository = "https://github.com/swellaby/rusty-hook" readme = "README.md" edition = "2018" -keywords = [ "hooks", "githook", "git", "hook", "commit" ] -categories = [ "development-tools" ] +keywords = ["hooks", "githook", "git", "hook", "commit"] +categories = ["development-tools"] exclude = [ ".coverage/**", ".testresults/**", @@ -32,9 +32,9 @@ exclude = [ [dependencies] ci_info = "0.14.2" -clap = "3.0.0-beta.4" -toml = "0.5.8" +getopts = "0.2.21" nias = "0.7.0" +toml = "0.5.8" [build-dependencies] ci_info = "0.14.2" @@ -42,6 +42,6 @@ toml = "0.5.8" nias = "0.7.0" [badges] -azure-devops = { project = "swellaby/opensource", pipeline = "rusty-hook.linux-pr", build="49" } +azure-devops = { project = "swellaby/opensource", pipeline = "rusty-hook.linux-pr", build = "49" } codecov = { repository = "swellaby/rusty-hook", branch = "master", service = "github" } maintenance = { status = "actively-developed" } diff --git a/build.rs b/build.rs index c40b15d..bda5e8e 100644 --- a/build.rs +++ b/build.rs @@ -2,8 +2,8 @@ #[path = "src/rusty_hook.rs"] mod rusty_hook; +use std::env; use std::process::exit; -use std::{env, vec}; fn main() { if ci_info::is_ci() { @@ -16,7 +16,7 @@ fn main() { nias::get_file_writer(), nias::get_file_existence_checker(), Some(&target_directory), - vec![], + &[], ) { println!( "Fatal error encountered during initialization. Details: {}", diff --git a/src/git.rs b/src/git.rs index 181253e..af37c35 100644 --- a/src/git.rs +++ b/src/git.rs @@ -47,7 +47,7 @@ pub fn setup_hooks( run_command: F, write_file: G, root_directory_path: &str, - hook_file_skip_list: &[&str], + hook_file_skip_list: &[String], ) -> Result<(), String> where F: Fn( diff --git a/src/hook_files/hook_script.sh b/src/hook_files/hook_script.sh index f5f7db8..a940a22 100644 --- a/src/hook_files/hook_script.sh +++ b/src/hook_files/hook_script.sh @@ -22,5 +22,5 @@ else fi # shellcheck disable=SC2046 -rusty-hook run --hook "${hookName}" $([ -z "$gitParams" ] && echo "" || echo "-- $gitParams") +rusty-hook run --hook "${hookName}" "${gitParams}" handleRustyHookCliResult $? "${hookName}" diff --git a/src/hooks.rs b/src/hooks.rs index 735f155..104f107 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -67,7 +67,7 @@ pub fn create_hook_files( write_file: F, root_directory_path: &str, hooks_directory: &str, - hook_file_skip_list: &[&str], + hook_file_skip_list: &[String], ) -> Result<(), String> where F: Fn(&str, &str, bool) -> Result<(), String>, @@ -75,7 +75,7 @@ where let hook_file_contents = get_hook_file_contents(); for hook in HOOK_NAMES .iter() - .filter(|h| !hook_file_skip_list.contains(h)) + .filter(|h| !hook_file_skip_list.contains(&h.to_string())) { let path = get_file_path(root_directory_path, hooks_directory, hook); if write_file(&path, &hook_file_contents, true).is_err() { diff --git a/src/hooks_test.rs b/src/hooks_test.rs index 2aab990..b9761f6 100644 --- a/src/hooks_test.rs +++ b/src/hooks_test.rs @@ -221,7 +221,12 @@ mod create_hook_files_tests { assert!(make_executable); Ok(()) }; - let result = create_hook_files(write_file, root_dir, git_hooks, &[EXP_SKIPPED_HOOK]); + let result = create_hook_files( + write_file, + root_dir, + git_hooks, + &[String::from(EXP_SKIPPED_HOOK)], + ); assert_eq!(result, Ok(())); } } diff --git a/src/main.rs b/src/main.rs index a90a145..11a5bf7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,58 +1,84 @@ use std::env; use std::process::exit; -use clap::Clap; +use getopts::{Matches, Options}; mod rusty_hook; -#[derive(Clap)] -#[clap(author, about, version)] -enum RustyHookOpts { - /// Initialize rusty-hook's git hooks in the current directory. - #[clap(author, version)] - Init { - #[clap(long)] - skip_hook_list: Option, - }, - /// Print the current version of rusty-hook. - #[clap(author, version, alias = "-v")] - Version, - /// Run a git hook using the current directory's configuration. - /// Ran automatically by rusty-hook's git hooks. - #[clap(author, version)] - Run { - #[clap(long)] - hook: String, - #[clap(name = "git args", raw(true))] - args: Option, - }, +const INIT_BRIEF: &str = r#" +Usage: + rusty-hook init +"#; +const RUN_BRIEF: &str = r#" +Usage: + rusty-hook run --hook [NAME] [git_args] + +Args: + Arguments that will replace "%rh!" token in hook +"#; +const DEFAULT_BRIEF: &str = r#" +Usage: + rusty-hook + +Subcommands: + run Run a git hook using the current directory's configuration. Ran automatically by rusty-hook's git hooks + init Initialize rusty-hook's git hooks in the current directory +"#; + +fn print_version() { + println!(env!("CARGO_PKG_VERSION")); +} + +fn print_usage(brief: &str, opts: &Options) { + print!("{}", opts.usage(brief)); +} + +fn parse_list_args(opts: &Options, args: &[String]) -> Matches { + match opts.parse(args) { + Ok(m) => m, + Err(e) => { + eprintln!("{}", e); + exit(1); + } + } } -fn init(skip_hook_list: Option) { +fn init(matches: Matches) { if ci_info::is_ci() { println!("[rusty-hook] CI Environment detected. Skipping hook install"); exit(0); } - let skip_hook_list = skip_hook_list - .as_deref() - .map_or(vec![], |s| s.split(',').collect()); + let skip_hook_list = matches.free; if let Err(err) = rusty_hook::init( nias::get_command_runner(), nias::get_file_writer(), nias::get_file_existence_checker(), - skip_hook_list, + &skip_hook_list, ) { eprintln!( - "[rusty-hook] Fatal error encountered during initialization. Details: {}", + "[rusty] Fatal error encountered during initialization. Details: {}", err ); exit(1); }; } -fn run(hook: String, args: Option) { +fn run(matches: Matches) { + if !matches.opt_present("hook") { + eprintln!("Hook name option missing"); + exit(1); + } + + let hook = matches.opt_str("hook").unwrap(); + + let args = if matches.free.is_empty() { + None + } else { + Some(matches.free.join(" ")) + }; + if let Err(err) = rusty_hook::run( nias::get_command_runner(), nias::get_file_existence_checker(), @@ -74,11 +100,54 @@ fn run(hook: String, args: Option) { } } +fn parse_args(args: &[String], opts: &mut Options) -> (Matches, String) { + let first_opt = &args[1]; + + let (arg_slice, brief_ref) = match first_opt.as_ref() { + "init" => { + opts.optopt( + "", + "skip_hook_list", + "A hook that should be skipped", + "SKIP_HOOK_LIST", + ); + + (&args[2..], INIT_BRIEF) + } + "run" => { + opts.optopt("", "hook", "The git hook name", "NAME"); + + (&args[2..], RUN_BRIEF) + } + _ => (&args[1..], DEFAULT_BRIEF), + }; + + let matches = parse_list_args(opts, arg_slice); + + (matches, brief_ref.to_string()) +} + fn main() { - let opts = RustyHookOpts::parse(); - match opts { - RustyHookOpts::Init { skip_hook_list } => init(skip_hook_list), - RustyHookOpts::Version => println!(env!("CARGO_PKG_VERSION")), - RustyHookOpts::Run { hook, args } => run(hook, args), + let args: Vec = env::args().collect(); + let mut opts = Options::new(); + opts.optflag("h", "help", "Print help information"); + opts.optflag("V", "version", "Print version information"); + + let (matches, brief) = parse_args(&args, &mut opts); + + if matches.opt_present("h") { + print_usage(&brief, &opts); + exit(0) + }; + + if matches.opt_present("V") { + print_version(); + exit(0) + }; + + match args[1].as_ref() { + "init" => init(matches), + "run" => run(matches), + cmd => eprintln!("Unknown command: {}", cmd), } } diff --git a/src/rusty_hook.rs b/src/rusty_hook.rs index 0e1b94c..e014518 100644 --- a/src/rusty_hook.rs +++ b/src/rusty_hook.rs @@ -13,7 +13,7 @@ pub fn init_directory( write_file: G, file_exists: H, target_directory: Option<&str>, - hook_file_skip_list: Vec<&str>, + hook_file_skip_list: &[String], ) -> Result<(), String> where F: Fn( @@ -33,7 +33,7 @@ where &run_command, &write_file, &root_directory_path, - &hook_file_skip_list, + hook_file_skip_list, ) .is_err() { @@ -52,7 +52,7 @@ pub fn init( run_command: F, write_file: G, file_exists: H, - hook_file_skip_list: Vec<&str>, + hook_file_skip_list: &[String], ) -> Result<(), String> where F: Fn( diff --git a/src/rusty_hook_test.rs b/src/rusty_hook_test.rs index 6b21cc6..46776c2 100644 --- a/src/rusty_hook_test.rs +++ b/src/rusty_hook_test.rs @@ -39,7 +39,7 @@ mod init_directory_tests { panic!("Should not get here"); }; let file_exists = |_path: &str| panic!("Should not get here"); - let result = init(run_command, write_file, file_exists, vec![]); + let result = init(run_command, write_file, file_exists, &[]); assert_eq!(result, Err(String::from(exp_err))); } @@ -48,7 +48,7 @@ mod init_directory_tests { let run_command = build_simple_command_runner(Ok(Some(String::from("")))); let write_file = |_file_path: &str, _contents: &str, _x: bool| Err(String::from("")); let file_exists = |_path: &str| panic!("Should not get here"); - let result = init(run_command, write_file, file_exists, vec![]); + let result = init(run_command, write_file, file_exists, &[]); assert_eq!(result, Err(String::from("Unable to create git hooks"))); } @@ -57,7 +57,7 @@ mod init_directory_tests { let run_command = build_simple_command_runner(Ok(Some(String::from("")))); let write_file = |_file_path: &str, _contents: &str, _x: bool| Ok(()); let file_exists = |_path: &str| Err(()); - let result = init(run_command, write_file, file_exists, vec![]); + let result = init(run_command, write_file, file_exists, &[]); assert_eq!(result, Err(String::from("Unable to create config file"))); } @@ -66,7 +66,7 @@ mod init_directory_tests { let run_command = build_simple_command_runner(Ok(Some(String::from("")))); let write_file = |_file_path: &str, _contents: &str, _x: bool| Ok(()); let file_exists = |_path: &str| Ok(false); - let result = init(run_command, write_file, file_exists, vec![]); + let result = init(run_command, write_file, file_exists, &[]); assert_eq!(result, Ok(())); } } @@ -91,7 +91,7 @@ mod init_tests { }; let write_file = |_file_path: &str, _contents: &str, _x: bool| Ok(()); let file_exists = |_path: &str| Ok(false); - let result = init(run_command, write_file, file_exists, vec![]); + let result = init(run_command, write_file, file_exists, &[]); assert_eq!(result, Ok(())); } }