Skip to content

Make cargo --list print description for custom subcommands #10662

Open
@dtolnay

Description

@dtolnay

Problem

Currently cargo --list prints descriptions only for the builtin subcommands. For third-party subcommands like cargo expand it does not print a description.

$ cargo --list
Installed Commands:

    doc                  Build a package's documentation
    expand
    fetch                Fetch dependencies of a package from the network

Proposed Solution

First of all, I don't want cargo --list to run any of the binaries (in order to, for example, run --help on them and parse the output, or some other handshake to cause the binary to print out a description of itself). Arbitrary binaries in the PATH are not necessarily safe to run. An arbitrary binary might completely ignore --help or any other handshake being passed by Cargo, and immediately do unwanted stuff instead, which would be unexpected and undesirable to the person running cargo --list.

Instead, Cargo subcommands should be able to embed a description into their compiled binary, which can then be directly retrieved from the binary by Cargo in a way that does not involve running it.

The way this is exposed to subcommands can be as simple as:

// subcommand's main.rs

cargo_subcommand_metadata::description!("…");

fn main() {
    /* … */
}

The underlying implementation would need to be platform-specific based on the file format used for executables on the platform. On platforms that use ELF executables, I would propose that this uses a Note. On those platforms the macro shown above would expand to:

#[used]
#[link_section = ".note.cargo.subcommand"]
static ELF_NOTE: ElfNote = {}

This note can then be retrieved efficiently from the ELF executable during cargo --list by using the object crate to parse the executable's program header.

From testing on my machine with the cargo-expand crate, cargo build --release produces a 13 MB executable, and retrieving the subcommand description ELF note from it using the object crate takes 0.03 milliseconds, so this should be plenty fast enough for cargo --list.

We do not necessarily need to implement support for a large number of platforms immediately up front. Supporting just ELF would already benefit a large fraction of Cargo users.

Notes

Yes, exactly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-custom-subcommandsArea: custom 3rd party subcommand pluginsC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`Command-listS-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions