From 8a2e38c76e3dd712009f35a566226e61083b0aab Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 10 Jan 2025 16:43:57 +0100 Subject: [PATCH 01/51] clarify benchmark comparison --- benchmarks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/README.md b/benchmarks/README.md index dec7445..c3a4b65 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,4 +1,4 @@ -== Rust Rewrite (ae45685) +== Rust Rewrite (v0.2.2 vs v0.1.6) === Show Help From 08c7b402dd5467b0965b4cacc38d149384b4a8af Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 10 Jan 2025 16:48:45 +0100 Subject: [PATCH 02/51] fix adoc syntax in md file --- benchmarks/README.md | 64 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/benchmarks/README.md b/benchmarks/README.md index c3a4b65..cfb066f 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,117 +1,153 @@ -== Rust Rewrite (v0.2.2 vs v0.1.6) +## Rust Rewrite (v0.2.2 vs v0.1.6) -=== Show Help +### Show Help 4.7 times faster +``` Benchmark 1: nps -h Time (mean ± σ): 991.4 µs ± 96.8 µs [User: 263.2 µs, System: 676.8 µs] Range (min … max): 827.3 µs … 1386.3 µs 2361 runs +``` +``` Benchmark 1: ./nps.sh -h Time (mean ± σ): 4.7 ms ± 0.2 ms [User: 2.4 ms, System: 2.4 ms] Range (min … max): 4.3 ms … 5.5 ms 540 runs +``` -=== Refresh Packages +### Refresh Packages -==== Flakes +#### Flakes 1.47 times faster (mainly due to processing JSON output from `nix search`) +``` Benchmark 1: nps -e=true -r Time (mean ± σ): 1.446 s ± 1.058 s [User: 0.992 s, System: 0.413 s] Range (min … max): 1.101 s … 4.456 s 10 runs +``` +``` Benchmark 1: ./nps --experimental=true -r Time (mean ± σ): 2.130 s ± 0.011 s [User: 1.673 s, System: 0.956 s] Range (min … max): 2.115 s … 2.155 s 10 runs +``` -==== Channels +#### Channels 1.07 times slower (noise, bottlenecked through internet I/O) +``` Benchmark 1: nps -e=false -r Time (mean ± σ): 9.752 s ± 0.635 s [User: 7.511 s, System: 1.402 s] Range (min … max): 8.862 s … 10.330 s 10 runs +``` +``` Benchmark 1: ./nps --experimental=false -r Time (mean ± σ): 9.154 s ± 0.087 s [User: 7.620 s, System: 1.503 s] Range (min … max): 9.076 s … 9.383 s 10 runs +``` -=== Short Match +### Short Match -==== Channels +#### Channels 3 times faster +``` Benchmark 1: ./nps --experimental=false neovim-gtk Time (mean ± σ): 17.7 ms ± 0.6 ms [User: 13.2 ms, System: 13.0 ms] Range (min … max): 16.5 ms … 20.0 ms 134 runs +``` +``` Benchmark 1: nps -e=false -i=false neovim-gtk Time (mean ± σ): 5.9 ms ± 0.3 ms [User: 0.8 ms, System: 5.1 ms] Range (min … max): 4.9 ms … 7.3 ms 321 runs +``` -==== Flakes +#### Flakes 4.6 times faster +``` Benchmark 1: ./nps --experimental=true neovim-gtk Time (mean ± σ): 17.0 ms ± 1.3 ms [User: 11.7 ms, System: 13.8 ms] Range (min … max): 15.6 ms … 28.3 ms 98 runs +``` +``` Benchmark 1: nps -e=true -i=false neovim-gtk Time (mean ± σ): 3.7 ms ± 0.3 ms [User: 0.6 ms, System: 3.2 ms] Range (min … max): 2.8 ms … 4.8 ms 443 runs +``` -=== Medium Match +### Medium Match -==== Channels +#### Channels 3.2 times faster +``` Benchmark 1: ./nps --experimental=false neovim Time (mean ± σ): 21.1 ms ± 0.6 ms [User: 14.9 ms, System: 15.5 ms] Range (min … max): 19.7 ms … 23.7 ms 115 runs +``` +``` Benchmark 1: nps -e=false -i=false neovim Time (mean ± σ): 6.5 ms ± 0.4 ms [User: 1.1 ms, System: 5.4 ms] Range (min … max): 5.6 ms … 8.1 ms 292 runs +``` -==== Flakes +#### Flakes 5.4 times faster +``` Benchmark 1: ./nps --experimental=true neovim Time (mean ± σ): 20.4 ms ± 0.6 ms [User: 14.2 ms, System: 15.5 ms] Range (min … max): 19.4 ms … 22.3 ms 122 runs +``` +``` Benchmark 1: nps -e=true -i=false neovim Time (mean ± σ): 3.8 ms ± 0.3 ms [User: 0.6 ms, System: 3.3 ms] Range (min … max): 2.9 ms … 4.8 ms 445 runs +``` -=== Long Match +### Long Match -==== Channels +#### Channels 10.5 times faster +``` Benchmark 1: ./nps --experimental=false e Time (mean ± σ): 917.4 ms ± 10.7 ms [User: 731.6 ms, System: 403.3 ms] Range (min … max): 903.8 ms … 938.4 ms 10 runs +``` +``` Benchmark 1: nps -e=false -i=false e Time (mean ± σ): 87.1 ms ± 0.9 ms [User: 58.3 ms, System: 28.2 ms] Range (min … max): 85.4 ms … 88.9 ms 33 runs +``` -==== Flakes +#### Flakes 12.1 times faster +``` Benchmark 1: ./nps --experimental=true e Time (mean ± σ): 1.182 s ± 0.010 s [User: 0.929 s, System: 0.499 s] Range (min … max): 1.172 s … 1.204 s 10 runs +``` +``` Benchmark 1: nps -e=true -i=false e Time (mean ± σ): 97.7 ms ± 1.1 ms [User: 69.7 ms, System: 27.4 ms] Range (min … max): 96.0 ms … 100.4 ms 29 runs +``` From a827537ad5dec5e290e4e6e04c39320d77da7bfb Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 10 Jan 2025 18:30:26 +0100 Subject: [PATCH 03/51] update demo image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3d5ac3..7aa2280 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Find installable packages at lightning speed and sort the result by relevance, s ... in configurable individual colors, optionally separated by a newline. Have a look: -![Color output of nps neovim](https://i.imgur.com/XpSo8qW.png "nps neovim") +![Color output of nps neovim](https://i.imgur.com/wNnWdxC.png "nps avahi") ## Installation ### Try It Without Installing From 8814f4dc9c2b4e11ad04531362bf3c5aefd1fe5d Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 11 Jan 2025 17:15:12 +0100 Subject: [PATCH 04/51] improve logging --- src/main.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 01cbdac..1e295df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -647,8 +647,7 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box log::info!("Refreshing cache"); let cache_folder = file_path.parent().unwrap(); - log::info!("file_path: {:?}", file_path); - log::info!("cache_folder: {:?}", cache_folder); + log::trace!("file_path: {:?}", file_path); let output = match experimental { true => Command::new("nix") @@ -758,7 +757,7 @@ fn main() -> ExitCode { log::debug!("Running in terminal, clap::ColorChoice set to Auto"); termcolor::ColorChoice::Auto } else { - log::warn!("Not running in terminal, ColorCoice forced to Never"); + log::warn!("Not running in terminal, clap::ColorCoice forced to Never"); termcolor::ColorChoice::Never } } From 8ee76c45f1173e76c464f86a2031c643ecfb6b5c Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 11 Jan 2025 17:58:06 +0100 Subject: [PATCH 05/51] use canonical package path --- flake.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 6017987..43246df 100644 --- a/flake.nix +++ b/flake.nix @@ -16,8 +16,8 @@ naersk' = pkgs.callPackage naersk {}; in rec { - defaultPackage = packages.nps; - packages.nps = naersk'.buildPackage { + defaultPackage = packages.default; + packages.default = naersk'.buildPackage { src = ./.; }; From abf3982265918ac8dc513161fcd5c3b3efb8bf39 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 11 Jan 2025 18:01:19 +0100 Subject: [PATCH 06/51] update installation instructions --- README.md | 111 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 7aa2280..fed538f 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,8 @@ Find installable packages at lightning speed and sort the result by relevance, s ### Try It Without Installing nix run github:OleMussmann/Nix-Package-Search -### "Installing" The Cheater Way -Add `nps = "nix run github:OleMussmann/Nix-Package-Search -- "` to your shell aliases. Don't forget the trailing double-dash. The program might be garbage collected every once in a while and will be automatically downloaded when needed. - -```nix -programs.bash.shellAliases = { # Replace `bash` with your shell name, if necessary. - nps = "nix run github:OleMussmann/Nix-Package-Search -- " -}; -``` - ### Declarative Installation (Recommended) -> :warning: The way of installing third-party flakes is highly dependent on your personal configuration. As far as I know there is no standardized, canonical way to do this. Instead, here is a generic approach via overlays. You will need to adapt it to your config files. +> ⚠️ The way of installing third-party flakes is highly dependent on your personal configuration. As far as I know there is no standardized, canonical way to do this. Instead, here is a generic approach via overlays. You will need to adapt it to your config files. Add `nps` to your inputs: @@ -46,7 +37,7 @@ Add an overlay to your outputs: outputs = { self, nixpkgs, ... }@inputs: let overlays-third-party = final: prev: { - nps = inputs.nps.defaultPackage.${prev.system}; + nps = inputs.nps.packages.${prev.system}.default; }; in { @@ -65,11 +56,22 @@ Finally, add `nps` to your `systemPackages` in `configuration.nix`: ```nix environment.systemPackages = with pkgs; [ git - nps + # Where to find `nps` depends on how you installed it. + # Here we assume your overlay is called `overlays-third-party`. + overlays-third-party.nps ... ]; ``` +### "Installing" The Cheater Way +Add `nps = "nix run github:OleMussmann/Nix-Package-Search -- "` to your shell aliases. Don't forget the trailing double-dash. The program might be garbage collected every once in a while and will be automatically downloaded when needed. + +```nix +programs.bash.shellAliases = { # Replace `bash` with your shell name, if necessary. + nps = "nix run github:OleMussmann/Nix-Package-Search -- " +}; +``` + ### Local Installation Directly installing in your `nix profile` is generally discouraged, since it is not declarative. @@ -83,32 +85,64 @@ nix profile install github:OleMussmann/Nix-Package-Search - Copy or symlink the `target/release/nps` executable to a folder in your `PATH`, or include it in your `PATH`. - Dependencies: `rustc`, `cargo` -## Automate package scanning (optional) -- Set up a cron job or a systemd timer for `nps -r` (or `nps -e -r` for using the nix experimental features) at regular intervals. Make sure to do so with your local user environment. +## Automate Package Scanning (Optional) +Set up a cron job or a systemd timer for `nps -dddd -r` (or `nps -dddd -e -r` for using the nix experimental features a.k.a flakes) at regular intervals. Make sure to do so with your local user environment. ```nix systemd.timers."refresh-nps-cache" = { - wantedBy = [ "timers.target" ]; + wantedBy = [ "timers.target" ]; timerConfig = { - OnCalendar = "weekly"; + OnCalendar = "weekly"; # or however often you'd like Persistent = true; - Unit = "hello-world.service"; + Unit = "refresh-nps-cache.service"; }; }; systemd.services."refresh-nps-cache" = { - script = '' - set -eu - nps -r # or `nps -e -r` if you use flakes - ''; - serviceConfig = { - Type = "simple"; - User = "YOU"; # replace with your username or ${user} - }; + # Make sure `nix` and `nix-env` are findable by systemd.services. + path = ["/run/current-system/sw/"]; + serviceConfig = { + Type = "oneshot"; + User = "REPLACE_ME"; # ⚠️ replace with your "username" or "${user}", if it's defined + }; + script = '' + set -eu + echo "Start refreshing nps cache..." + # ⚠️ note the use of overlay (as described above), adjust if needed + # ⚠️ use nps -dddd -e -r` if you use flakes + ${pkgs.overlays-third-party.nps}/bin/nps -r -dddd + echo "... finished nps cache with exit code $?." + ''; }; ``` +### Testing Automated Package Scanning +Test the service by starting it by hand and checking the logs. + +```bash +sudo systemctl start refresh-nps-cache.service +journalctl -xeu refresh-nps-cache.service +``` + +Test your timer by letting it run, for example, every 5 minutes. Adjust the timers as follows. Check the logs if it ran successfully. + +```diff +-OnCalendar = "weekly"; ++OnBootSec = "5m"; ++OnUnitActiveSec = "5m"; +``` + +```bash +journalctl -xeu refresh-nps-cache.service +``` + +Don't forget to revert your changes afterwards. + ## Usage + +- `nps PACKAGE_NAME` searches the cache file for packages matching the `PACKAGE_NAME` search string. +- The cache is created on the first call. Be patient, it might take a while. This is done under the hood by capturing the output of `nix-env -qaP` (or `nix search nixpkgs ^` for experimental/flake mode). Subsequent queries are much faster. + ```markdown Find SEARCH_TERM in available nix packages and sort results by relevance @@ -191,25 +225,22 @@ Options: Print version ``` -- `nps PACKAGE_NAME` searches the cache file for packages matching the `PACKAGE_NAME` search string, see image above. -- The cache is created on the first call. Be patient, it might take a while. This is done under the hood by calling `nix-env -qaP` (or `nix search nixpkgs ^` for experimental mode) and writing the output to a cache file. Subsequent queries are much faster. - ### Configuration -`nps` can be configured with environment variables. You can set these in your config file. Below are the defaults. You only need to set the ones you want to have changed. +Apart from command line flags, `nps` can be configured with environment variables. You can set these in your config file. Below are the defaults. Uncomment and change the ones you need. ```nix environment.sessionVariables = rec { - NIX_PACKAGE_SEARCH_EXPERIMENTAL = "false"; # Set to "true" for flakes - NIX_PACKAGE_SEARCH_FLIP = "false"; - NIX_PACKAGE_SEARCH_CACHE_FOLDER_ABSOLUTE_PATH = "/home/YOU/.nix-package-search"; # replace "YOU"! - NIX_PACKAGE_SEARCH_COLUMNS = "all"; - NIX_PACKAGE_SEARCH_EXACT_COLOR = "magenta"; - NIX_PACKAGE_SEARCH_DIRECT_COLOR = "blue"; - NIX_PACKAGE_SEARCH_INDIRECT_COLOR = "green"; - NIX_PACKAGE_SEARCH_COLOR_MODE = "auto"; - NIX_PACKAGE_SEARCH_PRINT_SEPARATOR = "true"; - NIX_PACKAGE_SEARCH_IGNORE_CASE = "true"; + #NIX_PACKAGE_SEARCH_EXPERIMENTAL = "false"; # Set to "true" for flakes + #NIX_PACKAGE_SEARCH_FLIP = "false"; + #NIX_PACKAGE_SEARCH_CACHE_FOLDER_ABSOLUTE_PATH = "/home/YOUR_USERNAME/.nix-package-search"; + #NIX_PACKAGE_SEARCH_COLUMNS = "all"; + #NIX_PACKAGE_SEARCH_EXACT_COLOR = "magenta"; + #NIX_PACKAGE_SEARCH_DIRECT_COLOR = "blue"; + #NIX_PACKAGE_SEARCH_INDIRECT_COLOR = "green"; + #NIX_PACKAGE_SEARCH_COLOR_MODE = "auto"; + #NIX_PACKAGE_SEARCH_PRINT_SEPARATOR = "true"; + #NIX_PACKAGE_SEARCH_IGNORE_CASE = "true"; }; ``` @@ -228,7 +259,7 @@ Flip the order of matches? By default most relevant matches appear below, which #### `NIX_PACKAGE_SEARCH_CACHE_FOLDER_ABSOLUTE_PATH` Absolute path of the cache folder -- default: /home/ole/.nix-package-search +- default: /home/YOUR_USERNAME/.nix-package-search - possible values: path #### `NIX_PACKAGE_SEARCH_COLUMNS` From ac5158e23725906b0f079271b804003b8eb4f626 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 11 Jan 2025 18:17:21 +0100 Subject: [PATCH 07/51] log changes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a64762..e6700e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Fixed +- Update documentation +- Improve logging + ## [0.2.2] - 2025-01-10 ### Added From 9ea1b43bcdd2d7d3d1ff971aff228361413089fe Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 11 Jan 2025 18:22:32 +0100 Subject: [PATCH 08/51] unify cargo usage in README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fed538f..2e7379c 100644 --- a/README.md +++ b/README.md @@ -318,7 +318,7 @@ These tests are by default disabled. Include them with Use `tarpaulin` to check for code coverage. Make sure to `--include-ignored` tests and include the integration tests with `--follow-exec`. This can take a long time. To generate a HTML report, run the check with -`cargo-tarpaulin --all-features --workspace --timeout 360 --out Html --follow-exec -- --include-ignored` +`cargo tarpaulin --all-features --workspace --timeout 360 --out Html --follow-exec -- --include-ignored` ### Benchmarking First build `nps` in release mode. @@ -338,11 +338,11 @@ Review the hooks in the [hooks](./hooks) folder and use them with Document future changes in the [CHANGELOG.md](./CHANGELOG.md) under "Unreleased". Do a dry-run with: -`cargo-release release [LEVEL|VERSION]` +`cargo release [LEVEL|VERSION]` and review the changes. Possible choices for `LEVEL` are `beta`, `alpha` or `rc` for development (pre-) releases and `major`, `minor`, `patch` or `release` (remove pre-release extension) for production releases. Then execute the release with: -`cargo-release release [LEVEL|VERSION] --execute --no-publish` +`cargo release [LEVEL|VERSION] --execute --no-publish` ## Contributing From cdf8d370610852b6d5eab6ec7e3a86da3a3b9b8a Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 11 Jan 2025 18:25:30 +0100 Subject: [PATCH 09/51] update dependencies --- Cargo.lock | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0540ec..71e6091 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,6 +204,16 @@ dependencies = [ "log", ] +[[package]] +name = "erased-serde" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.10" @@ -379,9 +389,12 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "log" -version = "0.4.22" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "3d6ea2a48c204030ee31a7d7fc72c93294c92fe87ecb1789881c9543516e1a0d" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -469,9 +482,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -553,6 +566,15 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.135" @@ -571,6 +593,84 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "sval" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6dc0f9830c49db20e73273ffae9b5240f63c42e515af1da1fceefb69fceafd8" + +[[package]] +name = "sval_buffer" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "429922f7ad43c0ef8fd7309e14d750e38899e32eb7e8da656ea169dd28ee212f" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f16ff5d839396c11a30019b659b0976348f3803db0626f736764c473b50ff4" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01c27a80b6151b0557f9ccbe89c11db571dc5f68113690c1e028d7e974bae94" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0deef63c70da622b2a8069d8600cf4b05396459e665862e7bdb290fd6cf3f155" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_nested" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a39ce5976ae1feb814c35d290cf7cf8cd4f045782fe1548d6bc32e21f6156e9f" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7c6ee3751795a728bc9316a092023529ffea1783499afbc5c66f5fabebb1fa" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a5572d0321b68109a343634e3a5d576bf131b82180c6c442dee06349dfc652a" +dependencies = [ + "serde", + "sval", + "sval_nested", +] + [[package]] name = "syn" version = "2.0.96" @@ -611,6 +711,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +[[package]] +name = "typeid" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" + [[package]] name = "unicode-ident" version = "1.0.14" @@ -623,6 +729,42 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "value-bag" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb773bd36fd59c7ca6e336c94454d9c66386416734817927ac93d81cb3c5b0b" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a916a702cac43a88694c97657d449775667bcd14b70419441d05b7fea4a83a" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "wait-timeout" version = "0.2.0" From 651346198df6fac628ab2c575f4eb2df5bf12740 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 11 Jan 2025 18:29:18 +0100 Subject: [PATCH 10/51] chore: Release nps version 0.2.3-rc.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71e6091..d0d47cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -419,7 +419,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.2" +version = "0.2.3-rc.1" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 8137660..4427c45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.2" +version = "0.2.3-rc.1" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From 7603c5a4dec341eb1cf25cf6c07b9b7ed047a966 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 11:44:24 +0100 Subject: [PATCH 11/51] improve error handling --- src/main.rs | 108 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1e295df..43bef1d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -169,7 +169,11 @@ struct Cli { long, require_equals = true, hide = true, - default_value = home::home_dir().unwrap().join(DEFAULTS.cache_folder).display().to_string(), + default_value = home::home_dir() + .unwrap() // We previously made sure this works. + .join(DEFAULTS.cache_folder) + .display() + .to_string(), value_parser = clap::value_parser!(PathBuf), env = "NIX_PACKAGE_SEARCH_CACHE_FOLDER_ABSOLUTE_PATH" )] @@ -346,7 +350,7 @@ fn option_help_text(help_text: &str) -> String { .replace( "{DEFAULT_CACHE_FOLDER}", &home::home_dir() - .unwrap() + .unwrap() // We previously made sure this works. .join(DEFAULTS.cache_folder) .display() .to_string(), @@ -386,12 +390,16 @@ fn option_help_text(help_text: &str) -> String { /// Find matches from cache file fn get_matches(cli: &Cli, content: &str) -> Result> { - let search_term = cli.search_term.as_ref().unwrap(); + let search_term = cli + .search_term + .as_ref() + .ok_or("Can't get search term as ref")?; // Matcher to find search term in rows let matcher = RegexMatcherBuilder::new() .case_insensitive(cli.ignore_case) - .build(search_term)?; + .build(search_term) + .map_err(|err| format!("Can't build regex: {err}"))?; // Printer collects matching rows in a Vec let mut printer = Standard::new_no_color(vec![]); @@ -399,12 +407,14 @@ fn get_matches(cli: &Cli, content: &str) -> Result> { SearcherBuilder::new() .line_number(false) .build() - .search_slice(&matcher, content.as_bytes(), printer.sink(&matcher))?; + .search_slice(&matcher, content.as_bytes(), printer.sink(&matcher)) + .map_err(|err| format!("Can't build searcher: {err}"))?; // into_inner gives us back the underlying writer we provided to // new_no_color, which is wrapped in a termcolor::NoColor. Thus, a second // into_inner gives us back the actual buffer. - let output = String::from_utf8(printer.into_inner().into_inner())?; + let output = String::from_utf8(printer.into_inner().into_inner()) + .map_err(|err| format!("Can't parse printer string: {err}"))?; Ok(output) } @@ -421,7 +431,10 @@ type MatchVecs = (Vec, Vec, Vec); /// Sort matches into match types and pad the lines to aligned columns fn sort_and_pad_matches(cli: &Cli, raw_matches: String) -> Result> { - let search_term = cli.search_term.as_ref().unwrap(); + let search_term = cli + .search_term + .as_ref() + .ok_or("Can't get search term as ref")?; let mut name_lengths: Vec = vec![]; let mut version_lengths: Vec = vec![]; @@ -509,7 +522,10 @@ fn color_matches( ) -> Result<(Buffer, Buffer, Buffer), Box> { let (mut padded_matches_exact, mut padded_matches_direct, mut padded_matches_indirect) = sorted_padded_matches; - let search_term = cli.search_term.as_ref().unwrap(); + let search_term = cli + .search_term + .as_ref() + .ok_or("Can't get search term as ref")?; // Defining different colors for different match types let exact_color: UserColorSpec = format!("match:fg:{:?}", &cli.exact_color).parse()?; @@ -546,7 +562,8 @@ fn color_matches( // Matcher to color `search_term` let matcher = RegexMatcherBuilder::new() .case_insensitive(cli.ignore_case) - .build(search_term)?; + .build(search_term) + .map_err(|err| format!("Can't build regex: {err}"))?; // Matcher to find _everything_, so lines without matches are still printed. // This can happen if certain columns are missing. @@ -567,7 +584,8 @@ fn color_matches( &matcher_all, padded_matches_exact.join("\n").as_bytes(), exact_printer.sink(&matcher), - )?; + ) + .map_err(|err| format!("Can't build searcher: {err}"))?; SearcherBuilder::new() .line_number(false) .build() @@ -575,7 +593,8 @@ fn color_matches( &matcher_all, padded_matches_direct.join("\n").as_bytes(), direct_printer.sink(&matcher), - )?; + ) + .map_err(|err| format!("Can't build searcher: {err}"))?; SearcherBuilder::new() .line_number(false) .build() @@ -583,7 +602,8 @@ fn color_matches( &matcher_all, padded_matches_indirect.join("\n").as_bytes(), indirect_printer.sink(&matcher), - )?; + ) + .map_err(|err| format!("Can't build searcher: {err}"))?; Ok((exact_buffer, direct_buffer, indirect_buffer)) } @@ -603,11 +623,14 @@ fn print_matches( // Assemble match type string segments let mut out: Vec = vec![ - String::from_utf8(exact_buffer.into_inner())?, + String::from_utf8(exact_buffer.into_inner()) + .map_err(|err| format!("Can't get string from buffer: {err}"))?, sep.clone(), - String::from_utf8(direct_buffer.into_inner())?, + String::from_utf8(direct_buffer.into_inner()) + .map_err(|err| format!("Can't get string from buffer: {err}"))?, sep, - String::from_utf8(indirect_buffer.into_inner())?, + String::from_utf8(indirect_buffer.into_inner()) + .map_err(|err| format!("Can't get string from buffer: {err}"))?, ]; if !cli.flip { @@ -615,15 +638,17 @@ fn print_matches( } // BufferWriter introduces a newline that we need to trim for some reason - writeln!(io::stdout(), "{}", &out.join("").trim())?; + writeln!(io::stdout(), "{}", &out.join("").trim()) + .map_err(|err| format!("Can't write to stdout: {err}"))?; Ok(()) } /// Parse package info from JSON to (NAME VERSION DESCRIPTION) lines -fn parse_json_to_lines(raw_output: &str) -> String { +fn parse_json_to_lines(raw_output: &str) -> Result> { // Load JSON package info into a HashMap - let parsed: HashMap = serde_json::from_str(raw_output).unwrap(); + let parsed: HashMap = + serde_json::from_str(raw_output).map_err(|err| format!("Can't parse JSON: {err}"))?; let mut lines = vec![]; for (name_string, package) in parsed.into_iter() { @@ -632,21 +657,23 @@ fn parse_json_to_lines(raw_output: &str) -> String { // This is different from package.pname, which contains the name // of the executable, which can be different from the package name. let name_vec: Vec<&str> = name_string.splitn(3, '.').collect(); - let name = name_vec.get(2).unwrap(); + let name = name_vec.get(2).ok_or("Can't get package name from JSON.")?; lines.push(format!( "{} {} {}", name, package.version, package.description )); } lines.sort(); - lines.join("\n") + Ok(lines.join("\n")) } /// Fetch new package info and write to cache file fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box> { log::info!("Refreshing cache"); - let cache_folder = file_path.parent().unwrap(); + let cache_folder = file_path + .parent() + .ok_or("Can't get cache folder from file path")?; log::trace!("file_path: {:?}", file_path); let output = match experimental { @@ -655,18 +682,22 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box .arg("nixpkgs") .arg("^") .arg("--json") - .output()?, + .output() + .map_err(|err| format!("`nix search` failed: {err}"))?, false => Command::new("nix-env") .arg("-qaP") .arg("--description") - .output()?, + .output() + .map_err(|err| format!("`nix-env` failed: {err}"))?, }; log::trace!("finished cli command"); let (stdout, stderr) = ( - str::from_utf8(&output.stdout).unwrap(), - str::from_utf8(&output.stderr).unwrap(), + str::from_utf8(&output.stdout) + .map_err(|err| format!("Can't convert stdout to UTF8: {err}"))?, + str::from_utf8(&output.stderr) + .map_err(|err| format!("Can't convert stdout to UTF8: {err}"))?, ); log::trace!("stdout.len(): {}", stdout.len()); @@ -695,26 +726,30 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box } let cache_content = match experimental { - true => parse_json_to_lines(stdout), + true => parse_json_to_lines(stdout).map_err(|err| format!("Can't parse JSON: {err}"))?, false => stdout.to_string(), }; log::trace!("trying to create folder: {:?}", cache_folder); // Create cache folder, if not exists - fs::create_dir_all(cache_folder)?; + fs::create_dir_all(cache_folder).map_err(|err| format!("Can't create folder: {err}"))?; log::trace!("folder created"); log::trace!("cache_folder: {:?}", cache_folder); log::trace!("file_path: {:?}", &file_path); // Atomic Writing: Write first to a tmp file, then persist (move) it to destination - let tempfile = NamedTempFile::new_in(cache_folder)?; + let tempfile = NamedTempFile::new_in(cache_folder) + .map_err(|err| format!("Can't create temp file: {err}"))?; log::trace!("tempfile: {:?}", &tempfile); log::trace!("trying to write tempfile"); - write!(&tempfile, "{}", cache_content)?; + write!(&tempfile, "{}", cache_content) + .map_err(|err| format!("Can't write to temp file: {err}"))?; log::trace!("tempfile written"); - tempfile.persist(file_path)?; + tempfile + .persist(file_path) + .map_err(|err| format!("Can't persist temp file: {err}"))?; log::trace!("tempfile persisted"); let number_of_packages = cache_content.lines().count(); @@ -726,6 +761,14 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box } fn main() -> ExitCode { + // Get home dir errors out of the way, since clap can't propagate errors + // from `derive`. + let home = home::home_dir(); + if home.is_none() || home == Some("".into()) { + Builder::new().filter_level(LevelFilter::Trace).init(); + log::error!("Can't find home dir."); + return ExitCode::FAILURE; + } let cli = Cli::parse(); let log_level = match cli.debug { @@ -1005,7 +1048,7 @@ mod tests { } #[test] - fn test_parse_json_to_lines() { + fn test_parse_json_to_lines() -> Result<(), Box> { init(); let json = "{\ @@ -1023,9 +1066,10 @@ mod tests { myotherpackage fresh i also describe\n\ mypackage old i describe\ "; - let parsed = parse_json_to_lines(json); + let parsed = parse_json_to_lines(json)?; assert_eq!(parsed, desired_output); + Ok(()) } #[test] From 7591665f51aae204ef0b1065273e4500fe87368d Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 12:59:13 +0100 Subject: [PATCH 12/51] fix inconsistent separating lines Fixes #9 --- src/main.rs | 85 +++++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 48 deletions(-) diff --git a/src/main.rs b/src/main.rs index 43bef1d..2a147ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -519,7 +519,7 @@ fn color_matches( cli: &Cli, sorted_padded_matches: MatchVecs, color_choice: termcolor::ColorChoice, -) -> Result<(Buffer, Buffer, Buffer), Box> { +) -> Result<[Buffer; 3], Box> { let (mut padded_matches_exact, mut padded_matches_direct, mut padded_matches_indirect) = sorted_padded_matches; let search_term = cli @@ -605,40 +605,32 @@ fn color_matches( ) .map_err(|err| format!("Can't build searcher: {err}"))?; - Ok((exact_buffer, direct_buffer, indirect_buffer)) + Ok([exact_buffer, direct_buffer, indirect_buffer]) } /// Print matches to screen in correct ordering -fn print_matches( - cli: &Cli, - colored_matches: (Buffer, Buffer, Buffer), -) -> Result<(), Box> { - let (exact_buffer, direct_buffer, indirect_buffer) = colored_matches; - - // Use newlines as separators, if requested - let sep = match cli.separate { - true => "\n".to_string(), - false => "".to_string(), - }; - +fn print_matches(cli: &Cli, colored_matches: [Buffer; 3]) -> Result<(), Box> { // Assemble match type string segments - let mut out: Vec = vec![ - String::from_utf8(exact_buffer.into_inner()) - .map_err(|err| format!("Can't get string from buffer: {err}"))?, - sep.clone(), - String::from_utf8(direct_buffer.into_inner()) - .map_err(|err| format!("Can't get string from buffer: {err}"))?, - sep, - String::from_utf8(indirect_buffer.into_inner()) - .map_err(|err| format!("Can't get string from buffer: {err}"))?, - ]; + let mut out: Vec = vec![]; + for buffer in colored_matches.into_iter() { + let content = String::from_utf8(buffer.into_inner()) + .map_err(|err| format!("Can't get string from buffer: {err}"))?; + if !content.is_empty() { + out.push(content); + } + } if !cli.flip { out.reverse(); } + // Use newlines as separators, if requested + let separator = match cli.separate { + true => "\n".to_string(), + false => "".to_string(), + }; // BufferWriter introduces a newline that we need to trim for some reason - writeln!(io::stdout(), "{}", &out.join("").trim()) + writeln!(io::stdout(), "{}", &out.join(&separator).trim()) .map_err(|err| format!("Can't write to stdout: {err}"))?; Ok(()) @@ -1087,36 +1079,33 @@ mod tests { "mylastpackage_2 v1 is not mypackage either".to_string(), ]; - let expect_exact_color = "\u{1b}[0m\u{1b}[1m\u{1b}[35mmypackage\u{1b}[0m v1 my package description\n"; - let expect_direct_color = "\u{1b}[0m\u{1b}[1m\u{1b}[34mmypackage\u{1b}[0m_extension_2 v1.0.1 my package description\n\ - \u{1b}[0m\u{1b}[1m\u{1b}[34mmypackage\u{1b}[0m_extension v1 my package description\n"; - let expect_indirect_color = "mylastpackage_2 v1 is not \u{1b}[0m\u{1b}[1m\u{1b}[32mmypackage\u{1b}[0m either\n\ - mylastpackage v5.0.0 is not \u{1b}[0m\u{1b}[1m\u{1b}[32mmypackage\u{1b}[0m\n"; - - let expect_exact_no_color = "mypackage v1 my package description\n"; - let expect_direct_no_color = "mypackage_extension_2 v1.0.1 my package description\n\ - mypackage_extension v1 my package description\n"; - let expect_indirect_no_color = "mylastpackage_2 v1 is not mypackage either\n\ - mylastpackage v5.0.0 is not mypackage\n"; + let expect_color = [ + "\u{1b}[0m\u{1b}[1m\u{1b}[35mmypackage\u{1b}[0m v1 my package description\n", + "\u{1b}[0m\u{1b}[1m\u{1b}[34mmypackage\u{1b}[0m_extension_2 v1.0.1 my package description\n\ + \u{1b}[0m\u{1b}[1m\u{1b}[34mmypackage\u{1b}[0m_extension v1 my package description\n", + "mylastpackage_2 v1 is not \u{1b}[0m\u{1b}[1m\u{1b}[32mmypackage\u{1b}[0m either\n\ + mylastpackage v5.0.0 is not \u{1b}[0m\u{1b}[1m\u{1b}[32mmypackage\u{1b}[0m\n", + ]; + let expect_no_color = [ + "mypackage v1 my package description\n", + "mypackage_extension_2 v1.0.1 my package description\n\ + mypackage_extension v1 my package description\n", + "mylastpackage_2 v1 is not mypackage either\n\ + mylastpackage v5.0.0 is not mypackage\n", + ]; let matches = (exact_matches, direct_matches, indirect_matches); - fn b2str(buffer: Buffer) -> String { - String::from_utf8(buffer.into_inner()).unwrap() - } - let colored_matches_color = color_matches(&cli, matches.clone(), termcolor::ColorChoice::Always).unwrap(); - let colored_matches_no_color = color_matches(&cli, matches, termcolor::ColorChoice::Never).unwrap(); - assert_eq!(expect_exact_color, b2str(colored_matches_color.0)); - assert_eq!(expect_direct_color, b2str(colored_matches_color.1)); - assert_eq!(expect_indirect_color, b2str(colored_matches_color.2)); - - assert_eq!(expect_exact_no_color, b2str(colored_matches_no_color.0)); - assert_eq!(expect_direct_no_color, b2str(colored_matches_no_color.1)); - assert_eq!(expect_indirect_no_color, b2str(colored_matches_no_color.2)); + for (expect, output) in std::iter::zip( + [expect_color, expect_no_color].concat(), + [colored_matches_color, colored_matches_no_color].concat(), + ) { + assert_eq!(expect, String::from_utf8(output.into_inner()).unwrap()); + } } } From 32790fde629b0bd0c809f58058fbca3f67ce6799 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 13:05:04 +0100 Subject: [PATCH 13/51] exit with failure exit status for no matches --- src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.rs b/src/main.rs index 2a147ca..1aa61e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -851,6 +851,9 @@ fn main() -> ExitCode { return ExitCode::FAILURE; } }; + if raw_matches.is_empty() { + return ExitCode::FAILURE; + } let sorted_padded_matches = match sort_and_pad_matches(&cli, raw_matches) { Ok(sorted_padded_matches) => sorted_padded_matches, From 34782bdc95d859af763ac7683219915c37b67bb0 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 13:54:08 +0100 Subject: [PATCH 14/51] log changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6700e8..46425ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Update documentation - Improve logging +- Minor bugfixes ## [0.2.2] - 2025-01-10 From 8be199c780faf5c3fafd5fc651ed6b508b602de9 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 16:50:32 +0100 Subject: [PATCH 15/51] fix padding in channel searches --- src/main.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 1aa61e6..d4901c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -719,7 +719,14 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box let cache_content = match experimental { true => parse_json_to_lines(stdout).map_err(|err| format!("Can't parse JSON: {err}"))?, - false => stdout.to_string(), + false => { + // Replace in every line the first two series of whitespaces with single spaces + let re = regex::RegexBuilder::new(r"^([^ ]+) +([^ ]+) +(.*)$") + .multi_line(true) + .build() + .unwrap(); + re.replace_all(stdout, "$1 $2 $3").to_string() + } }; log::trace!("trying to create folder: {:?}", cache_folder); From d61c0309e52733ae010778b1aca55bb059d7fcba Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 17:01:59 +0100 Subject: [PATCH 16/51] install cargo-edit for package management --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index 43246df..ae9d77a 100644 --- a/flake.nix +++ b/flake.nix @@ -24,6 +24,7 @@ devShells.default = with pkgs; mkShell { buildInputs = [ cargo-audit # check dependencies for vulnerabilities + cargo-edit # package management cargo-outdated # check for dependency updates cargo-release # help creating releases cargo-tarpaulin # code coverage From 6a884c295f2301879d27b445860ce525f5af3b3c Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 17:03:46 +0100 Subject: [PATCH 17/51] update packages --- Cargo.lock | 146 +---------------------------------------------------- Cargo.toml | 6 +-- 2 files changed, 5 insertions(+), 147 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0d47cc..bc166e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,16 +204,6 @@ dependencies = [ "log", ] -[[package]] -name = "erased-serde" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" -dependencies = [ - "serde", - "typeid", -] - [[package]] name = "errno" version = "0.3.10" @@ -389,12 +379,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "log" -version = "0.4.24" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6ea2a48c204030ee31a7d7fc72c93294c92fe87ecb1789881c9543516e1a0d" -dependencies = [ - "value-bag", -] +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" @@ -566,15 +553,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_fmt" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" -dependencies = [ - "serde", -] - [[package]] name = "serde_json" version = "1.0.135" @@ -593,84 +571,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "sval" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6dc0f9830c49db20e73273ffae9b5240f63c42e515af1da1fceefb69fceafd8" - -[[package]] -name = "sval_buffer" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "429922f7ad43c0ef8fd7309e14d750e38899e32eb7e8da656ea169dd28ee212f" -dependencies = [ - "sval", - "sval_ref", -] - -[[package]] -name = "sval_dynamic" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f16ff5d839396c11a30019b659b0976348f3803db0626f736764c473b50ff4" -dependencies = [ - "sval", -] - -[[package]] -name = "sval_fmt" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c01c27a80b6151b0557f9ccbe89c11db571dc5f68113690c1e028d7e974bae94" -dependencies = [ - "itoa", - "ryu", - "sval", -] - -[[package]] -name = "sval_json" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0deef63c70da622b2a8069d8600cf4b05396459e665862e7bdb290fd6cf3f155" -dependencies = [ - "itoa", - "ryu", - "sval", -] - -[[package]] -name = "sval_nested" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a39ce5976ae1feb814c35d290cf7cf8cd4f045782fe1548d6bc32e21f6156e9f" -dependencies = [ - "sval", - "sval_buffer", - "sval_ref", -] - -[[package]] -name = "sval_ref" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7c6ee3751795a728bc9316a092023529ffea1783499afbc5c66f5fabebb1fa" -dependencies = [ - "sval", -] - -[[package]] -name = "sval_serde" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5572d0321b68109a343634e3a5d576bf131b82180c6c442dee06349dfc652a" -dependencies = [ - "serde", - "sval", - "sval_nested", -] - [[package]] name = "syn" version = "2.0.96" @@ -711,12 +611,6 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" -[[package]] -name = "typeid" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" - [[package]] name = "unicode-ident" version = "1.0.14" @@ -729,42 +623,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "value-bag" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" -dependencies = [ - "value-bag-serde1", - "value-bag-sval2", -] - -[[package]] -name = "value-bag-serde1" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb773bd36fd59c7ca6e336c94454d9c66386416734817927ac93d81cb3c5b0b" -dependencies = [ - "erased-serde", - "serde", - "serde_fmt", -] - -[[package]] -name = "value-bag-sval2" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a916a702cac43a88694c97657d449775667bcd14b70419441d05b7fea4a83a" -dependencies = [ - "sval", - "sval_buffer", - "sval_dynamic", - "sval_fmt", - "sval_json", - "sval_ref", - "sval_serde", -] - [[package]] name = "wait-timeout" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 4427c45..8a4f334 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,15 +11,15 @@ readme = "README.md" edition = "2021" [dependencies] -clap = { version = "4.5.23", features = ["derive", "env", "string"] } +clap = { version = "4.5.26", features = ["derive", "env", "string"] } env_logger = "0.11.6" grep = "0.3.2" home = "0.5.11" log = "0.4.22" regex = "1.11.1" serde = { version = "1.0.217", features = ["derive"] } -serde_json = "1.0.134" -tempfile = "3.14.0" +serde_json = "1.0.135" +tempfile = "3.15.0" termcolor = "1.4.1" [dev-dependencies] From 015aafda5c2fb26376f9f650911bca8be337eb65 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sun, 12 Jan 2025 17:04:13 +0100 Subject: [PATCH 18/51] chore: Release nps version 0.2.3-rc.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc166e4..c64c8d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -406,7 +406,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.3-rc.1" +version = "0.2.3-rc.2" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 8a4f334..087a085 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.3-rc.1" +version = "0.2.3-rc.2" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From fdbf01a3c07db51a496b7c94043d365667522aab Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Wed, 15 Jan 2025 18:08:39 +0100 Subject: [PATCH 19/51] deprecate installation via defaultPackage --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46425ef..faaf337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Deprecated +- Installation via 'defaultPackage', use 'packages..default' instead + ### Fixed - Update documentation - Improve logging From d0bbfcd0167244a0cd4d386c785fff666f2cd28d Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Wed, 15 Jan 2025 18:18:54 +0100 Subject: [PATCH 20/51] format flake --- flake.nix | 61 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/flake.nix b/flake.nix index ae9d77a..b094eca 100644 --- a/flake.nix +++ b/flake.nix @@ -8,32 +8,41 @@ rust-overlay.url = "github:oxalica/rust-overlay"; }; - outputs = { self, nixpkgs, flake-utils, naersk, rust-overlay, ... }: - flake-utils.lib.eachDefaultSystem (system: - let - overlays = [ (import rust-overlay) ]; - pkgs = import nixpkgs { inherit system overlays; }; - naersk' = pkgs.callPackage naersk {}; - in rec - { - defaultPackage = packages.default; - packages.default = naersk'.buildPackage { + outputs = { + self, + nixpkgs, + flake-utils, + naersk, + rust-overlay, + ... + }: + flake-utils.lib.eachDefaultSystem ( + system: let + overlays = [(import rust-overlay)]; + pkgs = import nixpkgs {inherit system overlays;}; + naersk' = pkgs.callPackage naersk {}; + in rec + { + defaultPackage = packages.default; + packages.default = naersk'.buildPackage { src = ./.; - }; + }; - devShells.default = with pkgs; mkShell { - buildInputs = [ - cargo-audit # check dependencies for vulnerabilities - cargo-edit # package management - cargo-outdated # check for dependency updates - cargo-release # help creating releases - cargo-tarpaulin # code coverage - hyperfine # benchmarking - rust-bin.beta.latest.default - ]; - shellHook = '' - ''; - }; - } - ); + devShells.default = with pkgs; + mkShell { + buildInputs = [ + alejandra # nix formatting + cargo-audit # check dependencies for vulnerabilities + cargo-edit # package management + cargo-outdated # check for dependency updates + cargo-release # help creating releases + cargo-tarpaulin # code coverage + hyperfine # benchmarking + rust-bin.beta.latest.default + ]; + shellHook = '' + ''; + }; + } + ); } From 73fba8a87cf204bef0150d558fc0836a011e42f4 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Wed, 15 Jan 2025 22:25:11 +0100 Subject: [PATCH 21/51] support flake-less systems --- default.nix | 15 +++++++++++++++ flake.lock | 15 +++++++++++++++ flake.nix | 1 + shell.nix | 15 +++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 default.nix create mode 100644 shell.nix diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..f3fe942 --- /dev/null +++ b/default.nix @@ -0,0 +1,15 @@ +( + import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + nodeName = lock.nodes.root.inputs.flake-compat; + in + fetchTarball { + url = lock.nodes.${nodeName}.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz"; + sha256 = lock.nodes.${nodeName}.locked.narHash; + } + ) + {src = ./.;} +) +.defaultNix diff --git a/flake.lock b/flake.lock index 64720c3..30bd574 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,19 @@ { "nodes": { + "flake-compat": { + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "revCount": 57, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" + } + }, "flake-utils": { "locked": { "lastModified": 1667395993, @@ -80,6 +94,7 @@ }, "root": { "inputs": { + "flake-compat": "flake-compat", "flake-utils": "flake-utils", "naersk": "naersk", "nixpkgs": "nixpkgs_2", diff --git a/flake.nix b/flake.nix index b094eca..6c18e49 100644 --- a/flake.nix +++ b/flake.nix @@ -2,6 +2,7 @@ description = "Nix Package Search"; inputs = { + flake-compat.url = "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"; flake-utils.url = "github:numtide/flake-utils"; naersk.url = "github:nix-community/naersk"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..3899c24 --- /dev/null +++ b/shell.nix @@ -0,0 +1,15 @@ +( + import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + nodeName = lock.nodes.root.inputs.flake-compat; + in + fetchTarball { + url = lock.nodes.${nodeName}.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz"; + sha256 = lock.nodes.${nodeName}.locked.narHash; + } + ) + {src = ./.;} +) +.shellNix From 3424374b7b4c3d4c3e07efd9732cb25ef9c2a0c1 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Wed, 15 Jan 2025 22:28:45 +0100 Subject: [PATCH 22/51] update dependencies --- Cargo.lock | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c64c8d4..6caf381 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,11 +52,12 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys", ] @@ -84,9 +85,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bstr" @@ -379,9 +380,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "log" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "memchr" From 443c59310dffe8d5ad45934b83fc6a51fcee0253 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Wed, 15 Jan 2025 22:29:01 +0100 Subject: [PATCH 23/51] chore: Release nps version 0.2.3-rc.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6caf381..960c832 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,7 +407,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.3-rc.2" +version = "0.2.3-rc.3" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 087a085..66df108 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.3-rc.2" +version = "0.2.3-rc.3" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From 52d980399d95e999e6d108f211f1bb854666b639 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 13:14:12 +0100 Subject: [PATCH 24/51] update documentation - general clean-up - remove niche installation methods - move developer's documentation into its own DEVELOPMENT.md file --- DEVELOPMENT.md | 61 ++++++++++++++++++++++ README.md | 137 ++++++++++++++++++------------------------------- 2 files changed, 110 insertions(+), 88 deletions(-) create mode 100644 DEVELOPMENT.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..a8390e4 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,61 @@ +# Development Instructions +## Tests +Most tests run quick, execute them with: + +```bash +cargo test +``` + +Refreshing the cache needs a working internet connection and might take a while. +These tests are by default disabled. Include them with + +```bash +cargo test -- --include-ignored +``` + +Use `tarpaulin` to check for code coverage. Make sure to `--include-ignored` tests and include the integration tests with `--follow-exec`. This can take a long time. To generate a HTML report, run the check with + +```bash +cargo tarpaulin --all-features --workspace --timeout 360 --out Html --follow-exec -- --include-ignored +``` + +## Benchmarking +First build `nps` in release mode. + +```bash +cargo build --release +``` + +Then run benchmarks on the produced executable with: + +```bash +hyperfine './target/release/nps -e neovim' +``` + +## Git Hooks +Review the hooks in the [hooks](./hooks) folder and use them with + +```bash +git config core.hooksPath hooks +``` + +## Release + +Document future changes in the [CHANGELOG.md](./CHANGELOG.md) under "Unreleased". Check if the `pre-push` hooks pass - apart from tags. + +```bash +./hooks/pre-push +``` + +Do a dry-run with + +```bash +cargo release [LEVEL|VERSION] +``` + +and review the changes. Possible choices for `LEVEL` are `beta`, `alpha` or `rc` for development (pre-) releases and `major`, `minor`, `patch` or `release` (removes the pre-release extension) for production releases. Then execute the release. This will run the tests, tag the release and push to GitHub. + +```bash +cargo release [LEVEL|VERSION] --execute --no-publish +``` + diff --git a/README.md b/README.md index 2e7379c..ea1fe95 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ Cache the nix package list, query and sort by relevance. Find installable packages at lightning speed and sort the result by relevance, split by ... -- exact hits, the package _matching your exact string_ -- direct hits, packages that _start with the search string_ -- indirect hits, packages that _contain the search string_ +- indirect hits - packages that _contain the search string_, +- direct hits - packages that _start with the search string_, +- exact hits - the package that _matches your exact string_, ... in configurable individual colors, optionally separated by a newline. Have a look: @@ -15,9 +15,18 @@ Find installable packages at lightning speed and sort the result by relevance, s ## Installation ### Try It Without Installing - nix run github:OleMussmann/Nix-Package-Search +#### Flakes ❄️ +```bash +nix run github:OleMussmann/Nix-Package-Search -- COMMAND_LINE_OPTIONS +``` + +#### No Flakes ☀️ +```bash +nix-shell -p '(builtins.getFlake "github:OleMussmann/Nix-Package-Search").packages.${builtins.currentSystem}.nps' --run "nps COMMAND_LINE_OPTIONS" +``` ### Declarative Installation (Recommended) +#### Flakes ❄️ > ⚠️ The way of installing third-party flakes is highly dependent on your personal configuration. As far as I know there is no standardized, canonical way to do this. Instead, here is a generic approach via overlays. You will need to adapt it to your config files. Add `nps` to your inputs: @@ -36,7 +45,7 @@ Add an overlay to your outputs: ```nix outputs = { self, nixpkgs, ... }@inputs: let - overlays-third-party = final: prev: { + third-party-packages = final: prev: { nps = inputs.nps.packages.${prev.system}.default; }; @@ -44,7 +53,7 @@ in { nixosConfigurations."" = nixpkgs.lib.nixosSystem { system = ""; modules = [ - ({ config, pkgs, ... }: { nixpkgs.overlays = [ overlays-third-party ]; }) + ({ config, pkgs, ... }: { nixpkgs.overlays = [ third-party-packages ]; }) ./configuration.nix ]; }; @@ -55,38 +64,30 @@ Finally, add `nps` to your `systemPackages` in `configuration.nix`: ```nix environment.systemPackages = with pkgs; [ - git - # Where to find `nps` depends on how you installed it. - # Here we assume your overlay is called `overlays-third-party`. - overlays-third-party.nps + other_packages + third-party-packages.nps ... ]; ``` -### "Installing" The Cheater Way -Add `nps = "nix run github:OleMussmann/Nix-Package-Search -- "` to your shell aliases. Don't forget the trailing double-dash. The program might be garbage collected every once in a while and will be automatically downloaded when needed. - -```nix -programs.bash.shellAliases = { # Replace `bash` with your shell name, if necessary. - nps = "nix run github:OleMussmann/Nix-Package-Search -- " -}; -``` - -### Local Installation -Directly installing in your `nix profile` is generally discouraged, since it is not declarative. +#### No Flakes ☀️ +Add `nps` to your `systemPackages` in `configuration.nix`: ```nix -nix profile install github:OleMussmann/Nix-Package-Search +environment.systemPackages = with pkgs; [ + other_packages + (builtins.getFlake "github:OleMussmann/Nix-Package-Search").packages.${builtins.currentSystem}.nps + ... +]; ``` ### By Hand -- Clone this repository. -- Build with `cargo build --release`. +- Clone this repository and `cd Nix-Package-Search` into it. +- Build with `cargo build --release`. Dependencies needed: `gcc`, `cargo` - Copy or symlink the `target/release/nps` executable to a folder in your `PATH`, or include it in your `PATH`. -- Dependencies: `rustc`, `cargo` ## Automate Package Scanning (Optional) -Set up a cron job or a systemd timer for `nps -dddd -r` (or `nps -dddd -e -r` for using the nix experimental features a.k.a flakes) at regular intervals. Make sure to do so with your local user environment. +You can run `nps -r` (or `nps -e -r` for using the nix "experimental" features a.k.a flakes) every once in a while to refresh the package cache, or you can set up a systemd timer at regular intervals. If you automate it, make sure to do so with your local user environment. ```nix systemd.timers."refresh-nps-cache" = { @@ -109,39 +110,39 @@ systemd.services."refresh-nps-cache" = { set -eu echo "Start refreshing nps cache..." # ⚠️ note the use of overlay (as described above), adjust if needed - # ⚠️ use nps -dddd -e -r` if you use flakes - ${pkgs.overlays-third-party.nps}/bin/nps -r -dddd + # ⚠️ use `nps -dddd -e -r` if you use flakes + ${pkgs.third-party-packages.nps}/bin/nps -r -dddd echo "... finished nps cache with exit code $?." ''; }; ``` ### Testing Automated Package Scanning -Test the service by starting it by hand and checking the logs. +- Test the service by starting it by hand and checking the logs. + ```bash + sudo systemctl start refresh-nps-cache.service + journalctl -xeu refresh-nps-cache.service + ``` -```bash -sudo systemctl start refresh-nps-cache.service -journalctl -xeu refresh-nps-cache.service -``` +- Test your timer by letting it run, for example, every 5 minutes. Adjust the timers as follows. -Test your timer by letting it run, for example, every 5 minutes. Adjust the timers as follows. Check the logs if it ran successfully. + ```diff + -OnCalendar = "weekly"; + +OnBootSec = "5m"; + +OnUnitActiveSec = "5m"; + ``` -```diff --OnCalendar = "weekly"; -+OnBootSec = "5m"; -+OnUnitActiveSec = "5m"; -``` - -```bash -journalctl -xeu refresh-nps-cache.service -``` + Check the logs if it ran successfully. + ```bash + journalctl -xeu refresh-nps-cache.service + ``` -Don't forget to revert your changes afterwards. + ⚠️ Don't forget to revert your changes afterwards. ## Usage - `nps PACKAGE_NAME` searches the cache file for packages matching the `PACKAGE_NAME` search string. -- The cache is created on the first call. Be patient, it might take a while. This is done under the hood by capturing the output of `nix-env -qaP` (or `nix search nixpkgs ^` for experimental/flake mode). Subsequent queries are much faster. +- The cache is created on the first call. Be patient, it might take a while. This is done under the hood by capturing the output of `nix-env -qaP` (or `nix search nixpkgs ^` for "experimental"/flake mode). Subsequent queries are much faster. ```markdown Find SEARCH_TERM in available nix packages and sort results by relevance @@ -230,7 +231,7 @@ Options: Apart from command line flags, `nps` can be configured with environment variables. You can set these in your config file. Below are the defaults. Uncomment and change the ones you need. ```nix -environment.sessionVariables = rec { +environment.sessionVariables = { #NIX_PACKAGE_SEARCH_EXPERIMENTAL = "false"; # Set to "true" for flakes #NIX_PACKAGE_SEARCH_FLIP = "false"; #NIX_PACKAGE_SEARCH_CACHE_FOLDER_ABSOLUTE_PATH = "/home/YOUR_USERNAME/.nix-package-search"; @@ -304,48 +305,8 @@ Search ignore capitalization for the search? - default: true - possible values: true, false -## Development - -### Tests -Most tests run quick, execute them with: - -`cargo test` - -Refreshing the cache needs a working internet connection and might take a while. -These tests are by default disabled. Include them with - -`cargo test -- --include-ignored` - -Use `tarpaulin` to check for code coverage. Make sure to `--include-ignored` tests and include the integration tests with `--follow-exec`. This can take a long time. To generate a HTML report, run the check with - -`cargo tarpaulin --all-features --workspace --timeout 360 --out Html --follow-exec -- --include-ignored` - -### Benchmarking -First build `nps` in release mode. - -`cargo build --release` - -Then run benchmarks on the produced executable with: - -`hyperfine './target/release/nps -e neovim'` - -### Git Hooks -Review the hooks in the [hooks](./hooks) folder and use them with - -`git config core.hooksPath hooks` - -### Release - -Document future changes in the [CHANGELOG.md](./CHANGELOG.md) under "Unreleased". Do a dry-run with: - -`cargo release [LEVEL|VERSION]` - -and review the changes. Possible choices for `LEVEL` are `beta`, `alpha` or `rc` for development (pre-) releases and `major`, `minor`, `patch` or `release` (remove pre-release extension) for production releases. Then execute the release with: - -`cargo release [LEVEL|VERSION] --execute --no-publish` - ## Contributing -1. Check existing issues or open a new one to suggest a feature or report a bug -1. Fork the repository and make your changes +1. Check existing issues or open a new one to suggest a feature or report a bug. +1. Fork the repository, check the [DEVELOPMENT.md](DEVELOPMENT.md) and make your changes 1. Open a pull request From c0bdc3d4a4ffd1e27d7350dc49e238aec64acb1b Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 13:53:05 +0100 Subject: [PATCH 25/51] be more explicit in flake.nix --- flake.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 6c18e49..f79aafa 100644 --- a/flake.nix +++ b/flake.nix @@ -11,11 +11,11 @@ outputs = { self, - nixpkgs, + flake-compat, flake-utils, naersk, + nixpkgs, rust-overlay, - ... }: flake-utils.lib.eachDefaultSystem ( system: let From b61a469bde1a61307a4f795bb35dbf73bbe2ab14 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 15:15:25 +0100 Subject: [PATCH 26/51] automate releases --- .github/workflows/release.yml | 37 +++++++++++++++++++++++++++++++++++ CHANGELOG.md | 3 +++ 2 files changed, 40 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6ec8382 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,37 @@ +name: Cargo Build & Test + +on: + pull_request: + branches: + - main + +permissions: + contents: write + +jobs: + release: + name: release nps + runs-on: ubuntu-latest + steps: + - name: Set tag env var + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + - name: Create release text + env: + tag: ${{ github.ref_name }} + run: | + echo "Release version: ${RELEASE_VERSION}" + sed -e "/^## \\[${RELEASE_VERSION:1}\\]/,/^## / ! d" CHANGELOG.md | head -n -2 > RELEASE.md + echo >> RELEASE.md + sed -e "/^\\[${RELEASE_VERSION:1}\\]: / ! d;s/^\\[${RELEASE_VERSION:1}\\]: \(.*\)/**Full Changelog**: \1/" CHANGELOG.md >> RELEASE.md + echo "Release text:" + cat RELEASE.md + - name: Create release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + tag: ${{ github.ref_name }} + run: | + gh release create "$tag" \ + --repo="$GITHUB_REPOSITORY" \ + --title="${GITHUB_REPOSITORY#*/} ${tag#v}" \ + --notes-file="./RELEASE.md" \ + --draft diff --git a/CHANGELOG.md b/CHANGELOG.md index faaf337..6601670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Added +- Automated releases + ### Deprecated - Installation via 'defaultPackage', use 'packages..default' instead From 55660bbfca9d7cebf394fa966b36090e6b93e070 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 15:16:41 +0100 Subject: [PATCH 27/51] chore: Release nps version 0.2.3-rc.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 960c832..b9e2edc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,7 +407,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.3-rc.3" +version = "0.2.3-rc.4" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 66df108..e02438e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.3-rc.3" +version = "0.2.3-rc.4" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From dfe6abe831dbc1850dcd0f73fb4df045297dfc6c Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 15:43:55 +0100 Subject: [PATCH 28/51] fix GitHub Actions release script --- .github/workflows/release.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6ec8382..4863765 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,25 +13,22 @@ jobs: name: release nps runs-on: ubuntu-latest steps: - - name: Set tag env var - run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - name: Create release text - env: - tag: ${{ github.ref_name }} run: | - echo "Release version: ${RELEASE_VERSION}" - sed -e "/^## \\[${RELEASE_VERSION:1}\\]/,/^## / ! d" CHANGELOG.md | head -n -2 > RELEASE.md + echo grep "## \[" CHANGELOG.md | head -n 2 | tail -n 1 | sed "s/^## \\[\(.*\)\\].*/\1/" >> $TAG + echo "Tag: '${TAG}'" + sed -e "/^## \\[${TAG}\\]/,/^## / ! d" CHANGELOG.md | head -n -2 > RELEASE.md echo >> RELEASE.md - sed -e "/^\\[${RELEASE_VERSION:1}\\]: / ! d;s/^\\[${RELEASE_VERSION:1}\\]: \(.*\)/**Full Changelog**: \1/" CHANGELOG.md >> RELEASE.md + sed -e "/^\\[${TAG}\\]: / ! d;s/^\\[${TAG}\\]: \(.*\)/**Full Changelog**: \1/" CHANGELOG.md >> RELEASE.md echo "Release text:" cat RELEASE.md - name: Create release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ github.ref_name }} run: | - gh release create "$tag" \ + echo grep "## \[" CHANGELOG.md | head -n 2 | tail -n 1 | sed "s/^## \\[\(.*\)\\].*/\1/" >> $TAG + gh release create v"$TAG" \ --repo="$GITHUB_REPOSITORY" \ - --title="${GITHUB_REPOSITORY#*/} ${tag#v}" \ + --title="${GITHUB_REPOSITORY#*/} v${TAG#v}" \ --notes-file="./RELEASE.md" \ --draft From a536267e64a1cfce4d5ba615a132815312629454 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 15:44:19 +0100 Subject: [PATCH 29/51] chore: Release nps version 0.2.3-rc.5 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9e2edc..9512fb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,7 +407,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.3-rc.4" +version = "0.2.3-rc.5" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index e02438e..59d4b5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.3-rc.4" +version = "0.2.3-rc.5" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From bbe4d52a041cc28a28dd64206a73c80592b94d3c Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 15:55:36 +0100 Subject: [PATCH 30/51] fix GitHub Actions release script --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4863765..3bb7bce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Cargo Build & Test +name: Release on: pull_request: @@ -15,7 +15,7 @@ jobs: steps: - name: Create release text run: | - echo grep "## \[" CHANGELOG.md | head -n 2 | tail -n 1 | sed "s/^## \\[\(.*\)\\].*/\1/" >> $TAG + TAG=$(grep "## \[" CHANGELOG.md | head -n 2 | tail -n 1 | sed "s/^## \\[\(.*\)\\].*/\1/") echo "Tag: '${TAG}'" sed -e "/^## \\[${TAG}\\]/,/^## / ! d" CHANGELOG.md | head -n -2 > RELEASE.md echo >> RELEASE.md @@ -26,7 +26,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - echo grep "## \[" CHANGELOG.md | head -n 2 | tail -n 1 | sed "s/^## \\[\(.*\)\\].*/\1/" >> $TAG + TAG=$(grep "## \[" CHANGELOG.md | head -n 2 | tail -n 1 | sed "s/^## \\[\(.*\)\\].*/\1/") gh release create v"$TAG" \ --repo="$GITHUB_REPOSITORY" \ --title="${GITHUB_REPOSITORY#*/} v${TAG#v}" \ From 93f23a49604472a42e0e15a9e08b5c6e030ce767 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 15:58:45 +0100 Subject: [PATCH 31/51] chore: Release nps version 0.2.3-rc.6 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9512fb1..883b1dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,7 +407,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.3-rc.5" +version = "0.2.3-rc.6" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 59d4b5c..764e1f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.3-rc.5" +version = "0.2.3-rc.6" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From f7f464a896e6baf9d40adcb5dd9000515d2b30c2 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 16:08:40 +0100 Subject: [PATCH 32/51] fix GitHub Actions release script --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3bb7bce..5d17507 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,6 +13,7 @@ jobs: name: release nps runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - name: Create release text run: | TAG=$(grep "## \[" CHANGELOG.md | head -n 2 | tail -n 1 | sed "s/^## \\[\(.*\)\\].*/\1/") From cf152e0785caf0c3b776a7c8c5d85a534a553247 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 16:31:09 +0100 Subject: [PATCH 33/51] update release instructions --- DEVELOPMENT.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index a8390e4..9c9fce9 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -41,21 +41,26 @@ git config core.hooksPath hooks ## Release -Document future changes in the [CHANGELOG.md](./CHANGELOG.md) under "Unreleased". Check if the `pre-push` hooks pass - apart from tags. +1. Document future changes in the [CHANGELOG.md](./CHANGELOG.md) under "Unreleased". Check if the `pre-push` hooks pass - apart from tags. -```bash -./hooks/pre-push -``` + ```bash + ./hooks/pre-push + ``` -Do a dry-run with +1. Do a dry-run with -```bash -cargo release [LEVEL|VERSION] -``` + ```bash + cargo release [LEVEL|VERSION] + ``` -and review the changes. Possible choices for `LEVEL` are `beta`, `alpha` or `rc` for development (pre-) releases and `major`, `minor`, `patch` or `release` (removes the pre-release extension) for production releases. Then execute the release. This will run the tests, tag the release and push to GitHub. + and review the changes. Possible choices for `LEVEL` are `beta`, `alpha` or `rc` for development (pre-) releases and `major`, `minor`, `patch` or `release` (removes the pre-release extension) for production releases. -```bash -cargo release [LEVEL|VERSION] --execute --no-publish -``` +1. Execute the `cargo release`. This will run the tests, tag the release and push to GitHub. + + ```bash + cargo release [LEVEL|VERSION] --execute --no-publish + ``` + +1. Create a pull request for the `development` branch into `main`. If all pre-checks succeed, conclude the pull request. A release draft will is created from [CHANGELOG.md](CHANGELOG.md). +1. Review the release draft under "Releases" and publish the release. From db000f26883b7687b38f8c4c21d4cbfcfda70f7b Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Fri, 17 Jan 2025 16:33:39 +0100 Subject: [PATCH 34/51] chore: Release nps version 0.2.3 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6601670..e9f06f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +## [0.2.3] - 2025-01-17 + ### Added - Automated releases @@ -109,7 +111,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Versioning now adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) -[Unreleased]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.2...development +[Unreleased]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.3...development +[0.2.3]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.2...v0.2.3 [0.2.2]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.1...v0.2.2 [0.2.1]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.1.6...v0.2.0 diff --git a/Cargo.lock b/Cargo.lock index 883b1dd..d65fd0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,7 +407,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.3-rc.6" +version = "0.2.3" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 764e1f2..6c0d832 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.3-rc.6" +version = "0.2.3" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From 723c62103761461e986c510da427b4a3bca95e63 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 09:27:24 +0100 Subject: [PATCH 35/51] fix CHANGELOG.md formatting --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9f06f4..9534591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Automated releases ### Deprecated -- Installation via 'defaultPackage', use 'packages..default' instead +- Installation via 'defaultPackage', use 'packages.\.default' instead ### Fixed - Update documentation From 42799d6c08de92323363f11d7687c8e8dc17570c Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 09:27:34 +0100 Subject: [PATCH 36/51] fix error message text --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index d4901c5..1335907 100644 --- a/src/main.rs +++ b/src/main.rs @@ -689,7 +689,7 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box str::from_utf8(&output.stdout) .map_err(|err| format!("Can't convert stdout to UTF8: {err}"))?, str::from_utf8(&output.stderr) - .map_err(|err| format!("Can't convert stdout to UTF8: {err}"))?, + .map_err(|err| format!("Can't convert stderr to UTF8: {err}"))?, ); log::trace!("stdout.len(): {}", stdout.len()); From d7af616981120ab2d239383c5d63389c11af83b3 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 10:27:35 +0100 Subject: [PATCH 37/51] enable for fast-worward merge --- .github/workflows/fast-forward.yml | 26 ++++++++++++++++++++++++++ .github/workflows/pull_request.yml | 25 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 .github/workflows/fast-forward.yml create mode 100644 .github/workflows/pull_request.yml diff --git a/.github/workflows/fast-forward.yml b/.github/workflows/fast-forward.yml new file mode 100644 index 0000000..6348d30 --- /dev/null +++ b/.github/workflows/fast-forward.yml @@ -0,0 +1,26 @@ +name: fast-forward +on: + issue_comment: + types: [created, edited] +jobs: + fast-forward: + # Only run if the comment contains the /fast-forward command. + if: ${{ contains(github.event.comment.body, '/fast-forward') + && github.event.issue.pull_request }} + runs-on: ubuntu-latest + + permissions: + contents: write + pull-requests: write + issues: write + + steps: + - name: Fast forwarding + uses: sequoia-pgp/fast-forward@v1 + with: + merge: true + # To reduce the workflow's verbosity, use 'on-error' + # to only post a comment when an error occurs, or 'never' to + # never post a comment. (In all cases the information is + # still available in the step's summary.) + comment: always diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..fd8d798 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,25 @@ +name: pull_request +on: + pull_request: + types: [opened, reopened, synchronize] +jobs: + check-fast-forward: + runs-on: ubuntu-latest + + permissions: + contents: read + # We appear to need write permission for both pull-requests and + # issues in order to post a comment to a pull request. + pull-requests: write + issues: write + + steps: + - name: Checking if fast forwarding is possible + uses: sequoia-pgp/fast-forward@v1 + with: + merge: false + # To reduce the workflow's verbosity, use 'on-error' + # to only post a comment when an error occurs, or 'never' to + # never post a comment. (In all cases the information is + # still available in the step's summary.) + comment: always From 7cccad54e88df90838b113758beeeb198ff9c703 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 10:50:49 +0100 Subject: [PATCH 38/51] update development documentation for merges --- DEVELOPMENT.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 9c9fce9..6abbc90 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -64,3 +64,15 @@ git config core.hooksPath hooks 1. Create a pull request for the `development` branch into `main`. If all pre-checks succeed, conclude the pull request. A release draft will is created from [CHANGELOG.md](CHANGELOG.md). 1. Review the release draft under "Releases" and publish the release. + +## Merge onto `main` + +GitHub.com does not allow for fast-forward merges on the web UI. This means that the tags created on the `development` branch will not point to the main branch after merging. To fix this we need to disable the default merging and create our own way. + +### Setup +1. Abuse "Setting -> General -> Pull Requests" and "Settings -> Rules -> Ruleset (main)" to create conflicting requirements for the `main` branch. This disables merging on the web UI. See: https://github.com/orgs/community/discussions/4618#discussioncomment-11652479 + +1. Instead, use GitHub actions to fast-worward merge. See https://github.com/sequoia-pgp/fast-forward for details. + +### Usage +After all tests have passed, comment `/fast-worward` in the PR discussions. From 493a5272e695a70a8288154e31cad9a22a88e8bc Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 10:51:58 +0100 Subject: [PATCH 39/51] chore: Release nps version 0.2.4-rc.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d65fd0b..7c42224 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,7 +407,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.3" +version = "0.2.4-rc.1" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 6c0d832..8e0763a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.3" +version = "0.2.4-rc.1" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From 2c9ecaeb9578cd397015ba2144ae947555e76d08 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 14:17:18 +0100 Subject: [PATCH 40/51] add -q/--quiet option to suppress all non-debug messages --- README.md | 12 ++++++++++++ src/main.rs | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/README.md b/README.md index ea1fe95..245dfe8 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,12 @@ Options: [default: true] [possible values: true, false] + -q, --quiet[=] + Suppress non-debug messages + + [env: NIX_PACKAGE_SEARCH_QUIET=] + [default: false] + [possible values: true, false] -r, --refresh Refresh package cache and exit @@ -299,6 +305,12 @@ Separate matches with a newline? - default: true - possible values: true, false +#### `NIX_PACKAGE_SEARCH_QUIET` +Suppress non-debug messages? + +- default: false +- possible values: true, false + #### `NIX_PACKAGE_SEARCH_IGNORE_CASE` Search ignore capitalization for the search? diff --git a/src/main.rs b/src/main.rs index 1335907..f6a4b63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ const DEFAULTS: Defaults = Defaults { flip: false, ignore_case: true, print_separator: true, + quiet: false, exact_color: Colors::Magenta, direct_color: Colors::Blue, @@ -140,6 +141,19 @@ struct Cli { )] ignore_case: bool, + /// Suppress non-debug messages + #[arg( + short, + long, + require_equals = true, + default_value_t = DEFAULTS.quiet, + default_missing_value = "true", + num_args = 0..=1, + action = ArgAction::Set, + env = "NIX_PACKAGE_SEARCH_QUIET" + )] + quiet: bool, + /// Refresh package cache and exit #[arg(short, long)] refresh: bool, @@ -277,6 +291,11 @@ NIX_PACKAGE_SEARCH_PRINT_SEPARATOR [default: {DEFAULT_PRINT_SEPARATOR}] [possible values: true, false] +NIX_PACKAGE_SEARCH_QUIET + Suppress non-debug messages? + [default: {DEFAULT_QUIET}] + [possible values: true, false] + NIX_PACKAGE_SEARCH_IGNORE_CASE Search ignore capitalization for the search? [default: {DEFAULT_IGNORE_CASE}] @@ -328,6 +347,7 @@ struct Defaults<'a> { flip: bool, ignore_case: bool, print_separator: bool, + quiet: bool, exact_color: Colors, direct_color: Colors, @@ -374,6 +394,10 @@ fn option_help_text(help_text: &str) -> String { "{DEFAULT_PRINT_SEPARATOR}", &DEFAULTS.print_separator.to_string(), ) + .replace( + "{DEFAULT_QUIET}", + &DEFAULTS.quiet.to_string(), + ) .replace( "{DEFAULT_EXACT_COLOR}", &format!("{:?}", DEFAULTS.exact_color).to_lowercase(), From cccb4ac925fe13d63235c31bc250de9db813d16f Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 15:39:30 +0100 Subject: [PATCH 41/51] improve messages Print helpful warnings if there is a feature mismatch between the system setup and the `nps` usage. --- src/main.rs | 95 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index f6a4b63..9bd9235 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use std::{ fs, io::{self, IsTerminal, Write}, path::PathBuf, - process::{Command, ExitCode}, + process::{Command, ExitCode, Stdio}, str, }; use tempfile::NamedTempFile; @@ -354,6 +354,15 @@ struct Defaults<'a> { indirect_color: Colors, } +/// Print messages if quiet==false +fn message(message_string: &str, quiet: bool) -> Result<(), Box> { + if !quiet { + writeln!(io::stdout(), "{}", message_string) + .map_err(|err| format!("Can't write to stdout: {err}"))?; + } + Ok(()) +} + /// Supply Styles for colored help output. fn styles() -> Styles { Styles::styled() @@ -394,10 +403,7 @@ fn option_help_text(help_text: &str) -> String { "{DEFAULT_PRINT_SEPARATOR}", &DEFAULTS.print_separator.to_string(), ) - .replace( - "{DEFAULT_QUIET}", - &DEFAULTS.quiet.to_string(), - ) + .replace("{DEFAULT_QUIET}", &DEFAULTS.quiet.to_string()) .replace( "{DEFAULT_EXACT_COLOR}", &format!("{:?}", DEFAULTS.exact_color).to_lowercase(), @@ -683,9 +689,69 @@ fn parse_json_to_lines(raw_output: &str) -> Result> { Ok(lines.join("\n")) } +/// Check if requested `nps` features match system features +/// +/// Give helpful warnings if there is a mismatch. +fn check_for_features(experimental: bool, quiet: bool) -> Result<(), Box> { + // Check if flakes are enabled + let probe_for_flakes = Command::new("nix") + .arg("--extra-experimental-features") + .arg("nix-command") + .arg("config") + .arg("show") + .stdout(Stdio::piped()) + .spawn() + .map_err(|err| format!("Can't execute `nix` command: {err}"))?; + let find_experimental_features = Command::new("grep") + .arg("^experimental-features") + .stdin(Stdio::from(probe_for_flakes.stdout.unwrap())) + .stdout(Stdio::piped()) + .spawn() + .map_err(|err| format!("Can't execute `grep` command: {err}"))?; + let find_flakes = Command::new("grep") + .arg("flakes") + .stdin(Stdio::from(find_experimental_features.stdout.unwrap())) + .stdout(Stdio::piped()) + .status() + .map_err(|err| format!("Can't execute `grep` command: {err}"))?; + + let flakes_enabled: bool = find_flakes.success(); + + if flakes_enabled && !experimental { + let flakes_messages = [ + "Feature mismatch:", + "> Your system seems to be based on flakes.", + "> You may want to use `nps -e=true ...` instead to enable querying flake-based packages.", + ]; + for flake_message in flakes_messages { + message(flake_message, quiet)?; + log::warn!("{}", flake_message); + } + } + if !flakes_enabled && experimental { + let channels_messages = [ + "Feature mismatch:", + "> Your system seems to be based on channels.", + "> You may want to use `nps -e=false ...` instead to query packages from channels.", + ]; + for channel_message in channels_messages { + message(channel_message, quiet)?; + log::warn!("{}", channel_message); + } + } + + Ok(()) +} + /// Fetch new package info and write to cache file -fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box> { - log::info!("Refreshing cache"); +fn refresh(experimental: bool, file_path: &PathBuf, quiet: bool) -> Result<(), Box> { + // Print helpful warnings if there is a feature mismatch + // between the system setup and the `nps` usage. + check_for_features(experimental, quiet)?; + + let cache_start_message = "Refreshing cache. This might take a while..."; + log::info!("{}", cache_start_message); + message(cache_start_message, quiet)?; let cache_folder = file_path .parent() @@ -737,8 +803,12 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box // Throw error if cache is too small if stdout.len() < 10_000 { - log::error!("Only {} lines in cache.", stdout.len()); - return Err("Cache seems too small. Run with `-d` flag for more information.".into()); + log::warn!("Cache seems too small:"); + log::warn!("> Query returned only {} lines.", stdout.len()); + log::info!("> Did you set up your channels yet? See: https://nixos.wiki/wiki/Nix_channels"); + log::info!("> You can also set up your system for flakes instead. See: https://nixos.wiki/wiki/Flakes"); + log::info!("> Run with `-dddd` flag for even more information."); + return Err("Cache seems too small. Run with `-dd` flag for more information.".into()); } let cache_content = match experimental { @@ -778,7 +848,10 @@ fn refresh(experimental: bool, file_path: &PathBuf) -> Result<(), Box let number_of_packages = cache_content.lines().count(); let cache_file_path_string = format!("{:?}", file_path); - log::info!("Done. Cached info of {number_of_packages} packages in {cache_file_path_string}"); + let cache_end_message = + format!("Done. Cached info of {number_of_packages} packages in {cache_file_path_string}"); + log::info!("{}", &cache_end_message); + message(&cache_end_message, quiet)?; Ok(()) } @@ -854,7 +927,7 @@ fn main() -> ExitCode { // Refresh cache with new info? if cli.refresh || !cache_file_exists { log::trace!("inside if"); - match refresh(cli.experimental, &file_path) { + match refresh(cli.experimental, &file_path, cli.quiet) { Ok(_) => { if cli.refresh { return ExitCode::SUCCESS; From 5f57e963c5e08cffacf5740c5edf5df273ae6d61 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 15:45:03 +0100 Subject: [PATCH 42/51] log changes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9534591..e2fdf67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Added +- Non-debug messages for better feedback +- Quiet option `-q/--quiet` to suppress non-debug messages + ## [0.2.3] - 2025-01-17 ### Added From 7c363c5b6f2e58e9fa0ea2f5aa4aca2c0c1e2eee Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 15:45:28 +0100 Subject: [PATCH 43/51] chore: Release nps version 0.2.4-rc.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c42224..1080945 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,7 +407,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.4-rc.1" +version = "0.2.4-rc.2" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 8e0763a..9521493 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.4-rc.1" +version = "0.2.4-rc.2" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From 8c1de79661c92198fe99bdd1b40c82031d75efde Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 15:47:45 +0100 Subject: [PATCH 44/51] fix GitHub Actions naming --- .github/workflows/fast-forward.yml | 2 +- .github/workflows/pull_request.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fast-forward.yml b/.github/workflows/fast-forward.yml index 6348d30..94bab0f 100644 --- a/.github/workflows/fast-forward.yml +++ b/.github/workflows/fast-forward.yml @@ -1,4 +1,4 @@ -name: fast-forward +name: Fast-Forward on: issue_comment: types: [created, edited] diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index fd8d798..b0b4bf4 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -1,4 +1,4 @@ -name: pull_request +name: Pull Request on: pull_request: types: [opened, reopened, synchronize] From 2a6bb613bf97ebef7829fae2a31167347284e418 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 16:02:50 +0100 Subject: [PATCH 45/51] fix channel-specific messages --- src/main.rs | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9bd9235..1b079e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -689,11 +689,8 @@ fn parse_json_to_lines(raw_output: &str) -> Result> { Ok(lines.join("\n")) } -/// Check if requested `nps` features match system features -/// -/// Give helpful warnings if there is a mismatch. -fn check_for_features(experimental: bool, quiet: bool) -> Result<(), Box> { - // Check if flakes are enabled +/// Check if flakes are enabled +fn check_flakes_enabled() -> Result> { let probe_for_flakes = Command::new("nix") .arg("--extra-experimental-features") .arg("nix-command") @@ -715,8 +712,17 @@ fn check_for_features(experimental: bool, quiet: bool) -> Result<(), Box Result<(), Box> { if flakes_enabled && !experimental { let flakes_messages = [ "Feature mismatch:", @@ -745,9 +751,10 @@ fn check_for_features(experimental: bool, quiet: bool) -> Result<(), Box Result<(), Box> { + let flakes_enabled = check_flakes_enabled()?; // Print helpful warnings if there is a feature mismatch // between the system setup and the `nps` usage. - check_for_features(experimental, quiet)?; + check_for_features(flakes_enabled, experimental, quiet)?; let cache_start_message = "Refreshing cache. This might take a while..."; log::info!("{}", cache_start_message); @@ -805,8 +812,14 @@ fn refresh(experimental: bool, file_path: &PathBuf, quiet: bool) -> Result<(), B if stdout.len() < 10_000 { log::warn!("Cache seems too small:"); log::warn!("> Query returned only {} lines.", stdout.len()); - log::info!("> Did you set up your channels yet? See: https://nixos.wiki/wiki/Nix_channels"); - log::info!("> You can also set up your system for flakes instead. See: https://nixos.wiki/wiki/Flakes"); + if flakes_enabled { + log::info!( + "> Did you set up your channels yet? See: https://nixos.wiki/wiki/Nix_channels" + ); + log::info!( + "> You can also set up your system for flakes instead. See: https://nixos.wiki/wiki/Flakes" + ); + } log::info!("> Run with `-dddd` flag for even more information."); return Err("Cache seems too small. Run with `-dd` flag for more information.".into()); } From 94dc2424620d9413084f39aa558f76c5142c74ee Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 16:48:36 +0100 Subject: [PATCH 46/51] fix run-once instructions for non-flake systems --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 245dfe8..355267b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ nix run github:OleMussmann/Nix-Package-Search -- COMMAND_LINE_OPTIONS #### No Flakes ☀️ ```bash -nix-shell -p '(builtins.getFlake "github:OleMussmann/Nix-Package-Search").packages.${builtins.currentSystem}.nps' --run "nps COMMAND_LINE_OPTIONS" +nix --extra-experimental-features "nix-command flakes" run github:OleMussmann/Nix-Package-Search -- COMMAND_LINE_OPTIONS ``` ### Declarative Installation (Recommended) From 0e2e9dbe734b6c1c366b02e1227724a7a3250957 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 21:56:49 +0100 Subject: [PATCH 47/51] add tests Closes #12 --- Cargo.lock | 64 +++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 30 +++++++++++ tests/integration.rs | 121 +++++++++++++++++++++++++++++-------------- 4 files changed, 176 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1080945..980e453 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,6 +378,16 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[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" @@ -419,6 +429,7 @@ dependencies = [ "regex", "serde", "serde_json", + "temp-env", "tempfile", "termcolor", ] @@ -438,6 +449,29 @@ 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", +] + [[package]] name = "predicates" version = "3.1.3" @@ -486,6 +520,15 @@ 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", +] + [[package]] name = "regex" version = "1.11.1" @@ -534,6 +577,12 @@ 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" @@ -566,6 +615,12 @@ dependencies = [ "serde", ] +[[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" @@ -583,6 +638,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "temp-env" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96374855068f47402c3121c6eed88d29cb1de8f3ab27090e273e420bdabcf050" +dependencies = [ + "parking_lot", +] + [[package]] name = "tempfile" version = "3.15.0" diff --git a/Cargo.toml b/Cargo.toml index 9521493..064795f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,4 @@ termcolor = "1.4.1" [dev-dependencies] assert_cmd = "2.0.16" predicates = "3.1.3" +temp-env = "0.3.6" diff --git a/src/main.rs b/src/main.rs index 1b079e8..0228b21 100644 --- a/src/main.rs +++ b/src/main.rs @@ -767,6 +767,8 @@ fn refresh(experimental: bool, file_path: &PathBuf, quiet: bool) -> Result<(), B let output = match experimental { true => Command::new("nix") + .arg("--extra-experimental-features") + .arg("nix-command flakes") .arg("search") .arg("nixpkgs") .arg("^") @@ -1228,4 +1230,32 @@ mod tests { assert_eq!(expect, String::from_utf8(output.into_inner()).unwrap()); } } + + #[test] + fn test_check_flakes_enabled() { + init(); + + // Create a temporary directory for a nix.conf file + let tempdir = tempfile::TempDir::new().unwrap(); + let nix_conf_dir = &tempdir.path().join("nix"); + fs::create_dir_all(nix_conf_dir).unwrap(); + + let tempfile = NamedTempFile::new_in(&tempdir).unwrap(); + // Enable experimental features: "nix-command" and "flakes" + write!(&tempfile, "experimental-features = nix-command flakes").unwrap(); + tempfile.persist(nix_conf_dir.join("nix.conf")).unwrap(); + + temp_env::with_var("XDG_CONFIG_HOME", Some(&tempdir.path()), || { + assert!(check_flakes_enabled().unwrap()) + }); + + let tempfile = NamedTempFile::new_in(&tempdir).unwrap(); + // Disable all experimental features + write!(&tempfile, "experimental-features = ").unwrap(); + tempfile.persist(nix_conf_dir.join("nix.conf")).unwrap(); + + temp_env::with_var("XDG_CONFIG_HOME", Some(&tempdir.path()), || { + assert!(!check_flakes_enabled().unwrap()) + }); + } } diff --git a/tests/integration.rs b/tests/integration.rs index f94b5d8..0bf04ed 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,8 +1,8 @@ use assert_cmd::{assert::OutputAssertExt, cargo::CommandCargoExt}; use predicates::prelude::predicate; use regex::Regex; -use std::{fs, process::Command}; -use tempfile::TempDir; +use std::{fs, io::Write, process::Command}; +use tempfile::{NamedTempFile, TempDir}; fn init() { let _ = env_logger::builder().is_test(true).try_init(); @@ -273,60 +273,101 @@ nixpkgs.MyTestPackageName 1.0.0 Test package description } // The following tests are not run by default. Use +// // cargo test -- --ignored -// to execute them. +// +// to execute them. N.B.: By exception, we test for multiple things +// at the same time, since these tests are expensive to run. #[test] #[ignore] /// Testing the creation of new caches. This requires internet connection, so -/// it is disabled by default. +/// it is disabled by default. We also test for correct user messages. fn cache_creation() { init(); + // Create a temporary directory for a cache let temp_dir = TempDir::new().unwrap(); let temp_path = temp_dir.path().to_owned(); - let mut cmd = Command::cargo_bin("nps").unwrap(); - cmd.arg(format!("--cache-folder={}", &temp_path.display())) - .arg("--experimental=false") - .arg("-dddd") - .arg("-r"); - - let output = cmd.assert().success(); - - let cache_content = fs::read_to_string(temp_path.join("nps.cache")).unwrap(); - let re = Regex::new("vim .*popular clone of the VI editor").unwrap(); - assert!(re.is_match(&cache_content)); - - println!( - "STDERR:\n{}", - String::from_utf8_lossy(&output.get_output().stderr) - ); + // Create a temporary directory for a nix.conf file + let tempdir = tempfile::TempDir::new().unwrap(); + let nix_conf_dir = &tempdir.path().join("nix"); + fs::create_dir_all(nix_conf_dir).unwrap(); + + let tempfile = NamedTempFile::new_in(&tempdir).unwrap(); + // Enable experimental features: "nix-command" and "flakes" + write!(&tempfile, "experimental-features = nix-command flakes").unwrap(); + tempfile.persist(nix_conf_dir.join("nix.conf")).unwrap(); + + temp_env::with_var("XDG_CONFIG_HOME", Some(&tempdir.path()), || { + let mut cmd = Command::cargo_bin("nps").unwrap(); + cmd.arg(format!("--cache-folder={}", &temp_path.display())) + .arg("--experimental=false") + .arg("-dddd") + .arg("-r"); + + let output = cmd.assert().success(); + + let cache_content = fs::read_to_string(temp_path.join("nps.cache")).unwrap(); + let re_vim = Regex::new("vim .*popular clone of the VI editor").unwrap(); + assert!(re_vim.is_match(&cache_content)); + + let re_done = Regex::new("Done. Cached info of").unwrap(); + assert!(re_done.is_match(String::from_utf8_lossy(&output.get_output().stderr).as_ref())); + assert!(re_done.is_match(String::from_utf8_lossy(&output.get_output().stdout).as_ref())); + + let re_flakes = Regex::new("Your system seems to be based on flakes").unwrap(); + assert!(re_flakes.is_match(String::from_utf8_lossy(&output.get_output().stderr).as_ref())); + assert!(re_flakes.is_match(String::from_utf8_lossy(&output.get_output().stdout).as_ref())); + }); } #[test] #[ignore] /// Testing the creation of new caches. This requires internet connection, so -/// it is disabled by default. +/// it is disabled by default. We also test for correct user messages and the +/// -q/--quiet flag. fn experimental_cache_creation() { init(); - let temp_dir = TempDir::new().unwrap(); - let temp_path = temp_dir.path().to_owned(); - - let mut cmd = Command::cargo_bin("nps").unwrap(); - cmd.arg(format!("--cache-folder={}", &temp_path.display())) - .arg("--experimental=true") - .arg("-dddd") - .arg("-r"); - - let output = cmd.assert().success(); - - let cache_content = fs::read_to_string(temp_path.join("nps.experimental.cache")).unwrap(); - let re = Regex::new("vim .*popular clone of the VI editor").unwrap(); - assert!(re.is_match(&cache_content)); - - println!( - "STDERR:\n{}", - String::from_utf8_lossy(&output.get_output().stderr) - ); + // Create a temporary directory for a nix.conf file + let tempdir = tempfile::TempDir::new().unwrap(); + let nix_conf_dir = &tempdir.path().join("nix"); + fs::create_dir_all(nix_conf_dir).unwrap(); + + let tempfile = NamedTempFile::new_in(&tempdir).unwrap(); + // Disable all experimental features + write!(&tempfile, "experimental-features = ").unwrap(); + tempfile.persist(nix_conf_dir.join("nix.conf")).unwrap(); + + temp_env::with_var("XDG_CONFIG_HOME", Some(&tempdir.path()), || { + // Create a temporary directory for a cache + let temp_dir = TempDir::new().unwrap(); + let temp_path = temp_dir.path().to_owned(); + + let mut cmd = Command::cargo_bin("nps").unwrap(); + cmd.arg(format!("--cache-folder={}", &temp_path.display())) + .arg("--experimental=true") + .arg("--quiet") + .arg("-dddd") + .arg("-r"); + + let output = cmd.assert().success(); + + let cache_content = fs::read_to_string(temp_path.join("nps.experimental.cache")).unwrap(); + let re = Regex::new("vim .*popular clone of the VI editor").unwrap(); + assert!(re.is_match(&cache_content)); + + let re_done = Regex::new("Done. Cached info of").unwrap(); + assert!(re_done.is_match(String::from_utf8_lossy(&output.get_output().stderr).as_ref())); + // Check that we suppressed messages (--quiet works) + assert!(!re_done.is_match(String::from_utf8_lossy(&output.get_output().stdout).as_ref())); + + let re_channels = Regex::new("Your system seems to be based on channels").unwrap(); + assert!(re_channels.is_match(String::from_utf8_lossy(&output.get_output().stderr).as_ref())); + // Check that we suppressed messages (--quiet works) + assert!( + !re_channels.is_match(String::from_utf8_lossy(&output.get_output().stdout).as_ref()) + ); + }); } From 46a68a1cefff32ff34880f1d50e23cda7c53de54 Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 22:10:11 +0100 Subject: [PATCH 48/51] log changes --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2fdf67..c035204 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Non-debug messages for better feedback - Quiet option `-q/--quiet` to suppress non-debug messages +### Fixed +- Run instructions for channel systems + ## [0.2.3] - 2025-01-17 ### Added From 1f2f61583a73ce8698ffcb318de004b020769fcf Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 22:12:51 +0100 Subject: [PATCH 49/51] chore: Release nps version 0.2.4 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c035204..cc143da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +## [0.2.4] - 2025-01-18 + ### Added - Non-debug messages for better feedback - Quiet option `-q/--quiet` to suppress non-debug messages @@ -118,7 +120,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Versioning now adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) -[Unreleased]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.3...development +[Unreleased]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.4...development +[0.2.4]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.3...v0.2.4 [0.2.3]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.2...v0.2.3 [0.2.2]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.1...v0.2.2 [0.2.1]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.0...v0.2.1 diff --git a/Cargo.lock b/Cargo.lock index 980e453..fe9343b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,7 +417,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.4-rc.2" +version = "0.2.4" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 064795f..98907e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.4-rc.2" +version = "0.2.4" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search" From 44375c338bd4d516bb53415c1d763d5a3fb4f08a Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 22:43:00 +0100 Subject: [PATCH 50/51] use llvm engine for code coverage standard engine segfaults now, seems to be a bug in tarpaulin --- .github/workflows/coverage.yml | 2 +- DEVELOPMENT.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index f37e427..373d661 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -38,7 +38,7 @@ jobs: - name: Generate code coverage run: | - RUST_LOG=TRACE cargo-tarpaulin --verbose --all-features --workspace --timeout 360 --out xml --follow-exec -- --include-ignored + RUST_LOG=TRACE cargo-tarpaulin --engine llvm --verbose --all-features --workspace --timeout 360 --out xml --follow-exec -- --include-ignored - name: Upload coverage to Codecov uses: codecov/codecov-action@v5 diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 6abbc90..6002af6 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -16,7 +16,7 @@ cargo test -- --include-ignored Use `tarpaulin` to check for code coverage. Make sure to `--include-ignored` tests and include the integration tests with `--follow-exec`. This can take a long time. To generate a HTML report, run the check with ```bash -cargo tarpaulin --all-features --workspace --timeout 360 --out Html --follow-exec -- --include-ignored +cargo tarpaulin --engine llvm --all-features --workspace --timeout 360 --out Html --follow-exec -- --include-ignored ``` ## Benchmarking From e7f3c760871bbd86b2519e1530e5ea1c66079d9f Mon Sep 17 00:00:00 2001 From: Ole Mussmann Date: Sat, 18 Jan 2025 22:47:41 +0100 Subject: [PATCH 51/51] chore: Release nps version 0.2.5 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc143da..da918d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +## [0.2.5] - 2025-01-18 + ## [0.2.4] - 2025-01-18 ### Added @@ -120,7 +122,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Versioning now adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) -[Unreleased]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.4...development +[Unreleased]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.5...development +[0.2.5]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.4...v0.2.5 [0.2.4]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.3...v0.2.4 [0.2.3]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.2...v0.2.3 [0.2.2]: https://github.com/OleMussmann/Nix-Package-Search/compare/v0.2.1...v0.2.2 diff --git a/Cargo.lock b/Cargo.lock index fe9343b..d4f377e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,7 +417,7 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "nps" -version = "0.2.4" +version = "0.2.5" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 98907e2..4d5eb9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nps" -version = "0.2.4" +version = "0.2.5" description = "Find SEARCH_TERM in available nix packages and sort results by relevance" authors = ["Ole Mussmann "] homepage = "https://github.com/OleMussmann/Nix-Package-Search"