From a35c041999a9e5ca07fb22755fde85331cf92b41 Mon Sep 17 00:00:00 2001 From: piegames Date: Tue, 25 Feb 2025 15:39:49 +0100 Subject: [PATCH] cli: Migrate to native clap Structopt has mostly been assimilated into clap_derive, so it didn't even require much changes --- Cargo.lock | 243 ++++++++++++---------------------------------------- Cargo.toml | 2 +- README.md | 241 +++++++++++++++++++++------------------------------ src/cli.rs | 119 ++++++++++++------------- src/main.rs | 4 +- 5 files changed, 218 insertions(+), 391 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c93aa37..9b2f95c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,15 +26,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anstream" version = "0.6.14" @@ -98,18 +89,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", + "syn", ] [[package]] @@ -139,12 +119,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[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" @@ -177,19 +151,44 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.34.0" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", + "anstream", + "anstyle", + "clap_lex", "strsim", - "textwrap", - "unicode-width", - "vec_map", ] +[[package]] +name = "clap_derive" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[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.1" @@ -202,7 +201,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.8.0", + "bitflags", "parking_lot", "rustix", ] @@ -215,7 +214,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] @@ -327,7 +326,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] @@ -385,21 +384,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" -version = "0.3.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -618,7 +605,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] @@ -670,12 +657,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "lenient_semver_parser" version = "0.4.2" @@ -773,6 +754,7 @@ version = "0.2.4" dependencies = [ "anyhow", "async-trait", + "clap", "crossterm", "env_logger", "futures", @@ -782,7 +764,6 @@ dependencies = [ "reqwest", "serde", "serde_json", - "structopt", "tokio", "url", ] @@ -793,7 +774,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] @@ -858,7 +839,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] @@ -873,30 +854,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[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 1.0.109", - "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.85" @@ -921,7 +878,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.8.0", + "bitflags", ] [[package]] @@ -1021,7 +978,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.8.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -1098,7 +1055,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] @@ -1173,33 +1130,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "strsim" -version = "0.8.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -1207,17 +1140,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.66" @@ -1243,16 +1165,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", + "syn", ] [[package]] @@ -1291,7 +1204,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] @@ -1363,18 +1276,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode-width" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" - [[package]] name = "untrusted" version = "0.9.0" @@ -1411,18 +1312,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "want" version = "0.3.1" @@ -1459,7 +1348,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn", "wasm-bindgen-shared", ] @@ -1493,7 +1382,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1523,28 +1412,6 @@ dependencies = [ "rustls-pki-types", ] -[[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" @@ -1726,7 +1593,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", "synstructure", ] @@ -1747,7 +1614,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", "synstructure", ] @@ -1776,5 +1643,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index 282e59b..73479e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license = "EUPL-1.2" serde = { version = "^1.0", features = [ "derive" ] } serde_json = { version = "^1.0", features = ["preserve_order"] } url = { version = "^2.2.2", features = [ "serde" ] } -structopt = "^0.3" +clap = { version = "4.5", features = [ "derive", "env" ] } anyhow = "^1.0" tokio = { version = "^1.0", features = ["macros", "rt-multi-thread", "process"] } env_logger = { version = "^0.11.0", features = ["color", "auto-color", "regex"], default-features = false } diff --git a/README.md b/README.md index b03ae3d..0edf550 100644 --- a/README.md +++ b/README.md @@ -100,31 +100,23 @@ You may also use attributes from the JSON file, they are exposed 1:1. For exampl ```console $ npins help -npins 0.2.4 - -USAGE: - npins [OPTIONS] - -FLAGS: - -h, --help Prints help information - -V, --version Prints version information - -OPTIONS: - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] - [default: npins] - -SUBCOMMANDS: - add Adds a new pin entry - help Prints this message or the help of the given subcommand(s) - import-flake Try to import entries from flake.lock - import-niv Try to import entries from Niv - init Intializes the npins directory. Running this multiple times will restore/upgrade the - `default.nix` and never touch your sources.json - remove Removes one pin entry - show Lists the current pin entries - update Updates all or the given pins to the latest version - upgrade Upgrade the sources.json and default.nix to the latest format version. This may occasionally - break Nix evaluation! +Usage: npins [OPTIONS] + +Commands: + init Intializes the npins directory. Running this multiple times will restore/upgrade the `default.nix` and never touch your sources.json + add Adds a new pin entry + show Lists the current pin entries + update Updates all or the given pins to the latest version + upgrade Upgrade the sources.json and default.nix to the latest format version. This may occasionally break Nix evaluation! + remove Removes one pin entry + import-niv Try to import entries from Niv + import-flake Try to import entries from flake.lock + help Print this message or the help of the given subcommand(s) + +Options: + -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + -h, --help Print help + -V, --version Print version ``` ### Initialization @@ -139,20 +131,14 @@ This will create an `npins` folder with a `default.nix` and `sources.json` withi ```console $ npins help init -npins-init 0.2.4 -Intializes the npins directory. Running this multiple times will restore/upgrade the `default.nix` and never touch your -sources.json +Intializes the npins directory. Running this multiple times will restore/upgrade the `default.nix` and never touch your sources.json -USAGE: - npins init [FLAGS] [OPTIONS] +Usage: npins init [OPTIONS] -FLAGS: - --bare Don't add an initial `nixpkgs` entry - -h, --help Prints help information - -OPTIONS: - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] - [default: npins] +Options: + --bare Don't add an initial `nixpkgs` entry + -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + -h, --help Print help ``` ### Migrate from Niv @@ -170,22 +156,17 @@ Note that the import functionality is minimal and only preserves the necessary i ```console $ npins help import-niv -npins-import-niv 0.2.4 Try to import entries from Niv -USAGE: - npins import-niv [OPTIONS] [path] - -FLAGS: - -h, --help Prints help information +Usage: npins import-niv [OPTIONS] [PATH] -OPTIONS: - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] - [default: npins] - -n, --name Only import one entry from Niv +Arguments: + [PATH] [default: nix/sources.json] -ARGS: - [default: nix/sources.json] +Options: + -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + -n, --name Only import one entry from Niv + -h, --help Print help ``` ### Adding dependencies @@ -210,81 +191,70 @@ Depending on what kind of dependency you are adding, different arguments must be ```console $ npins help add -npins-add 0.2.4 Adds a new pin entry -USAGE: - npins add [FLAGS] [OPTIONS] - -FLAGS: - -n, --dry-run Don't actually apply the changes - -h, --help Prints help information - -OPTIONS: - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] - [default: npins] - --name Add the pin with a custom name. If a pin with that name already exists, it willl be - overwritten - -SUBCOMMANDS: - channel Track a Nix channel - forgejo Track a Forgejo repository - git Track a git repository - github Track a GitHub repository - gitlab Track a GitLab repository - help Prints this message or the help of the given subcommand(s) - pypi Track a package on PyPi +Usage: npins add [OPTIONS] + +Commands: + channel Track a Nix channel + github Track a GitHub repository + forgejo Track a Forgejo repository + gitlab Track a GitLab repository + git Track a git repository + pypi Track a package on PyPi + help Print this message or the help of the given subcommand(s) + +Options: + -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + --name Add the pin with a custom name. If a pin with that name already exists, it willl be overwritten + -n, --dry-run Don't actually apply the changes + -h, --help Print help ``` There are several options for tracking git branches, releases and tags: ```console $ npins help add git -npins-add-git 0.2.4 Track a git repository -USAGE: - npins add git [FLAGS] [OPTIONS] - -FLAGS: - -h, --help Prints help information - --pre-releases Also track pre-releases. Conflicts with the --branch option - --submodules Also fetch submodules - -OPTIONS: - --at Use a specific commit/release instead of the latest. This may be a tag - name, or a git revision when --branch is set - -b, --branch Track a branch instead of a release - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: - NPINS_DIRECTORY=] [default: npins] - --release-prefix Optional prefix required for each release name / tag. For example, setting - this to "release/" will only consider those that start with that string - --upper-bound Bound the version resolution. For example, setting this to "2" will - restrict updates to 1.X versions. Conflicts with the --branch option - -ARGS: - The git remote URL. For example +Usage: npins add git [OPTIONS] + +Arguments: + The git remote URL. For example + +Options: + -b, --branch + Track a branch instead of a release + -d, --directory + Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + --at + Use a specific commit/release instead of the latest. This may be a tag name, or a git revision when --branch is set + --pre-releases + Also track pre-releases. Conflicts with the --branch option + --upper-bound + Bound the version resolution. For example, setting this to "2" will restrict updates to 1.X versions. Conflicts with the --branch option + --release-prefix + Optional prefix required for each release name / tag. For example, setting this to "release/" will only consider those that start with that string + --submodules + Also fetch submodules + -h, --help + Print help ``` ### Removing dependencies ```console $ npins help remove -npins-remove 0.2.4 Removes one pin entry -USAGE: - npins remove [OPTIONS] - -FLAGS: - -h, --help Prints help information +Usage: npins remove [OPTIONS] -OPTIONS: - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] - [default: npins] +Arguments: + -ARGS: - +Options: + -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + -h, --help Print help ``` ### Show current entries @@ -293,18 +263,13 @@ This will print the currently pinned dependencies in a human readable format. Th ```console $ npins help show -npins-show 0.2.4 Lists the current pin entries -USAGE: - npins show [OPTIONS] +Usage: npins show [OPTIONS] -FLAGS: - -h, --help Prints help information - -OPTIONS: - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] - [default: npins] +Options: + -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + -h, --help Print help ``` ### Updating dependencies @@ -313,27 +278,26 @@ You can decide to update only selected dependencies, or all at once. For some pi ```console $ npins help update -npins-update 0.2.4 Updates all or the given pins to the latest version -USAGE: - npins update [FLAGS] [OPTIONS] [names]... - -FLAGS: - -n, --dry-run Print the diff, but don't write back the changes - -f, --full Re-fetch hashes even if the version hasn't changed. Useful to make sure the derivations are in the - Nix store - -h, --help Prints help information - -p, --partial Don't update versions, only re-fetch hashes - -OPTIONS: - -d, --directory - Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] - - --max-concurrent-downloads Maximum number of simultaneous downloads [default: 5] - -ARGS: - ... Updates only the specified pins +Usage: npins update [OPTIONS] [NAMES]... + +Arguments: + [NAMES]... Updates only the specified pins + +Options: + -d, --directory + Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + -p, --partial + Don't update versions, only re-fetch hashes + -f, --full + Re-fetch hashes even if the version hasn't changed. Useful to make sure the derivations are in the Nix store + -n, --dry-run + Print the diff, but don't write back the changes + --max-concurrent-downloads + Maximum number of simultaneous downloads [default: 5] + -h, --help + Print help ``` ### Upgrading the pins file @@ -342,18 +306,13 @@ To ensure compatibility across releases, the `npins/sources.json` and `npins/def ```console $ npins help upgrade -npins-upgrade 0.2.4 Upgrade the sources.json and default.nix to the latest format version. This may occasionally break Nix evaluation! -USAGE: - npins upgrade [OPTIONS] - -FLAGS: - -h, --help Prints help information +Usage: npins upgrade [OPTIONS] -OPTIONS: - -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] - [default: npins] +Options: + -d, --directory Base folder for sources.json and the boilerplate default.nix [env: NPINS_DIRECTORY=] [default: npins] + -h, --help Print help ``` ### Using private GitLab repositories diff --git a/src/cli.rs b/src/cli.rs index e59b485..469ef17 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -9,6 +9,7 @@ use std::{ }; use anyhow::{Context, Result}; +use clap::{Parser, Subcommand}; use crossterm::{ cursor, execute, style::{ContentStyle, Print, StyledContent, Stylize}, @@ -19,7 +20,6 @@ use futures::{ stream::{self, StreamExt}, TryStreamExt, }; -use structopt::StructOpt; use url::{ParseError, Url}; @@ -56,7 +56,7 @@ impl UpdateStrategy { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct ChannelAddOpts { name: String, } @@ -73,25 +73,25 @@ impl ChannelAddOpts { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct GenericGitAddOpts { /// Track a branch instead of a release - #[structopt(short, long)] + #[arg(short, long)] pub branch: Option, /// Use a specific commit/release instead of the latest. /// This may be a tag name, or a git revision when --branch is set. - #[structopt(long, value_name = "tag or rev")] + #[arg(long, value_name = "tag or rev")] pub at: Option, /// Also track pre-releases. /// Conflicts with the --branch option. - #[structopt(long, conflicts_with = "branch")] + #[arg(long, conflicts_with = "branch")] pub pre_releases: bool, /// Bound the version resolution. For example, setting this to "2" will /// restrict updates to 1.X versions. Conflicts with the --branch option. - #[structopt( + #[arg( long = "upper-bound", value_name = "version", conflicts_with_all = &["branch", "at"] @@ -101,20 +101,20 @@ pub struct GenericGitAddOpts { /// Optional prefix required for each release name / tag. For /// example, setting this to "release/" will only consider those /// that start with that string. - #[structopt(long = "release-prefix")] + #[arg(long = "release-prefix")] pub release_prefix: Option, /// Also fetch submodules - #[structopt(long)] + #[arg(long)] pub submodules: bool, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct GitHubAddOpts { pub owner: String, pub repository: String, - #[structopt(flatten)] + #[command(flatten)] pub more: GenericGitAddOpts, } @@ -154,13 +154,13 @@ impl GitHubAddOpts { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct ForgejoAddOpts { pub server: String, pub owner: String, pub repository: String, - #[structopt(flatten)] + #[command(flatten)] pub more: GenericGitAddOpts, } impl ForgejoAddOpts { @@ -208,13 +208,13 @@ impl ForgejoAddOpts { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct GitLabAddOpts { /// Usually just `"owner" "repository"`, but GitLab allows arbitrary folder-like structures. - #[structopt(required = true, min_values = 2)] + #[arg(required = true)] // TODO set min number of values to 2 again pub repo_path: Vec, - #[structopt( + #[arg( long, default_value = "https://gitlab.com/", help = "Use a self-hosted GitLab instance instead", @@ -222,14 +222,14 @@ pub struct GitLabAddOpts { )] pub server: url::Url, - #[structopt( + #[arg( long, help = "Use a private token to access the repository.", value_name = "token" )] pub private_token: Option, - #[structopt(flatten)] + #[command(flatten)] pub more: GenericGitAddOpts, } @@ -275,12 +275,12 @@ impl GitLabAddOpts { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct GitAddOpts { /// The git remote URL. For example pub url: String, - #[structopt(flatten)] + #[command(flatten)] pub more: GenericGitAddOpts, } @@ -338,18 +338,18 @@ impl GitAddOpts { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct PyPiAddOpts { /// Name of the package at PyPi.org pub name: String, /// Use a specific release instead of the latest. - #[structopt(long, value_name = "version")] + #[arg(long, value_name = "version")] pub at: Option, /// Bound the version resolution. For example, setting this to "2" will /// restrict updates to 1.X versions. Conflicts with the --branch option. - #[structopt(long = "upper-bound", value_name = "version", conflicts_with = "at")] + #[arg(long = "upper-bound", value_name = "version", conflicts_with = "at")] pub version_upper_bound: Option, } @@ -368,38 +368,38 @@ impl PyPiAddOpts { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Subcommand)] pub enum AddCommands { /// Track a Nix channel - #[structopt(name = "channel")] + #[command(name = "channel")] Channel(ChannelAddOpts), /// Track a GitHub repository - #[structopt(name = "github")] + #[command(name = "github")] GitHub(GitHubAddOpts), /// Track a Forgejo repository - #[structopt(name = "forgejo")] + #[command(name = "forgejo")] Forgejo(ForgejoAddOpts), /// Track a GitLab repository - #[structopt(name = "gitlab")] + #[command(name = "gitlab")] GitLab(GitLabAddOpts), /// Track a git repository - #[structopt(name = "git")] + #[command(name = "git")] Git(GitAddOpts), /// Track a package on PyPi - #[structopt(name = "pypi")] + #[command(name = "pypi")] PyPi(PyPiAddOpts), } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct AddOpts { /// Add the pin with a custom name. /// If a pin with that name already exists, it willl be overwritten - #[structopt(long)] + #[arg(long)] pub name: Option, /// Don't actually apply the changes - #[structopt(short = "n", long)] + #[arg(short = 'n', long)] pub dry_run: bool, - #[structopt(subcommand)] + #[command(subcommand)] command: AddCommands, } @@ -428,56 +428,56 @@ impl AddOpts { } } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct RemoveOpts { pub name: String, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct UpdateOpts { /// Updates only the specified pins. pub names: Vec, /// Don't update versions, only re-fetch hashes - #[structopt(short, long, conflicts_with = "full")] + #[arg(short, long, conflicts_with = "full")] pub partial: bool, /// Re-fetch hashes even if the version hasn't changed. /// Useful to make sure the derivations are in the Nix store. - #[structopt(short, long, conflicts_with = "partial")] + #[arg(short, long, conflicts_with = "partial")] pub full: bool, /// Print the diff, but don't write back the changes - #[structopt(short = "n", long, global = true)] + #[arg(short = 'n', long, global = true)] pub dry_run: bool, /// Maximum number of simultaneous downloads #[structopt(default_value = "5", long)] pub max_concurrent_downloads: usize, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct InitOpts { /// Don't add an initial `nixpkgs` entry - #[structopt(long)] + #[arg(long)] pub bare: bool, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct ImportOpts { - #[structopt(default_value = "nix/sources.json", parse(from_os_str))] + #[arg(default_value = "nix/sources.json")] pub path: PathBuf, /// Only import one entry from Niv - #[structopt(short, long)] + #[arg(short, long)] pub name: Option, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct ImportFlakeOpts { - #[structopt(default_value = "flake.lock", parse(from_os_str))] + #[arg(default_value = "flake.lock")] pub path: PathBuf, /// Only import one entry from the flake - #[structopt(short, long)] + #[arg(short, long)] pub name: Option, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Subcommand)] pub enum Command { /// Intializes the npins directory. Running this multiple times will restore/upgrade the /// `default.nix` and never touch your sources.json. @@ -521,27 +521,28 @@ fn print_diff(name: &str, diff: impl AsRef<[diff::DiffEntry]>) { } } -use structopt::clap::AppSettings; - -#[derive(Debug, StructOpt)] -#[structopt( - setting(AppSettings::ArgRequiredElseHelp), - global_setting(AppSettings::VersionlessSubcommands), - global_setting(AppSettings::ColoredHelp), - global_setting(AppSettings::ColorAuto) +#[derive(Debug, Parser)] +#[command( + version, + about, + arg_required_else_help = true, + // Confirm clap defaults + propagate_version = false, + disable_colored_help = false, + color = clap::ColorChoice::Auto )] pub struct Opts { /// Base folder for sources.json and the boilerplate default.nix - #[structopt( + #[arg( global = true, - short = "d", + short = 'd', long = "directory", default_value = "npins", env = "NPINS_DIRECTORY" )] folder: std::path::PathBuf, - #[structopt(subcommand)] + #[command(subcommand)] command: Command, } diff --git a/src/main.rs b/src/main.rs index a523751..e30897c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ use std::path::PathBuf; use anyhow::Result; +use clap::Parser; use diff::{Diff, OptionExt}; use reqwest::IntoUrl; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; -use structopt::StructOpt; pub mod channel; pub mod cli; @@ -283,7 +283,7 @@ async fn main() -> Result<()> { .format_target(false) .init(); - let opts = cli::Opts::from_args(); + let opts = cli::Opts::parse(); opts.run().await?; Ok(()) }