init
This commit is contained in:
commit
0a48113d38
10 changed files with 1660 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
624
Cargo.lock
generated
Normal file
624
Cargo.lock
generated
Normal file
|
@ -0,0 +1,624 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"crossterm_winapi",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"signal-hook",
|
||||||
|
"signal-hook-mio",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm_winapi"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dyn-clone"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuzzy-matcher"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
|
||||||
|
dependencies = [
|
||||||
|
"thread_local",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fxhash"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "g"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"inquire",
|
||||||
|
"serde_json",
|
||||||
|
"subprocess",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inquire"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.8.0",
|
||||||
|
"crossterm",
|
||||||
|
"dyn-clone",
|
||||||
|
"fuzzy-matcher",
|
||||||
|
"fxhash",
|
||||||
|
"newline-converter",
|
||||||
|
"once_cell",
|
||||||
|
"unicode-segmentation",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.169"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "newline-converter"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.8.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.217"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.217"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.137"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-mio"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"signal-hook",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subprocess"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.96"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[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-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.59.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
|
"windows_aarch64_msvc 0.48.5",
|
||||||
|
"windows_i686_gnu 0.48.5",
|
||||||
|
"windows_i686_msvc 0.48.5",
|
||||||
|
"windows_x86_64_gnu 0.48.5",
|
||||||
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
|
"windows_x86_64_msvc 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.52.6",
|
||||||
|
"windows_aarch64_msvc 0.52.6",
|
||||||
|
"windows_i686_gnu 0.52.6",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc 0.52.6",
|
||||||
|
"windows_x86_64_gnu 0.52.6",
|
||||||
|
"windows_x86_64_gnullvm 0.52.6",
|
||||||
|
"windows_x86_64_msvc 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yansi"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "g"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "4.5.26", features = ["cargo"] }
|
||||||
|
inquire = "0.7.5"
|
||||||
|
serde_json = "1.0.137"
|
||||||
|
subprocess = "0.2.9"
|
||||||
|
yansi = "1.0.1"
|
38
PKGBUILD
Normal file
38
PKGBUILD
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Maintainer: JMARyA <jmarya@hydrar.de>
|
||||||
|
pkgname=g
|
||||||
|
pkgver=main
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc="git workflow wrapper"
|
||||||
|
arch=('x86_64')
|
||||||
|
url="https://git.hydrar.de/jmarya/g"
|
||||||
|
license=("MIT")
|
||||||
|
depends=("git" "serie" "ripgrep" "onefetch")
|
||||||
|
makedepends=("rustup" "git")
|
||||||
|
source=("${pkgname}::git+https://git.hydrar.de/jmarya/g.git")
|
||||||
|
sha256sums=("SKIP")
|
||||||
|
|
||||||
|
pkgver() {
|
||||||
|
cd "$srcdir/$pkgname"
|
||||||
|
echo "$(date +%Y.%m.%d)_$(git rev-parse --short HEAD)"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
cd "$srcdir/$pkgname"
|
||||||
|
rustup default nightly
|
||||||
|
cargo fetch
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$srcdir/$pkgname"
|
||||||
|
cargo build --release
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
cd "$srcdir/$pkgname"
|
||||||
|
cargo test --release
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
cd "$srcdir/$pkgname"
|
||||||
|
install -Dm755 "target/release/g" "$pkgdir/usr/bin/g"
|
||||||
|
}
|
101
README.md
Normal file
101
README.md
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
# `g`: The TOP G of Git Wrappers
|
||||||
|
|
||||||
|
Welcome to `g`, the ultimate Git wrapper for the hustlers. Inspired by the TOP G mindset, `g` ensures your version control game is faster, cleaner, and dripping with efficiency. Whether you're stacking branches like cash or committing to greatness, `g` is your ticket into the Real Git.
|
||||||
|
|
||||||
|
## Why choose `g`?
|
||||||
|
- **Efficiency is key** - Git commands can feel like a 9-to-5 grind. `g` is here to automate the hustle.
|
||||||
|
- **Stay focused** - Just like in Hustlers University, distractions are the enemy. `g` keeps you in the zone.
|
||||||
|
- **Work like a TOP G** - This isn’t just version control; it’s a lifestyle. Be the alpha in your repo.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
### Repository Management
|
||||||
|
- `g bootstrap <BASE> <REPO>`
|
||||||
|
|
||||||
|
Initialize a new repository from a base repository.
|
||||||
|
|
||||||
|
> You don’t start from scratch; you leverage the foundation like a true hustler.
|
||||||
|
|
||||||
|
### Branching
|
||||||
|
- `g branch`
|
||||||
|
|
||||||
|
Display all branches.
|
||||||
|
|
||||||
|
> Know your assets, track your investments. This is your repo empire.
|
||||||
|
|
||||||
|
- `g new <BRANCH>`
|
||||||
|
|
||||||
|
Create a new branch.
|
||||||
|
|
||||||
|
> In the world of branching, growth is king.
|
||||||
|
|
||||||
|
- `g remove <BRANCH>`
|
||||||
|
|
||||||
|
Remove a branch.
|
||||||
|
|
||||||
|
> Trim the weak branches so the strong ones can thrive.
|
||||||
|
|
||||||
|
### Syncing
|
||||||
|
- `g fetch`
|
||||||
|
|
||||||
|
Run `git fetch --prune`.
|
||||||
|
|
||||||
|
> Prune like a gardener who only grows money trees. Keep the repo tight and right.
|
||||||
|
|
||||||
|
- `g pull`
|
||||||
|
|
||||||
|
Run `git pull --prune`.
|
||||||
|
|
||||||
|
> Pull harder than a Bugatti in first gear. Stay synced, stay winning.
|
||||||
|
|
||||||
|
- `g push`
|
||||||
|
|
||||||
|
Push changes to a remote repository.
|
||||||
|
|
||||||
|
> Send your code to the cloud like it’s your private jet.
|
||||||
|
|
||||||
|
### Logs and Status
|
||||||
|
- `g log`
|
||||||
|
|
||||||
|
Display the commit log.
|
||||||
|
|
||||||
|
> The hustle doesn’t lie. Your commit history is your legacy.
|
||||||
|
|
||||||
|
- `g status`
|
||||||
|
|
||||||
|
Show the current repository status.
|
||||||
|
|
||||||
|
> Stay on top of your repo. TOP Gs don’t leave things to chance.
|
||||||
|
|
||||||
|
### Commit Management
|
||||||
|
- `g todo`
|
||||||
|
|
||||||
|
Show open TODOs within the repository.
|
||||||
|
|
||||||
|
> Keep the numbers rising, except this one.
|
||||||
|
|
||||||
|
- `g save`
|
||||||
|
|
||||||
|
Create a WIP (Work In Progress) commit.
|
||||||
|
|
||||||
|
> Sometimes you gotta save it now to cash in later.
|
||||||
|
|
||||||
|
- `g commit [-a, --all] [-d, --done] [-i, --interactive] [-m, --message <MSG>]`
|
||||||
|
|
||||||
|
Commit changes.
|
||||||
|
|
||||||
|
- `-all` adds all changed files to Git.
|
||||||
|
|
||||||
|
- `--done` refuses to commit with open TODOs.
|
||||||
|
|
||||||
|
- `--interactive` creates gitmoji commits with an interactive menu.
|
||||||
|
|
||||||
|
- `--message` sets the commit message directly.
|
||||||
|
|
||||||
|
> Seal the deal with a strong message. Every commit should flex."
|
||||||
|
|
||||||
|
### Adding Files
|
||||||
|
- `g add <FILE>`
|
||||||
|
|
||||||
|
Stage files for the next commit.
|
||||||
|
|
||||||
|
> Add value, one file at a time.
|
89
src/args.rs
Normal file
89
src/args.rs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
use clap::{arg, command};
|
||||||
|
|
||||||
|
pub fn get_args() -> clap::ArgMatches {
|
||||||
|
command!()
|
||||||
|
.about("Git wrapper")
|
||||||
|
.subcommand(
|
||||||
|
command!("bootstrap")
|
||||||
|
.about("Bootstrap a new repository from base repository")
|
||||||
|
.arg(arg!(<BASE> "Base repository").required(true))
|
||||||
|
.arg(arg!(<NEW> "Repository name").required(true))
|
||||||
|
.alias("bs"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!("todo")
|
||||||
|
.about("Show open TODOs in repository")
|
||||||
|
.alias("t"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!("new")
|
||||||
|
.about("Create a new branch")
|
||||||
|
.arg(arg!(<BRANCH> "Branch name").required(true))
|
||||||
|
.alias("n"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!("commit")
|
||||||
|
.about("Commit current changes")
|
||||||
|
.alias("c")
|
||||||
|
.arg(arg!(-a --all "Add all changed files to commit"))
|
||||||
|
.arg(arg!(-d --done "Only allow commiting if no TODOs are present"))
|
||||||
|
.arg(
|
||||||
|
arg!(-i --interactive "Write interactive commit message with gitmoji standard")
|
||||||
|
.conflicts_with("message"),
|
||||||
|
)
|
||||||
|
.arg(arg!(-m --message <MSG> "Commit message").required(false)),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!("remove")
|
||||||
|
.about("Remove a branch")
|
||||||
|
.arg(arg!(<BRANCH> "Branch name").required(true))
|
||||||
|
.alias("r"),
|
||||||
|
)
|
||||||
|
.subcommand(command!("branch").about("Show branches").alias("b"))
|
||||||
|
.subcommand(
|
||||||
|
command!()
|
||||||
|
.name("push")
|
||||||
|
.about("Push to a remote")
|
||||||
|
.arg(arg!(-f --force "Force push"))
|
||||||
|
.alias("p"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!()
|
||||||
|
.name("status")
|
||||||
|
.about("Show git status")
|
||||||
|
.alias("stat")
|
||||||
|
.alias("stats"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!()
|
||||||
|
.name("add")
|
||||||
|
.about("Add files to git")
|
||||||
|
.alias("a")
|
||||||
|
.arg(arg!(<FILE> "File to add").required(true)),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!()
|
||||||
|
.name("fetch")
|
||||||
|
.about("Run git fetch --prune")
|
||||||
|
.alias("f"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!()
|
||||||
|
.name("pull")
|
||||||
|
.about("Run git pull --prune")
|
||||||
|
.alias("p"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!()
|
||||||
|
.name("log")
|
||||||
|
.about("Show git commit log")
|
||||||
|
.alias("l"),
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
command!()
|
||||||
|
.name("save")
|
||||||
|
.about("Create a WIP commit")
|
||||||
|
.alias("s"),
|
||||||
|
)
|
||||||
|
.get_matches()
|
||||||
|
}
|
260
src/git.rs
Normal file
260
src/git.rs
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
use subprocess::Exec;
|
||||||
|
use yansi::{Color, Paint};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
NO_COMMIT_REGEX, no_commit_amount, precommit::rust_pre_commit, read_stdout, show_rg,
|
||||||
|
todos_amount,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Check if the current repository has a remote set up
|
||||||
|
pub fn has_remote() -> bool {
|
||||||
|
let e = Exec::cmd("git").arg("remote").arg("-v");
|
||||||
|
let str = read_stdout(e);
|
||||||
|
!str.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new branch and switch to it in the current repository
|
||||||
|
pub fn create_new_branch(branch: &str) {
|
||||||
|
let mut git = Exec::cmd("git")
|
||||||
|
.arg("checkout")
|
||||||
|
.arg("-b")
|
||||||
|
.arg(branch)
|
||||||
|
.popen()
|
||||||
|
.unwrap();
|
||||||
|
git.wait().unwrap();
|
||||||
|
if has_remote() {
|
||||||
|
let mut git = Exec::cmd("git")
|
||||||
|
.arg("push")
|
||||||
|
.arg("-u")
|
||||||
|
.arg("origin")
|
||||||
|
.arg(branch)
|
||||||
|
.popen()
|
||||||
|
.unwrap();
|
||||||
|
git.wait().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push the current repository to remote
|
||||||
|
pub fn push(force: bool) {
|
||||||
|
let mut cmd = Exec::cmd("git")
|
||||||
|
.arg("push")
|
||||||
|
.arg("--set-upstream")
|
||||||
|
.arg("origin");
|
||||||
|
|
||||||
|
if force {
|
||||||
|
cmd = cmd.arg("--force-with-lease");
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.popen().unwrap().wait().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete a branch from the current repository
|
||||||
|
pub fn delete_branch(branch: &str) {
|
||||||
|
let mut git = Exec::cmd("git")
|
||||||
|
.arg("branch")
|
||||||
|
.arg("-d")
|
||||||
|
.arg(branch)
|
||||||
|
.popen()
|
||||||
|
.unwrap();
|
||||||
|
git.wait().unwrap();
|
||||||
|
if has_remote() {
|
||||||
|
let mut git = Exec::cmd("git")
|
||||||
|
.arg("push")
|
||||||
|
.arg("origin")
|
||||||
|
.arg("--delete")
|
||||||
|
.arg(branch)
|
||||||
|
.popen()
|
||||||
|
.unwrap();
|
||||||
|
git.wait().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the title of the last commit
|
||||||
|
pub fn last_commit() -> String {
|
||||||
|
let e = Exec::cmd("git").arg("log").arg("-1").arg("--pretty=%B");
|
||||||
|
read_stdout(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get all files affected by last commit
|
||||||
|
pub fn last_commit_files() -> Vec<String> {
|
||||||
|
let file_str = read_stdout(
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("diff-tree")
|
||||||
|
.arg("--no-commit-id")
|
||||||
|
.arg("--name-only")
|
||||||
|
.arg("-r")
|
||||||
|
.arg("HEAD"),
|
||||||
|
);
|
||||||
|
|
||||||
|
file_str.split('\n').map(|x| x.to_string()).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a file to git
|
||||||
|
pub fn git_add(file: &str) {
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("add")
|
||||||
|
.arg(file)
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a Vec of programming languages used in this repository
|
||||||
|
pub fn get_languages() -> Vec<String> {
|
||||||
|
let e: Exec = Exec::cmd("onefetch").arg("-o").arg("json");
|
||||||
|
let json_str = read_stdout(e);
|
||||||
|
if let Result::<serde_json::Value, _>::Ok(json) = serde_json::from_str(&json_str) {
|
||||||
|
let languages = (|| {
|
||||||
|
let fields = json.as_object()?.get("infoFields")?.as_array()?;
|
||||||
|
let langs = fields
|
||||||
|
.iter()
|
||||||
|
.find(|x| x.as_object().unwrap().contains_key("LanguagesInfo"))?;
|
||||||
|
let langs = langs
|
||||||
|
.as_object()?
|
||||||
|
.get("LanguagesInfo")?
|
||||||
|
.as_object()?
|
||||||
|
.get("languagesWithPercentage")?
|
||||||
|
.as_array()?;
|
||||||
|
Some(
|
||||||
|
langs
|
||||||
|
.iter()
|
||||||
|
.map(|x| {
|
||||||
|
x.as_object()
|
||||||
|
.unwrap()
|
||||||
|
.get("language")
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
})();
|
||||||
|
|
||||||
|
languages.unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Commit changes to the repository.
|
||||||
|
pub fn commit(all: bool, done: bool, msg: &str) {
|
||||||
|
// Work In Progress Save Commit
|
||||||
|
if last_commit().as_str() == "WIP" {
|
||||||
|
// Get files affected by commit
|
||||||
|
let last_commit_files = last_commit_files();
|
||||||
|
|
||||||
|
// Reset last commit
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("reset")
|
||||||
|
.arg("HEAD~1")
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Readd files affected by commit
|
||||||
|
for file in last_commit_files {
|
||||||
|
git_add(&file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check TODOs
|
||||||
|
let todos = todos_amount();
|
||||||
|
|
||||||
|
if todos > 0 {
|
||||||
|
println!(
|
||||||
|
"{}: Repository still contains {todos} TODO entries.",
|
||||||
|
"Warning".paint(Color::Yellow)
|
||||||
|
);
|
||||||
|
|
||||||
|
if done {
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
"💀 Make sure to close them before commiting or we can't rest in peace..."
|
||||||
|
.paint(Color::Red)
|
||||||
|
);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Impossible commits
|
||||||
|
if no_commit_amount() > 0 {
|
||||||
|
println!("{}", "Unable to commit because of:".paint(Color::Red));
|
||||||
|
show_rg(NO_COMMIT_REGEX);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Laguage specific pre-commit hooks
|
||||||
|
for lang in get_languages() {
|
||||||
|
match lang.as_str() {
|
||||||
|
"Rust" => {
|
||||||
|
rust_pre_commit();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if all {
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("add")
|
||||||
|
.arg("-A")
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("commit")
|
||||||
|
.arg("-m")
|
||||||
|
.arg(msg)
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetch remote state
|
||||||
|
pub fn fetch() {
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("fetch")
|
||||||
|
.arg("--prune")
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pull remote changes
|
||||||
|
pub fn pull() {
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("pull")
|
||||||
|
.arg("--prune")
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bootstrap a git repository using a base template
|
||||||
|
pub fn bootstrap(base: &str, name: &str) {
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("clone")
|
||||||
|
.arg(base)
|
||||||
|
.arg(name)
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
std::fs::remove_dir_all(std::path::Path::new(name).join(".git")).unwrap();
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("init")
|
||||||
|
.arg("--quiet")
|
||||||
|
.cwd(std::path::Path::new(name))
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
360
src/gitmoji.rs
Normal file
360
src/gitmoji.rs
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
pub fn select_from_list<F: FnOnce(&str) -> String>(
|
||||||
|
prompt: &str,
|
||||||
|
lst: Vec<&str>,
|
||||||
|
quit: bool,
|
||||||
|
then: F,
|
||||||
|
) -> String {
|
||||||
|
match inquire::Select::new(prompt, lst).prompt() {
|
||||||
|
Ok(val) => then(val),
|
||||||
|
Err(_) => {
|
||||||
|
if quit {
|
||||||
|
eprintln!("Nothing selected");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji() -> String {
|
||||||
|
let topics = vec![
|
||||||
|
"Fix",
|
||||||
|
"Refactor",
|
||||||
|
"Improve",
|
||||||
|
"Add/Update",
|
||||||
|
"Remove",
|
||||||
|
"Git",
|
||||||
|
"UI",
|
||||||
|
"Dependency",
|
||||||
|
"Security",
|
||||||
|
"Text",
|
||||||
|
"Test",
|
||||||
|
"Fun",
|
||||||
|
"Misc",
|
||||||
|
];
|
||||||
|
|
||||||
|
let select = select_from_list(
|
||||||
|
"Gitmoji Intention Topic",
|
||||||
|
topics,
|
||||||
|
true,
|
||||||
|
|topic| match topic {
|
||||||
|
"Fix" => select_gitmoji_fix(),
|
||||||
|
"Improve" => select_gitmoji_improvement(),
|
||||||
|
"Remove" => select_gitmoji_remove(),
|
||||||
|
"Dependency" => select_gitmoji_dependency(),
|
||||||
|
"Test" => select_gitmoji_test(),
|
||||||
|
"Git" => select_gitmoji_git(),
|
||||||
|
"Refactor" => select_gitmoji_refactor(),
|
||||||
|
"UI" => select_gitmoji_ui(),
|
||||||
|
"Text" => select_gitmoji_text(),
|
||||||
|
"Fun" => select_gitmoji_fun(),
|
||||||
|
"Security" => select_gitmoji_security(),
|
||||||
|
"Add/Update" => select_gitmoji_add_update(),
|
||||||
|
_ => select_gitmoji_misc(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if select.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
select
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_fix() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"🐛 Fix a bug",
|
||||||
|
"🩹 Simple fix for a non-critical issue",
|
||||||
|
"🚑️ Critical hotfix",
|
||||||
|
"✏️ Fix typos",
|
||||||
|
"💚 Fix CI Build",
|
||||||
|
"🔒️ Fix security or privacy issues",
|
||||||
|
"🚨 Fix compiler / linter warnings",
|
||||||
|
"🥅 Catch errors",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_improvement() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"✨ Introduce new features",
|
||||||
|
"🎨 Improve structure / format of the code",
|
||||||
|
"⚡️ Improve performance",
|
||||||
|
"🧑💻 Improve developer experience",
|
||||||
|
"🚸 Improve user experience / usability",
|
||||||
|
"♿️ Improve accessibility",
|
||||||
|
"🔍️ Improve SEO",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_remove() -> String {
|
||||||
|
let options = vec!["🔥 Remove code or files", "⚰️ Remove dead code"];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_dependency() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"➖ Remove a dependency",
|
||||||
|
"➕ Add a dependency",
|
||||||
|
"⬇️ Downgrade dependencies",
|
||||||
|
"⬆️ Upgrade dependencies",
|
||||||
|
"📌 Pin dependencies to specific versions",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_test() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"✅ Add, update, or pass tests",
|
||||||
|
"🧪 Add a failing test",
|
||||||
|
"🤡 Mock things",
|
||||||
|
"⚗️ Perform experiments",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_fun() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"🍻 Write code drunkenly",
|
||||||
|
"🍃 Write code high",
|
||||||
|
"❄ Write code on coke",
|
||||||
|
"🍄 Write code on psychedelics",
|
||||||
|
"🥚 Add or update an easter egg",
|
||||||
|
"💩 Write bad code that needs to be improved",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_git() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"⏪️ Revert changes",
|
||||||
|
"🔀 Merge branches",
|
||||||
|
"🔖 Release / Version tags",
|
||||||
|
"🙈 Add or update a .gitignore file",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_refactor() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"♻️ Refactor code",
|
||||||
|
"🗑️ Deprecate code that needs to be cleaned up",
|
||||||
|
"🚚 Move or rename resources (e.g.: files, paths, routes)",
|
||||||
|
"🍱 Add or update assets",
|
||||||
|
"👽️ Update code due to external API changes",
|
||||||
|
"💡 Add or update comments in source code",
|
||||||
|
"🏷️ Add or update types",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_ui() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"💄 Add or update the UI and style files",
|
||||||
|
"📱 Work on responsive design",
|
||||||
|
"💫 Add or update animations and transitions",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_text() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"📝 Add or update documentation",
|
||||||
|
"🌐 Internationalization and localization",
|
||||||
|
"💬 Add or update text and literals",
|
||||||
|
"👥 Add or update contributor(s)",
|
||||||
|
"📄 Add or update license",
|
||||||
|
"🔊 Add or update logs",
|
||||||
|
"🔇 Remove logs",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_security() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"🛂 Work on code related to authorization, roles and permissions",
|
||||||
|
"🔐 Add or update secrets",
|
||||||
|
"🦺 Add or update code related to validation",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_add_update() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"👷 Add or update CI build system",
|
||||||
|
"🔧 Add or update configuration files",
|
||||||
|
"🔨 Add or update development scripts",
|
||||||
|
"📦️ Add or update compiled files or packages",
|
||||||
|
"🚩 Add, update, or remove feature flags",
|
||||||
|
"🩺 Add or update healthcheck",
|
||||||
|
"🧵 Add or update code related to multithreading or concurrency",
|
||||||
|
"🌱 Add or update seed files",
|
||||||
|
"📸 Add or update snapshots",
|
||||||
|
"📈 Add or update analytics or track code",
|
||||||
|
"👔 Add or update business logic",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_gitmoji_misc() -> String {
|
||||||
|
let options = vec![
|
||||||
|
"🎉 Begin a project",
|
||||||
|
"🚀 Deploy stuff",
|
||||||
|
"🚧 Work in progress",
|
||||||
|
"💥 Introduce breaking changes",
|
||||||
|
"🗃️ Perform database related changes",
|
||||||
|
"🏗️ Make architectural changes",
|
||||||
|
"🧱 Infrastructure related changes",
|
||||||
|
"💸 Add sponsorships or money related infrastructure",
|
||||||
|
"🧐 Data exploration/inspection",
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = select_from_list("Gitmoji Intention", options, false, |selected| {
|
||||||
|
selected.split_whitespace().next().unwrap().to_string()
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_empty() {
|
||||||
|
return select_gitmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CommitMessage {
|
||||||
|
gitmoji: String,
|
||||||
|
title: String,
|
||||||
|
body: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommitMessage {
|
||||||
|
pub const fn new(gitmoji: String, title: String, body: Option<String>) -> Self {
|
||||||
|
CommitMessage {
|
||||||
|
gitmoji,
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_msg(&self) -> String {
|
||||||
|
let mut msg = self.gitmoji.clone();
|
||||||
|
msg.push_str(&format!(" {}", self.title));
|
||||||
|
|
||||||
|
if let Some(body) = &self.body {
|
||||||
|
if !body.is_empty() {
|
||||||
|
msg.push_str(&format!("\n\n{body}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
}
|
154
src/main.rs
Normal file
154
src/main.rs
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
use git::{bootstrap, commit, create_new_branch, delete_branch, fetch, git_add, pull, push};
|
||||||
|
use gitmoji::{CommitMessage, select_gitmoji};
|
||||||
|
use std::io::Read;
|
||||||
|
use subprocess::{Exec, Redirection};
|
||||||
|
|
||||||
|
mod args;
|
||||||
|
mod git;
|
||||||
|
mod gitmoji;
|
||||||
|
mod precommit;
|
||||||
|
|
||||||
|
pub fn read_stdout(e: Exec) -> String {
|
||||||
|
let mut p = e.stdout(Redirection::Pipe).popen().unwrap();
|
||||||
|
let mut str = String::new();
|
||||||
|
p.stdout.as_mut().unwrap().read_to_string(&mut str).unwrap();
|
||||||
|
str.trim().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
const TODO_REGEX: &str = r" (todo|unimplemented|refactor|wip|fix)(:|!|\n|\ :)";
|
||||||
|
const NO_COMMIT_REGEX: &str = r"(NOCOMMIT|ENSURE: )";
|
||||||
|
|
||||||
|
pub fn no_commit_amount() -> u64 {
|
||||||
|
rg_matches(NO_COMMIT_REGEX)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn todos_amount() -> u64 {
|
||||||
|
rg_matches(TODO_REGEX)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rg_matches(regex: &str) -> u64 {
|
||||||
|
let mut cmd = Exec::cmd("rg")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("--json")
|
||||||
|
.arg("--multiline")
|
||||||
|
.arg(regex)
|
||||||
|
.stdout(Redirection::Pipe)
|
||||||
|
.popen()
|
||||||
|
.unwrap();
|
||||||
|
cmd.wait().unwrap();
|
||||||
|
let mut str = String::new();
|
||||||
|
cmd.stdout
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.read_to_string(&mut str)
|
||||||
|
.unwrap();
|
||||||
|
let last_line = str.lines().last().unwrap();
|
||||||
|
let val: serde_json::Value = serde_json::from_str(last_line).unwrap();
|
||||||
|
let ret = (|| {
|
||||||
|
val.as_object()
|
||||||
|
.unwrap()
|
||||||
|
.get("data")?
|
||||||
|
.as_object()?
|
||||||
|
.get("stats")?
|
||||||
|
.as_object()?
|
||||||
|
.get("matches")?
|
||||||
|
.as_number()
|
||||||
|
.unwrap()
|
||||||
|
.as_i64()
|
||||||
|
})();
|
||||||
|
ret.unwrap_or(0) as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show_rg(regex: &str) {
|
||||||
|
Exec::cmd("rg")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("--multiline")
|
||||||
|
.arg(regex)
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show_todos() {
|
||||||
|
println!("{} todos found.", todos_amount());
|
||||||
|
show_rg(TODO_REGEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = args::get_args();
|
||||||
|
|
||||||
|
match args.subcommand() {
|
||||||
|
Some(("bootstrap", bs_args)) => {
|
||||||
|
let base = bs_args.get_one::<String>("BASE").unwrap();
|
||||||
|
let repo = bs_args.get_one::<String>("NEW").unwrap();
|
||||||
|
bootstrap(base, repo);
|
||||||
|
}
|
||||||
|
Some(("new", new_args)) => {
|
||||||
|
let branch: &String = new_args.get_one("BRANCH").unwrap();
|
||||||
|
create_new_branch(branch);
|
||||||
|
}
|
||||||
|
Some(("remove", rm_args)) => {
|
||||||
|
let branch: &String = rm_args.get_one("BRANCH").unwrap();
|
||||||
|
delete_branch(branch);
|
||||||
|
}
|
||||||
|
Some(("branch", _)) => {
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("branch")
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Some(("push", push_args)) => {
|
||||||
|
let force = push_args.get_flag("force");
|
||||||
|
push(force);
|
||||||
|
}
|
||||||
|
Some(("commit", commit_args)) => {
|
||||||
|
let all = commit_args.get_flag("all");
|
||||||
|
let done = commit_args.get_flag("done");
|
||||||
|
let msg: Option<&String> = commit_args.get_one("message");
|
||||||
|
let interactive = commit_args.get_flag("interactive");
|
||||||
|
|
||||||
|
if interactive || msg.is_none() {
|
||||||
|
let gitmoji = select_gitmoji();
|
||||||
|
let title = inquire::prompt_text("Commit Title").unwrap();
|
||||||
|
let body = inquire::Text::new("Commit Description")
|
||||||
|
.with_page_size(5)
|
||||||
|
.prompt();
|
||||||
|
let msg = CommitMessage::new(gitmoji, title, body.ok()).to_msg();
|
||||||
|
commit(all, done, &msg);
|
||||||
|
} else {
|
||||||
|
commit(all, done, msg.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(("save", _)) => {
|
||||||
|
commit(true, false, "WIP");
|
||||||
|
}
|
||||||
|
Some(("fetch", _)) => {
|
||||||
|
fetch();
|
||||||
|
}
|
||||||
|
Some(("pull", _)) => {
|
||||||
|
pull();
|
||||||
|
}
|
||||||
|
Some(("todo", _)) => {
|
||||||
|
show_todos();
|
||||||
|
}
|
||||||
|
Some(("log", _)) => {
|
||||||
|
Exec::cmd("serie").popen().unwrap().wait().unwrap();
|
||||||
|
}
|
||||||
|
Some(("status", _)) => {
|
||||||
|
Exec::cmd("git")
|
||||||
|
.arg("status")
|
||||||
|
.popen()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Some(("add", args)) => {
|
||||||
|
let file: &String = args.get_one("FILE").unwrap();
|
||||||
|
git_add(file);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
22
src/precommit.rs
Normal file
22
src/precommit.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use crate::{git::git_add, read_stdout};
|
||||||
|
use subprocess::Exec;
|
||||||
|
|
||||||
|
pub fn rust_pre_commit() {
|
||||||
|
println!("Running cargo fmt");
|
||||||
|
let e = Exec::cmd("cargo").arg("fmt").arg("--verbose");
|
||||||
|
let out = read_stdout(e);
|
||||||
|
|
||||||
|
for line in out.lines() {
|
||||||
|
println!("line {line}");
|
||||||
|
if line.starts_with("rustfmt") {
|
||||||
|
let mut split: Vec<_> = line.split_whitespace().collect();
|
||||||
|
split.reverse();
|
||||||
|
split.pop();
|
||||||
|
split.pop();
|
||||||
|
split.pop();
|
||||||
|
split.reverse();
|
||||||
|
let file = split.join(" ");
|
||||||
|
git_add(&file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue