diff --git a/Cargo.lock b/Cargo.lock index dbcbf7c..17ef4d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,55 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + [[package]] name = "anyhow" version = "1.0.57" @@ -46,7 +95,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -80,6 +129,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -101,42 +156,52 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" dependencies = [ - "atty", - "bitflags", + "clap_builder", "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" +dependencies = [ + "anstream", + "anstyle", + "bitflags", "clap_lex", - "indexmap", - "lazy_static", "strsim", - "termcolor", - "textwrap", + "terminal_size", ] [[package]] name = "clap_derive" -version = "3.1.18" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck 0.4.0", - "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" -dependencies = [ - "os_str_bytes", -] +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "combine" @@ -204,7 +269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ "quote", - "syn", + "syn 1.0.95", ] [[package]] @@ -258,6 +323,27 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "etcetera" version = "0.3.2" @@ -325,6 +411,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "indexmap" version = "1.8.1" @@ -342,6 +434,29 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05a0bd019339e5d968b37855180087b7b9d512c5046fbd244cf8c95687927d6e" +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "itertools" version = "0.10.3" @@ -359,9 +474,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "linked-hash-map" @@ -369,6 +484,12 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "lock_api" version = "0.4.7" @@ -403,7 +524,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -437,12 +558,6 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" -[[package]] -name = "os_str_bytes" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" - [[package]] name = "output_vt100" version = "0.1.3" @@ -472,7 +587,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -545,44 +660,20 @@ dependencies = [ "output_vt100", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -630,6 +721,20 @@ version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +[[package]] +name = "rustix" +version = "0.37.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "rustversion" version = "1.0.6" @@ -638,7 +743,7 @@ checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "sauce" -version = "0.8.0" +version = "0.9.0" dependencies = [ "ansi_term", "anyhow", @@ -685,7 +790,7 @@ checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.95", ] [[package]] @@ -756,7 +861,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.95", ] [[package]] @@ -781,25 +886,31 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.1.3" +name = "syn" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ - "winapi-util", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "termtree" -version = "0.2.4" +name = "terminal_size" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] [[package]] -name = "textwrap" -version = "0.15.0" +name = "termtree" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" [[package]] name = "thiserror" @@ -818,7 +929,7 @@ checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.95", ] [[package]] @@ -867,10 +978,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] -name = "version_check" -version = "0.9.4" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "wait-timeout" @@ -909,15 +1020,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -930,39 +1032,105 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/Cargo.toml b/Cargo.toml index 3b03691..960c8a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sauce" -version = "0.8.0" +version = "0.9.0" authors = ["Dan Cardin "] edition = "2021" description = "A tool for managing directory-specific state." @@ -37,11 +37,15 @@ toml_edit = "0.2.0" once_cell = "1.8.0" [dependencies.clap] -version = "3.1.18" +version = "4.3.3" features = [ - "suggestions", "color", "derive", + "error-context", + "help", + "suggestions", + "usage", + "wrap_help", ] [dependencies.indexmap] diff --git a/doc/options.md b/doc/options.md index 10d04f9..fb9ff0d 100644 --- a/doc/options.md +++ b/doc/options.md @@ -15,7 +15,7 @@ Any key-value pair can be tagged with, you might call “namespaces”. Consider an env var definition ```toml -AWS_PROFILE = {default = "projectname-dev", uat = "projectname-uat", prod = "projectname-prod"} +AWS_PROFILE = {default = "dev", uat = "uat", prod = "prod"} ``` Given `sauce`, you will get the “default” namespace @@ -26,6 +26,15 @@ Given `sauce --as prod`, you will get the “prod” namespace (i.e. AWS_PROFILE=projectname-prod) for this value, as well as all other unnamespaced values. +As of v0.9.0, you can supply multiple `--as` arguments, and they will be used to +choose the first matching value (falling back to "default" if none match). + +Per the above example, `sauce --as foo` would produce "dev" and +`sauce --as uat --as prod` would produce "uat". + +If there was no "default" option specified above, then any "namespaced" keys without +a matching value would be unchanged relative to the current environment. + ## `sauce --glob glob` and `sauce --filter filter` Either `--glob` and/or `--filter` can be applied in order to filter down diff --git a/src/cli/run.rs b/src/cli/run.rs index d4b0fc5..1c9565b 100644 --- a/src/cli/run.rs +++ b/src/cli/run.rs @@ -26,7 +26,7 @@ pub fn run() -> Result<()> { let filter_options = FilterOptions { globs: &parse_match_option(opts.glob.as_deref()), filters: &parse_match_option(opts.filter.as_deref()), - as_: opts.r#as.as_deref(), + as_: opts.r#as, target: opts.target.as_deref(), filter_exclusions: &[], }; @@ -69,7 +69,7 @@ pub fn match_subcommmand( match cmd.kind { ShellKinds::Init => context.init_shell(shell_kind, output), ShellKinds::Exec(command) => { - context.execute_shell_command(shell_kind, &*command.command, output) + context.execute_shell_command(shell_kind, &command.command, output) } }; } diff --git a/src/cli/shape.rs b/src/cli/shape.rs index 97227d5..46a7997 100644 --- a/src/cli/shape.rs +++ b/src/cli/shape.rs @@ -4,65 +4,65 @@ use std::{io::Write, path::PathBuf}; /// Sauce! #[derive(Parser, Debug)] -#[clap(version, author)] +#[command(version, author)] pub struct CliOptions { /// Determines the shell behavior, this flag should always be set automatically /// by the shell hook. Valid options are: zsh, fish, bash - #[clap(long)] + #[arg(long)] pub shell: ShellName, /// Supplied during autoload sequence. Not generally useful to end-users. - #[clap(long)] + #[arg(long)] pub autoload: bool, /// For typical commands such as `sauce` and `sauce clear` this outputs the exact /// shell output that would have executed. For mutating commands like `sauce config` /// and `sauce set`, the change is printed but not saved. - #[clap(long)] + #[arg(long)] pub show: bool, /// Valid options: always, never, auto. Auto (default) will attempt to autodetect /// whether it should output color based on the existence of a tty. - #[clap(long, default_value = "auto")] + #[arg(long, default_value = "auto")] pub color: ColorStrategy, /// Enables verbose output. This causes all stdout to be mirrored to stderr. - #[clap(short, long)] + #[arg(short, long)] pub verbose: bool, /// Disables normal messaging output after a command is executed. - #[clap(short, long)] + #[arg(short, long)] pub quiet: bool, /// The path which should be sauce'd. Defaults to the current directory. - #[clap(short, long)] + #[arg(short, long)] pub path: Option, /// Sets a specific saucefile to load, overriding the default lookup mechanisms and /// cascading behavior - #[clap(long)] + #[arg(long)] pub file: Option, /// Runs the given command "as" the given "as" namespace. - #[clap(short, long)] - pub r#as: Option, + #[arg(short, long)] + pub r#as: Option>, /// Filters the set of values to load, allowing globs. By default filters apply to /// all targets, but also can use the form ":" to be more specific. - #[clap(short, long)] + #[arg(short, long)] pub glob: Option, /// Only use values for a specific target. Essentially this can be thought of /// as a shortcut for `-g ':*`. - #[clap(short, long)] + #[arg(short, long)] pub target: Option, /// Filters the set of values to load, literally. By default filters apply to all /// targets, but also can use the form ":" to be more specific. - #[clap(short, long)] + #[arg(short, long)] pub filter: Option, - #[clap(subcommand)] + #[command(subcommand)] pub subcmd: Option, } @@ -109,10 +109,10 @@ pub enum SubCommand { #[derive(Parser, Debug)] pub struct ConfigCommand { - #[clap(long, short)] + #[arg(long, short)] pub global: bool, - #[clap(parse(try_from_str = crate::cli::utilities::parse_key_val))] + #[arg(value_parser = crate::cli::utilities::parse_key_val::)] pub values: Vec<(String, String)>, } @@ -120,18 +120,18 @@ pub struct ConfigCommand { pub struct MoveCommand { /// The destination location to which a `sauce` invocation would point. /// That is, not the destination saucefile location. - #[clap()] + #[arg()] pub destination: PathBuf, /// Instead of removing the files at the source location, leave the original /// file untouched. - #[clap(short, long)] + #[arg(short, long)] pub copy: bool, } #[derive(Parser, Debug)] pub struct SetCommand { - #[clap(subcommand)] + #[command(subcommand)] pub kind: SetKinds, } @@ -146,7 +146,7 @@ pub enum SetKinds { /// Key-value pairs, delimited by an "=". #[derive(Parser, Debug)] pub struct SetVarKind { - #[clap(parse(try_from_str = crate::cli::utilities::parse_key_val))] + #[arg(value_parser = crate::cli::utilities::parse_key_val::)] pub values: Vec<(String, String)>, } @@ -159,7 +159,7 @@ pub struct KeyValuePair { #[derive(Parser, Debug)] pub struct ShellCommand { - #[clap(subcommand)] + #[command(subcommand)] pub kind: ShellKinds, } @@ -174,13 +174,13 @@ pub enum ShellKinds { #[derive(Parser, Debug)] pub struct ExecCommand { - #[clap()] + #[arg()] pub command: String, } #[derive(Parser, Debug)] pub struct ShowCommand { - #[clap(subcommand)] + #[command(subcommand)] pub kind: ShowKinds, } diff --git a/src/filter.rs b/src/filter.rs index c921550..47f567b 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -5,7 +5,7 @@ pub type MatchOption<'a> = (Option<&'a str>, &'a str); #[derive(Debug, Clone, Default)] pub struct FilterOptions<'a> { pub target: Option<&'a str>, - pub as_: Option<&'a str>, + pub as_: Option>, pub globs: &'a [MatchOption<'a>], @@ -42,8 +42,8 @@ impl<'a> FilterOptions<'a> { } } -fn check_matches<'a, F>( - globs: &[MatchOption<'a>], +fn check_matches( + globs: &[MatchOption], kinds: &[&str], value: &str, matcher: F, diff --git a/src/saucefile.rs b/src/saucefile.rs index ace7eb5..caba852 100644 --- a/src/saucefile.rs +++ b/src/saucefile.rs @@ -2,6 +2,7 @@ use crate::{filter::FilterOptions, output::Output}; use crate::{settings::Settings, toml::unwrap_toml_value}; use indexmap::IndexMap; use itertools::iproduct; +use std::iter::once; use crate::toml::get_document; use std::path::PathBuf; @@ -72,7 +73,15 @@ impl Saucefile { return Vec::new(); } } - let tag = filter_options.as_.unwrap_or("default"); + // let default = ["default".to_string()]; + + let tags: Vec = filter_options + .as_ + .clone() + .unwrap_or(vec![]) + .into_iter() + .chain(once("default".to_string())) + .collect(); iproduct!(self.documents(), sections) .filter_map(|(document, section)| document[section].as_table()) @@ -82,22 +91,25 @@ impl Saucefile { && filter_options.filter_match(sections, key) && filter_options.filter_exclude(sections, key) }) - .map(|(key, item)| { - let var = match item { - Item::Value(value) => match value { - Value::InlineTable(table) => match table.get(tag) { - Some(value) => unwrap_toml_value(value), - _ => "".to_string(), + .filter_map(|(key, item)| { + for tag in tags.iter() { + let var = match item { + Item::Value(value) => match value { + Value::InlineTable(table) => match table.get(tag) { + Some(value) => unwrap_toml_value(value), + _ => continue, + }, + _ => unwrap_toml_value(value), + }, + Item::Table(table) => match &table[tag] { + Item::Value(value) => unwrap_toml_value(value), + _ => continue, }, - _ => unwrap_toml_value(value), - }, - Item::Table(table) => match &table[tag] { - Item::Value(value) => unwrap_toml_value(value), - _ => "".to_string(), - }, - _ => "".to_string(), - }; - (key, var) + _ => continue, + }; + return Some((key, var)); + } + None }) .collect::>() .into_iter() @@ -194,11 +206,7 @@ mod tests { let result = sauce.section(&["foo"], &FilterOptions::default()); assert_eq!( result, - vec![ - ("bar", "1".to_string()), - ("bees", "2".to_string()), - ("boops", "".to_string()), - ] + vec![("bar", "1".to_string()), ("bees", "2".to_string()),] ); } @@ -217,16 +225,44 @@ mod tests { let result = sauce.section( &["foo"], &FilterOptions { - as_: Some("wow"), + as_: Some(vec!["wow".to_string()]), + ..Default::default() + }, + ); + assert_eq!( + result, + vec![("bar", "1".to_string()), ("bees", "2".to_string()),] + ); + } + + #[test] + fn it_selects_multiple_tags() { + let mut sauce = Saucefile::default(); + + let toml = r#" + [foo] + one = 1 + two = {default = 2} + three = {three = 3} + four = {four = 4} + notfive = {ohno = 4} + "#; + sauce.document = toml.parse::().expect("invalid doc"); + + let result = sauce.section( + &["foo"], + &FilterOptions { + as_: Some(vec!["three".to_string(), "four".to_string()]), ..Default::default() }, ); assert_eq!( result, vec![ - ("bar", "1".to_string()), - ("bees", "2".to_string()), - ("boops", "".to_string()), + ("one", "1".to_string()), + ("two", "2".to_string()), + ("three", "3".to_string()), + ("four", "4".to_string()), ] ); } diff --git a/src/shell/utilities.rs b/src/shell/utilities.rs index 3846727..80f201e 100644 --- a/src/shell/utilities.rs +++ b/src/shell/utilities.rs @@ -3,7 +3,7 @@ use std::{collections::VecDeque, str::FromStr}; use crate::shell::Shell; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ShellName { Zsh, Fish, @@ -26,7 +26,7 @@ impl FromStr for ShellName { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ColorStrategy { Always, Never, diff --git a/src/toml.rs b/src/toml.rs index 8432d6f..0cdf87c 100644 --- a/src/toml.rs +++ b/src/toml.rs @@ -16,7 +16,7 @@ pub fn get_document(path: &Path, output: &mut Output) -> Document { } pub fn write_document(file: &Path, document: &Document, output: &mut Output) { - let handle = OpenOptions::new().write(true).open(&file); + let handle = OpenOptions::new().write(true).open(file); write_contents(handle, file, document, output); }