Skip to content

Package-specific sub-commands #13359

@abhillman

Description

@abhillman

Disclaimer

Although many of the details would be the same, this design should almost certainly be refactored to enable Package-specific Binaries more generally (which would include sub-commands).

See the "Notes" section below for more information.

Problem

Sub-commands are, of course, a powerful feature for extending cargo; and the strategy of looking for sub-commands via the developer's path1 makes for an ergonomic and simple architecture.

Yet sub-commands cannot be specified in a package-specific manner and are instead system-wide which means that developers cannot easily specify a specific version of a sub-command.

Proposed Solution

Proposed addition: CLI
We propose the following CLI argument:

cargo install --project-local <cargo-cmd>

Proposed addition: Cargo.toml: [sub-commands]

We also propose the introduction of the following to Cargo.toml, which the above CLI command relies upon:

[sub-commands]
cargo-cmd-xyz = "1.6"
cargo-cmd-rst = "0.2"
cargo-cmd-abc = "0.6"

Each sub-command listed takes the same form of a dependency; for example cargo-cmd-xyz = { path = ... }, cargo-cmd = { git = ... }`.

Proposed addition: Cargo.toml: [sub-commands]: profile and target

Enables cargo install --profile=... --target=... semantics (see https://doc.rust-lang.org/cargo/commands/cargo-install.html).

Proposed addition: Cargo.toml: Additional crate-type

Whereas the above proposed additions are for users of a cargo sub-command, this addition is for cargo sub-command developers:

[[bin]]
name = "cargo-command-xyz"
crate-type = ["cargo-bin"]

It is an error to specify the "cargo-bin" type if name is not suffixed by "cargo-".

Proposed Build Semantics

When a user runs cargo build, all sub-commands are built. Resulting build products are stored in target/debug/sub-commands/. For example:

[sub-commands]
cargo-cmd-xyz = "1.6"
cargo-cmd-rst = { version = "0.2", profile = "dev" }
cargo-cmd-abc = "0.6"

... results in the following build products:

% ls target/debug/sub-commands/
cargo-cmd-rst
% ls target/release/sub-commands/
cargo-cmd-xyz
cargo-cmd-abc

Proposed Build Semantics: Existing System Installs

If a sub-command is installed at the system-level

Proposed Invocation Semantics

Simply, /.../target/debug/sub-commands/ and /.../target/release/sub-commands/ are added to the path cargo uses at runtime.

Notes

Although many of the details would be the same, this design should almost certainly be refactored to enable Package-specific Binaries more generally (which would include sub-commands). The main differences would be:

  • renaming [sub-commands] to [installs]
  • storing binaries in `target/[debug|release]/installs/
  • crate-type = ["cargo-bin"] would be dropped

Upon reflection, most other semantics would remain similar.

Footnotes

  1. i.e. cargo <the-cmd> searches for cargo-the-cmd on the developer's path

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`S-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions