Repository: swellaby/rusty-hook
Pull request #115 (2020-09-22 18:06:37)

Switch from 'getopts' to 'clap'
## Changes
<!-- Summary of changes included in this PR -->
- Switches from the [getopts](https://crates.io/crates/getopts) crate to [clap 3.0](https://crates.io/crates/clap).
  - This allows for simpler, easier to understand code, and an actual help menu (invalid arguments won't panic now, they'll actually provide a help menu)

aspenluxxxy: This also provides the basis for passing git args to hook - they're actually part of the arguments now, and are passed (although not used yet) to `run()`
codecov[bot]: # [Codecov](https://codecov.io/gh/swellaby/rusty-hook/pull/115?src=pr&el=h1) Report
> Merging [#115](https://codecov.io/gh/swellaby/rusty-hook/pull/115?src=pr&el=desc) into [master](https://codecov.io/gh/swellaby/rusty-hook/commit/7f2eb4b519bd93b558e140813b7fdf37aec4a491?el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/swellaby/rusty-hook/pull/115/graphs/tree.svg?width=650&height=150&src=pr&token=gPTOAvGaQY)](https://codecov.io/gh/swellaby/rusty-hook/pull/115?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##            master      #115   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         4           
  Lines          129       129           
=========================================
  Hits           129       129           
```


| [Impacted Files](https://codecov.io/gh/swellaby/rusty-hook/pull/115?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/git.rs](https://codecov.io/gh/swellaby/rusty-hook/pull/115/diff?src=pr&el=tree#diff-c3JjL2dpdC5ycw==) | `100.00% <ø> (ø)` | |
| [src/rusty\_hook.rs](https://codecov.io/gh/swellaby/rusty-hook/pull/115/diff?src=pr&el=tree#diff-c3JjL3J1c3R5X2hvb2sucnM=) | `100.00% <ø> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/swellaby/rusty-hook/pull/115?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/swellaby/rusty-hook/pull/115?src=pr&el=footer). Last update [7f2eb4b...b770565](https://codecov.io/gh/swellaby/rusty-hook/pull/115?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

calebcartwright: Thanks for the PR!

I'd originally gone with getopts over clap deliberately as the former was notably more lightweight (at least at the time), and the benefits clap provides around the user-friendliness front weren't really applicable for rusty-hook because we didn't anticipate much, if any, human interaction.

That being said I'm fine with the switch to clap especially given future plans, like #5, that'd involve the human more. 
aspenluxxxy: I'm not sure why `shunit2.sh` is failing shellcheck... considering that I haven't touched it in this PR
calebcartwright: > I'm not sure why `shunit2.sh` is failing shellcheck... considering that I haven't touched it in this PR

That's unrelated to the changes here, no worries. That job is configured to use the latest version of ShellCheck so most likely what's happened is a new version that's change the way files are ignored. I'll update this later when I'm back at my machine and take a look at the changes here as well
aspenluxxxy: Also, when multi-command support is added, perhaps a `rusty-hook add` command could be added?
calebcartwright: > Also, when multi-command support is added, perhaps a rusty-hook add command could be added?

Could you elaborate? Not sure I follow
aspenluxxxy: Like, `rusty-hook add --hook pre-commit cargo check -- --all`
calebcartwright: > Like, `rusty-hook add --hook pre-commit cargo check -- --all`

Ahh okay gotcha. Probably worth opening a new issue for discussion. I'm not necessarily opposed to it but want to understand the use case/ease of use vs updating the toml file manually relative to additional code and features to support

Patch:
diff --git a/.gitignore b/.gitignore
index b570003..3c3ce41 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
 **/*.gcda
 **/*.gcno
 **/*kcov*/
+**/.idea
 .coverage/
 .testresults/
 cobertura.xml
diff --git a/Cargo.lock b/Cargo.lock
index c4a731c..642b4d0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,32 +1,115 @@
 # 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"
+dependencies = [
+ "hermit-abi 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.77 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "ci_info"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "envmnt 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "envmnt 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "clap"
+version = "3.0.0-beta.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap_derive 3.0.0-beta.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "os_str_bytes 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "textwrap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "clap_derive"
+version = "3.0.0-beta.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro-error 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "envmnt"
-version = "0.8.0"
+version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fsio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "getopts"
-version = "0.2.21"
+name = "fsio"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "hashbrown"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "heck"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.77 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "indexmap"
-version = "1.0.2"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hashbrown 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libc"
+version = "0.2.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -34,40 +117,188 @@ name = "nias"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "os_str_bytes"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro-error-attr 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rusty-hook"
 version = "0.11.2"
 dependencies = [
  "ci_info 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 3.0.0-beta.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "nias 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde"
-version = "1.0.98"
+version = "1.0.116"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "syn"
+version = "1.0.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "toml"
 version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "unicode-segmentation"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "unicode-width"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "vec_map"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "version_check"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-util"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
+"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 "checksum ci_info 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24f638c70e8c5753795cc9a8c07c44da91554a09e4cf11a7326e8161b0a3c45e"
-"checksum envmnt 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db101f16134ca37f91a6e30c32d9df5bbfcbe8d926f0c1f03602baf2fc2f7352"
-"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
-"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
+"checksum clap 3.0.0-beta.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
+"checksum clap_derive 3.0.0-beta.2 (registry+https://github.com/rust-lang/crates.io-index)" = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1"
+"checksum envmnt 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2d328fc287c61314c4a61af7cfdcbd7e678e39778488c7cb13ec133ce0f4059"
+"checksum fsio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1fd087255f739f4f1aeea69f11b72f8080e9c2e7645cd06955dad4a178a49e3"
+"checksum hashbrown 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7"
+"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+"checksum hermit-abi 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151"
+"checksum indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
+"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+"checksum libc 0.2.77 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
 "checksum nias 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0"
-"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113"
+"checksum os_str_bytes 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2ac6fe3538f701e339953a3ebbe4f39941aababa8a3f6964635b24ab526daeac"
+"checksum proc-macro-error 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+"checksum proc-macro-error-attr 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+"checksum proc-macro2 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
+"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+"checksum serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)" = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
+"checksum strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+"checksum syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
+"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+"checksum textwrap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
 "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
-"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
+"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
+"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
index a03992e..3a6345a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,7 +32,7 @@ exclude = [
 
 [dependencies]
 ci_info = "0.10.2"
-getopts = "0.2.21"
+clap = "3.0.0-beta.2"
 toml = "0.5.6"
 nias = "0.5.0"
 
diff --git a/src/git.rs b/src/git.rs
index d4282d3..87f361d 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -1,7 +1,7 @@
-mod hooks;
-
 pub use hooks::NO_CONFIG_FILE_FOUND_ERROR_CODE;
 
+mod hooks;
+
 pub fn get_root_directory_path<F>(
     run_command: F,
     target_directory: Option<&str>,
diff --git a/src/hook_files/hook_script.sh b/src/hook_files/hook_script.sh
index 37228c7..161614c 100644
--- a/src/hook_files/hook_script.sh
+++ b/src/hook_files/hook_script.sh
@@ -21,5 +21,6 @@ else
   ensureMinimumRustyHookCliVersion || true
 fi
 
-rusty-hook run --hook "${hookName}" "${gitParams}"
+# shellcheck disable=SC2046
+rusty-hook run --hook "${hookName}" $([ -z "$gitParams" ] && echo "" || echo "-- $gitParams")
 handleRustyHookCliResult $? "${hookName}"
diff --git a/src/main.rs b/src/main.rs
index ba8688d..c0b3abe 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,18 +1,31 @@
-mod rusty_hook;
-
+use std::env;
 use std::process::exit;
 
-extern crate ci_info;
-extern crate getopts;
-extern crate nias;
-use getopts::Options;
-use std::env;
+use clap::Clap;
 
-fn print_version() {
-    println!(env!("CARGO_PKG_VERSION"));
+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,
+    /// 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<String>,
+    },
 }
 
-fn init(_args: Vec<String>) {
+fn init() {
     if ci_info::is_ci() {
         println!("CI Environment detected. Skipping hook install");
         exit(0);
@@ -31,30 +44,14 @@ fn init(_args: Vec<String>) {
     };
 }
 
-fn run(args: Vec<String>) {
-    let mut opts = Options::new();
-    opts.optopt("h", "hook", "the git hook name", "NAME");
-    let matches = match opts.parse(&args[2..]) {
-        Ok(m) => m,
-        Err(_) => {
-            eprintln!("Error parsing options");
-            exit(1);
-        }
-    };
-
-    if !matches.opt_present("h") {
-        eprintln!("Hook name option missing");
-        exit(1);
-    }
-
-    let hook_name = matches.opt_str("h").unwrap();
-
+fn run(hook: String, args: String) {
     if let Err(err) = rusty_hook::run(
         nias::get_command_runner(),
         nias::get_file_existence_checker(),
         nias::get_file_reader(),
         nias::get_conditional_logger(),
-        &hook_name,
+        &hook,
+        &args,
     ) {
         match err {
             Some(e) if e == rusty_hook::NO_CONFIG_FILE_FOUND => {
@@ -70,13 +67,10 @@ fn run(args: Vec<String>) {
 }
 
 fn main() {
-    let args: Vec<String> = env::args().collect();
-    let first_opt = args[1].clone();
-    match first_opt.as_ref() {
-        "-v" => print_version(),
-        "--version" => print_version(),
-        "init" => init(args),
-        "run" => run(args),
-        _ => panic!("Unknown command or option: {}", first_opt),
-    };
+    let opts = RustyHookOpts::parse();
+    match opts {
+        RustyHookOpts::Init => init(),
+        RustyHookOpts::Version => println!(env!("CARGO_PKG_VERSION")),
+        RustyHookOpts::Run { hook, args } => run(hook, args.unwrap_or_default()),
+    }
 }
diff --git a/src/rusty_hook.rs b/src/rusty_hook.rs
index 4c759d5..d4f3888 100644
--- a/src/rusty_hook.rs
+++ b/src/rusty_hook.rs
@@ -1,12 +1,12 @@
+pub use config::NO_CONFIG_FILE_FOUND;
+pub use git::NO_CONFIG_FILE_FOUND_ERROR_CODE;
+
 #[path = "config.rs"]
 mod config;
 
 #[path = "git.rs"]
 mod git;
 
-pub use config::NO_CONFIG_FILE_FOUND;
-pub use git::NO_CONFIG_FILE_FOUND_ERROR_CODE;
-
 pub fn init_directory<F, G, H>(
     run_command: F,
     write_file: G,
@@ -50,6 +50,7 @@ pub fn run<F, G, H, I>(
     read_file: H,
     log: I,
     hook_name: &str,
+    _args: &str,
 ) -> Result<(), Option<String>>
 where
     F: Fn(&str, Option<&str>, bool) -> Result<Option<String>, Option<String>>,


Test patch:
diff --git a/src/rusty_hook_test.rs b/src/rusty_hook_test.rs
index 0e02669..3dc49c0 100644
--- a/src/rusty_hook_test.rs
+++ b/src/rusty_hook_test.rs
@@ -82,7 +82,7 @@ mod run_tests {
         let read_file = |_file_path: &str| panic!("");
         let file_exists = |_path: &str| panic!("");
         let log = |_path: &str, _should_log: bool| panic!("");
-        let result = run(run_command, file_exists, read_file, log, "");
+        let result = run(run_command, file_exists, read_file, log, "", "");
         assert_eq!(result, Err(Some(String::from(exp_err))));
     }
 
@@ -94,7 +94,7 @@ mod run_tests {
         let read_file = |_file_path: &str| Err(());
         let file_exists = |_path: &str| Ok(false);
         let log = |_path: &str, _should_log: bool| panic!("");
-        let result = run(run_command, file_exists, read_file, log, "");
+        let result = run(run_command, file_exists, read_file, log, "", "");
         assert_eq!(result, Err(Some(String::from(exp_err))));
     }
 
@@ -106,7 +106,7 @@ mod run_tests {
         let read_file = |_file_path: &str| Err(());
         let file_exists = |_path: &str| Ok(true);
         let log = |_path: &str, _should_log: bool| panic!("");
-        let result = run(run_command, file_exists, read_file, log, "");
+        let result = run(run_command, file_exists, read_file, log, "", "");
         assert_eq!(result, Err(Some(String::from(exp_err))));
     }
 
@@ -120,7 +120,7 @@ mod run_tests {
         let read_file = |_file_path: &str| Ok(String::from(contents));
         let file_exists = |_path: &str| Ok(true);
         let log = |_path: &str, _should_log: bool| panic!("");
-        let result = run(run_command, file_exists, read_file, log, "pre-push");
+        let result = run(run_command, file_exists, read_file, log, "pre-push", "");
         assert_eq!(result, Ok(()));
     }
 
@@ -133,7 +133,7 @@ mod run_tests {
         let read_file = |_file_path: &str| Ok(String::from(contents));
         let file_exists = |_path: &str| Ok(true);
         let log = |_path: &str, _should_log: bool| panic!("");
-        let result = run(run_command, file_exists, read_file, log, "pre-push");
+        let result = run(run_command, file_exists, read_file, log, "pre-push", "");
         assert_eq!(result, Err(Some(String::from(exp_err))));
     }
 
@@ -158,7 +158,7 @@ mod run_tests {
                 panic!("")
             }
         };
-        let result = run(run_command, file_exists, read_file, log, "pre-commit");
+        let result = run(run_command, file_exists, read_file, log, "pre-commit", "");
         assert_eq!(result, Ok(()));
     }
 
@@ -183,7 +183,7 @@ mod run_tests {
                 panic!("")
             }
         };
-        let result = run(run_command, file_exists, read_file, log, "pre-commit");
+        let result = run(run_command, file_exists, read_file, log, "pre-commit", "");
         assert_eq!(result, Ok(()));
     }
 
@@ -200,7 +200,7 @@ mod run_tests {
         let read_file = |_file_path: &str| Ok(String::from(contents));
         let file_exists = |_path: &str| Ok(true);
         let log = |_path: &str, _should_log: bool| ();
-        let result = run(run_command, file_exists, read_file, log, "pre-commit");
+        let result = run(run_command, file_exists, read_file, log, "pre-commit", "");
         assert_eq!(result, Ok(()));
     }
 
@@ -222,7 +222,7 @@ mod run_tests {
         let read_file = |_file_path: &str| Ok(String::from(contents));
         let file_exists = |_path: &str| Ok(true);
         let log = |_path: &str, _should_log: bool| ();
-        let result = run(run_command, file_exists, read_file, log, "pre-commit");
+        let result = run(run_command, file_exists, read_file, log, "pre-commit", "");
         assert_eq!(result, Err(Some(String::from(exp_err))));
     }
 }