apticrate: search for crates in your apt repositories

TL;DR repo here

About six weeks ago I published a post called Rust without crates.io about how you could skip the central crates.io repository and develop directly against Debian packages. This annoyed quite a lot of people. By my rough reckoning, about one third of people liked it, one third of people hated it, and the rest only read the comments and upvoted whatever sounded good without checking what I actually wrote. Not too shabby for a day on the internet. It’s fine, the beauty of the suggested approach is that I don’t need anyone’s permission.

Anyway it turns out that if you’re used to searching on crates.io, figuring out what packages are available to you on Debian (and at what versions) is not trivial. The package names generally take the form of librust-crate-name-dev and the package version matches the crate version, so it is possible to search for them but it quickly devolves into a bunch of faffing about with apt commands. There’s a nice Rust package overview on the Debian site but this isn’t particularly easy to use either.

You’re left with ambiguity over whether multi-word crate names are separated by a hyphen or an underscore and it takes a second level of lookup to figure out what actual version librust-tokio-dev represents. Then there’s a series of metapackages that represent the dependencies required for different features. For example if you want to use the color feature of structopt then this requires more dependencies—you can install librust-structopt+color-dev, which will pull in the required librust-clap-2+color-dev (provided by librust-clap-2-dev).

To make this all a bit easier I hacked together a tool called… apticrate. If you want to use it, here is the repository. I’m just going to paste a couple of invocations here and you’ll get the idea.

$ apticrate struct
struct-patch 0.4.1              --         librust-struct-patch-dev
struct-patch-derive 0.4.1       --         librust-struct-patch-derive-dev
structmeta 0.2.0                --         librust-structmeta-dev
structmeta-derive 0.2.0         --         librust-structmeta-derive-dev
structopt 0.3.26                installed  librust-structopt-dev
  deps for feat "color"         --         librust-structopt+color-dev
  deps for feat "debug"         --         librust-structopt+debug-dev
  deps for feat "default"       installed  librust-structopt+default-dev
  deps for feat "doc"           --         librust-structopt+doc-dev
  deps for feat "no_cargo"      --         librust-structopt+no-cargo-dev
  deps for feat "suggestions"   --         librust-structopt+suggestions-dev
  deps for feat "wrap_help"     --         librust-structopt+wrap-help-dev
  deps for feat "yaml"          --         librust-structopt+yaml-dev
structopt-derive 0.4.18         installed  librust-structopt-derive-dev
synstructure 0.12.3             installed  librust-synstructure-dev
  deps for feat "proc-macro"    installed  librust-synstructure+proc-macro-dev
synstructure_test_traits 0.1.0  --         librust-synstructure-test-traits-dev
$ apticrate clap
carapace_spec_clap 0.1.12  --         librust-carapace-spec-clap-dev
clap 2.34.0                installed  librust-clap-2-dev
clap 3.2.25                --         librust-clap-3-dev
clap 4.4.6                 --         librust-clap-dev
clap-num 1.0.2             --         librust-clap-num-dev
clap-verbosity-flag 2.0.1  --         librust-clap-verbosity-flag-dev
clap_builder 4.4.6         --         librust-clap-builder-dev
clap_complete 3.1.1        --         librust-clap-complete-3-dev
clap_complete 4.4.3        --         librust-clap-complete-dev
clap_complete_fig 4.3.1    --         librust-clap-complete-fig-dev
clap_derive 3.2.25         --         librust-clap-derive-3-dev
clap_derive 4.4.2          --         librust-clap-derive-dev
clap_lex 0.5.0             --         librust-clap-lex-dev
clap_mangen 0.2.12         --         librust-clap-mangen-dev

So you can either run it directly to get a list of all Rust crate packages on your system or you can pass a filter to search for specific crates and find out what versions are available. In either case it will tell you what the name of the package is that you have to install, and neatly group up the feature metapackages in case you want to install those ones too.

As of today, I finally got around to fixing some bugs and it is now correctly picking up all the Rust crates available in testing (trixie) and stable (bookworm), relying entirely on offline package data that you can query through apt-cache.

$ cargo run | wc -l
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/apticrate`
2423
$ apt-cache search librust-* | grep -vE "^parsec-service" | wc -l
2423
$ cargo run | wc -l
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/apticrate`
1949
$ apt-cache search librust-* | wc -l
1949

Fair warning: the code does not look very good. It is an unfortunate reality that the Debian packages indicate which crates they provide in inconsistent ways, and in some cases not at all so I had to hard-code a short list of them. Probably I should extract some of this apt data and write test cases, but for today it’s working.

On the bright side, however, I have ensured that this apticrate code will build against the rust-all compiler provided by both Debian stable and testing, and I have so far resisted the urge to add any external crates at all (even regex) which means that you don’t need any other dependencies to use this tool.

I am actively using apticrate to work on some things but I have limited hobby time at the moment so it may be some time before I can make a full report on the efficacy of developing against the Debian subset of crates. It will be influenced heavily by what you’re working on. Early indications are that much is available and also much is not. If there was an easy way to “pass through” a specific crates.io crate in addition to the Debian packages then I would add it but supporting this looks messy right now. I think the spirit of the approach is to stick with what I’m given and if I can’t make that work, best to give up and go grovelling back to crates.io. In theory the situation should only get better as more Rust software gets added to Debian and the dependency base grows.