Expand description
§Command providers
Command providers can be anything from where a command could be installed. These differ from the environments in that a provider merely tells whether a program can be found there or not, but it doesn’t provide the ability to immediately run the program. On the other hand, an execution environment is something that allows the active execution of commands.
Generally speaking, a provider is any sort of package manager (cargo, pip, apt, dnf,
…).
Execution environments may have zero or more providers available. Containers usually don’t have providers, whereas a host operating system will offer some means of installing packages.
§Implementing a new provider
The following instructions relate to writing a new provider in Rust, with the goal of inclusion
into the application in mind. Of course you don’t have to submit your own provider for
inclusion if you don’t want to. Similarly, you can write a custom provider first and
then open an issue to discuss long-term reimplementation and inclusion in the application.
Here are the mandatory steps you must take to write a new provider:
- Create a new module file in the
providersmodule (here) and name if after the desired provider. - Next, in the
providersroot module:- Include your new module (
pub mod ...) - Import the module into the code (
use ...) - Add your new module to the
Providerstruct - Pass through the
fmt::Displayof your new module forProvider
- Include your new module (
- In your new provider module:
- Import the prelude:
use crate::provider::prelude::*; - Create a new type (struct) for your provider with any internal state you need (or none at all)
- Implement
fmt::Display, and please adhere to the projects naming convention. For example,dnfis usually referred to as DNF. - Implement
IsProviderfor your new provider - (Optional) Write some tests, in case your provider can be tested
- Import the prelude:
- In
src/lib.rs:- Add your provider into the
providersvector
- Add your provider into the
Following you will find a set of guidelines to help you in the process of writing a robust provider. It’s written as a checklist, so feel free to copy it and check the boxes if you want.
- Interacting with the provider:
- Test all the different existent queries you can find (i.e. when your provider returns a successful result for existing applications). Some providers change their output format based on what they find, for example by adding optional fields.
-
Test a non-existent search query (Personally I like ‘asdwasda’ for that purpose) and
return such errors as
ProviderError::NotFound -
When pre-conditions for your provider aren’t fulfilled (i.e. it needs a specific
application/package manager), return a
ProviderError::Requirements - Prefer offline operation and fall back to online operation only when e.g. package manager caches don’t exist. Log an info message in such cases so the user can deduce from the log why searching took longer than expected.
- Prefer parsing results from machine-readable output when possible
- Error handling:
-
Never cause a panic by calling e.g.
unwrap(): Prefer wrapping errors intoanyhow::Errorand returning that asProviderError::ApplicationErrorinstead. Panics ruin the TUI output and don’t add any value for the end-user. - If you want to recover from errors, consider writing a concrete error type for your provider
-
Check if
ProviderErroralready has the error variant you need and reuse that before reimplementing your own version of it
-
Never cause a panic by calling e.g.
- Other things:
-
A
Candidatemust have at least its’packageandactions.executefields populated. Try to populate as many as you can. - Prefer a precise search and returning only few relevant results over generic searches with many results. Built-in providers currently try to stick with less or equal 10 results each.
-
Try to check whether any of the results you find are already installed. Most package
managers will happily report that e.g.
coreutilsprovides thelscommand, butcoreutilsis likely already installed.
-
A
Feel free to look at some of the existing providers as a reference.
Modules§
- apt
- Search packages with APT
- cargo
- Search packages with cargo (Rust)
- custom
- Custom provider
- cwd
- Current Working Directory Provider
- dnf
- Search packages with DNF
- flatpak
- Search packages with Flatpak
- pacman
- Search packages with pacman
- path
- Path provider
Structs§
- Actions
- Action specification for a Candidate.
- Candidate
- Potential candidate for a command.
- Query
- A convenient representation of a search query with its’ results.
Enums§
- Error
- Possible errors arising from provider interactions.
- Provider
- Wrapper type for everything implementing
IsProvider.
Traits§
- IsProvider
- A command provider.
Functions§
- search_
in - Search for
commandinside the givenIsProvider, targeting a specificEnvironment.