From e920af396cce7496c45c5762cc362f0915de3dfa Mon Sep 17 00:00:00 2001 From: Isaac Oscar Gariano Date: Fri, 29 Aug 2025 18:33:59 +1000 Subject: [PATCH 1/6] Look for dnf5 repos in /etc/dnf/repos.d openSUSE's dnf5 package adds /etc/dnf/repos.d to the default repo directory list. So this makes cnf search that as well. --- src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index fe9cebe..86aaaa9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,9 @@ mod pool; const ZYPPER_REPO_GLOB: &str = "/etc/zypp/repos.d/*.repo"; // Default value of the reposdir configuration directory -const DNF5_REPOS_GLOBS: [&str; 3] = [ +// (Note that /etc/dnf/repos.d is patched in by the openSUSE dnf5 package) +const DNF5_REPOS_GLOBS: [&str; 4] = [ + "/etc/dnf/repos.d/*.repo", "/etc/yum.repos.d/*.repo", "/etc/distro.repos.d/*.repo", "/usr/share/dnf5/repos.d/*.repo", From 2a1fc902488c187b204ce3d4864b116ba0b7fc94 Mon Sep 17 00:00:00 2001 From: Isaac Oscar Gariano Date: Fri, 29 Aug 2025 19:50:13 +1000 Subject: [PATCH 2/6] Check if zypper is installed. This gives an error if it can't detect a supported package manager. --- src/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 86aaaa9..462a6f8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -72,8 +72,11 @@ fn main() { let pm = if Path::exists(Path::new("/usr/bin/dnf5")) { // Use DNF5 if it's installed (this should probably be set via a config file, in case you have both installed but prefer zypper) PackageManager::Dnf5 - } else { + } else if Path::exists(Path::new("/usr/bin/zypper")) { PackageManager::Zypper + } else { + println!("Neither /usr/bin/dnf5 nor /usr/bin/zypper could be found."); + exit(127); }; let repos = match load_repos(pm) { From 7445f29c8c61ef8769cacd882320fb6992f51be8 Mon Sep 17 00:00:00 2001 From: Isaac Oscar Gariano Date: Fri, 29 Aug 2025 20:02:00 +1000 Subject: [PATCH 3/6] Updated documentation examples. This just makes the examples in the documentation match the current output format. --- README.md | 28 +++++++++++++++++----------- cnf.1 | 4 ++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ccafb95..532a0de 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ To query not installed programs: ``` > ```.log > The program 'cmake' can be found in following packages: -> * cmake-full [ path: /usr/bin/cmake, repository: zypp (repo-oss) ] -> * cmake-mini [ path: /usr/bin/cmake, repository: zypp (repo-oss) ] +> * cmake-full [ path: /usr/bin/cmake, repository: repo-oss ] +> * cmake-mini [ path: /usr/bin/cmake, repository: repo-oss ] > > Try installing with: > sudo zypper install @@ -66,8 +66,8 @@ cmake ``` > ```.log > The program 'cmake' can be found in following packages: -> * cmake-full [ path: /usr/bin/cmake, repository: zypp (repo-oss) ] -> * cmake-mini [ path: /usr/bin/cmake, repository: zypp (repo-oss) ] +> * cmake-full [ path: /usr/bin/cmake, repository: repo-oss ] +> * cmake-mini [ path: /usr/bin/cmake, repository: repo-oss ] > > Try installing with: > sudo zypper install @@ -85,13 +85,19 @@ The testing itself is wrapped in [bats](https://github.com/bats-core/bats-core) > ```.log > test.bats > ✓ root: installed /usr/bin/rpm -> ✓ root: installed /usr/sbin/sysctl -> ✓ root: not installed single package -> ✓ root: not installed more packages -> ✓ root: bash handler: not installed more packages -> ✓ nonroot: not installed more packages -> -> 6 tests, 0 failures +> > ✓ root: installed /usr/sbin/sysctl +> ✓ root: not installed xnake +> ✓ root: not installed make +> ✓ root: not installed cmake +> ✓ nonroot: not installed cmake +> ✓ nonroot: bash without handler: not installed cmake +> ✓ nonroot: bash handler: not installed cmake +> ✓ nonroot: zsh without handler: not installed cmake +> ✓ nonroot: zsh handler: not installed cmake +> ✓ nonroot: fish handler: not installed cmake +> ✓ issue26: do not list not installable files +> +> 12 tests, 0 failures > ``` Every test can be executed on a command line. The `root.sh` wrapper mounts the diff --git a/cnf.1 b/cnf.1 index a2808e9..f27f5ab 100644 --- a/cnf.1 +++ b/cnf.1 @@ -16,8 +16,8 @@ packages. Simply typing missing command executes the handler. cmake The program 'cmake' can be found in following packages: - * cmake-full [ path: /usr/bin/cmake, repository: zypp (repo-oss) ] - * cmake-mini [ path: /usr/bin/cmake, repository: zypp (repo-oss) ] + * cmake-full [ path: /usr/bin/cmake, repository: repo-oss ] + * cmake-mini [ path: /usr/bin/cmake, repository: repo-oss ] Try installing with: sudo zypper install From 6e4b36d9c0f7a8b6c65801da9ede12b09dfa90b0 Mon Sep 17 00:00:00 2001 From: Isaac Oscar Gariano Date: Fri, 29 Aug 2025 20:02:00 +1000 Subject: [PATCH 4/6] Updated documentation to mention dnf5 support The man page also instructs you on how to update the repository chache that is queried. --- README.md | 1 + cnf.1 | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 532a0de..31d60fb 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ | **`zsh` integration** | Yes | Yes | | **Disable integration** | Uninstall package | Magic variable | | **Localization** | Yes (UTF-8 only) | Yes | +| **Package Managers Queried** | Dnf5, Zypper | Zypper | ## **Build** diff --git a/cnf.1 b/cnf.1 index f27f5ab..a4855aa 100644 --- a/cnf.1 +++ b/cnf.1 @@ -9,6 +9,9 @@ cnf \- A command not found handler for openSUSE libsolv(3) under the hood. The source of truth of information about repositories, packages and their content. .PP +This works with enabled dnf5 or zypper repostiores: the first one found in /usr/bin will be used. +Use dnf5 \-\-refresh makecache or zypper \-\-force refresh to update the metadata used. +.PP It is typically called through command-not-found mechanism of bash(1) or zsh(1) or fish(1). This is enabled via installing the cnf-bash or cnf-zsh packages. Simply typing missing command executes the handler. From df878e8aeff9731dae2fc7ebe443aa6e5f705007 Mon Sep 17 00:00:00 2001 From: Isaac Oscar Gariano Date: Fri, 29 Aug 2025 21:58:12 +1000 Subject: [PATCH 5/6] Added instructions for .zsh This also modifies the zsh file to use the COMMAND_NOT_FOUND_BIN variable, just like the bash one. --- README.md | 4 ++-- command_not_found.zsh | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 31d60fb..0edab3e 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,10 @@ To query installed programs in `/usr/bin`: > Absolute path to 'vim' is '/usr/bin/vim'. Please check your $PATH variable to see whether it contains the mentioned path > ``` -## **Integrate with `bash`** +## **Integrate with `bash` and `zsh`** ```.sh -source command_not_found_bash +source command_not_found.bash # or command_not_found.zsh export COMMAND_NOT_FOUND_BIN=./target/debug/cnf cmake ``` diff --git a/command_not_found.zsh b/command_not_found.zsh index 5579fdb..0a34b11 100644 --- a/command_not_found.zsh +++ b/command_not_found.zsh @@ -5,10 +5,11 @@ # - one to be generic command_not_found_handler() and to be hooked # - one to be available when command_not_found_handler() is redefined function command_not_found_handler cnf_handler { - if [ -x /usr/bin/cnf ]; then + local cnf_bin=${COMMAND_NOT_FOUND_BIN:-/usr/bin/cnf} + if [ -x $cnf_bin ]; then # take first parameter and remove quotes if there were any so # $ 'foo' # will search for foo - /usr/bin/cnf "${(Q)1}" + $cnf_bin "${(Q)1}" fi } From ab4cd24b351a8d070da4903a928ae6333f84b0a4 Mon Sep 17 00:00:00 2001 From: Isaac Oscar Gariano Date: Fri, 29 Aug 2025 22:52:51 +1000 Subject: [PATCH 6/6] Added fish support. This mentions that cnf support is already included in fish. It also adds a command_not_found.fish script, but you only need to use that if: command-not-found is not in your path, or not the one you want to use fish has detected another command not found handler, and prefers that Note that overriding the command not found behaviour is only avilable since fish version 1.23.1. --- README.md | 27 ++++++++++++++------------- command_not_found.fish | 7 +++++++ 2 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 command_not_found.fish diff --git a/README.md b/README.md index 0edab3e..7b6e200 100644 --- a/README.md +++ b/README.md @@ -6,17 +6,18 @@ ## **Differences** -| | **`cnf`** | **`scout(cnf)`** | -|------------------------------------|-------------------|-------------------------------| -| **Uses** | `libsolv` | `libsolv` | -| **Written in** | Rust | Shell, two packages in Python | -| **Detect enabled/disabled repos?** | Yes | Yes | -| **Tries to refresh repos** | No | Yes | -| **`bash` integration** | Yes | Yes | -| **`zsh` integration** | Yes | Yes | -| **Disable integration** | Uninstall package | Magic variable | -| **Localization** | Yes (UTF-8 only) | Yes | -| **Package Managers Queried** | Dnf5, Zypper | Zypper | +| | **`cnf`** | **`scout(cnf)`** | +|------------------------------------|---------------------------|-------------------------------| +| **Uses** | `libsolv` | `libsolv` | +| **Written in** | Rust | Shell, two packages in Python | +| **Detect enabled/disabled repos?** | Yes | Yes | +| **Tries to refresh repos** | No | Yes | +| **`bash` integration** | Yes | Yes | +| **`zsh` integration** | Yes | Yes | +| **`fish` integration** | Included with fish 1.23.1 | Included with fish 1.23.1 | +| **Disable integration** | Uninstall package | Magic variable | +| **Localization** | Yes (UTF-8 only) | Yes | +| **Package Managers Queried** | Dnf5, Zypper | Zypper | ## **Build** @@ -58,10 +59,10 @@ To query installed programs in `/usr/bin`: > Absolute path to 'vim' is '/usr/bin/vim'. Please check your $PATH variable to see whether it contains the mentioned path > ``` -## **Integrate with `bash` and `zsh`** +## **Integrate with `bash`, `zsh`, and `fish`** ```.sh -source command_not_found.bash # or command_not_found.zsh +source command_not_found.bash # or command_not_found.zsh, or command_not_found.fish export COMMAND_NOT_FOUND_BIN=./target/debug/cnf cmake ``` diff --git a/command_not_found.fish b/command_not_found.fish new file mode 100644 index 0000000..1cbc47c --- /dev/null +++ b/command_not_found.fish @@ -0,0 +1,7 @@ +function fish_command_not_found + if test -z "$COMMAND_NOT_FOUND_BIN" + set -l COMMAND_NOT_FOUND_BIN /usr/bin/cnf + end + # The 'env' is there in case your fish is older than v3.0.0 + env $COMMAND_NOT_FOUND_BIN $argv[1] +end \ No newline at end of file