Lockface77
Lockface77

Reputation: 21

How to force a crate to only be available in dev-dependencies

I am writing a crate that contains some mock implementations for my traits. These traits will be used in my tests.

Since this crate is only for testing, I would like to force it to be only included in the dev-dependencies of the Cargo.toml file.

How can I achieve that?

I have tried to look at the manifest file: https://doc.rust-lang.org/cargo/reference/manifest.html but I couldn't find any parameter that I can put in Cargo.toml to specify that this library must only be imported as a dev-dependency.

Upvotes: 1

Views: 278

Answers (3)

Lockface77
Lockface77

Reputation: 21

After some more testing and implementing, I realized that a crate should not only be allowed in dev-dependencies for the following reasons:

  • As @Peter Hall pointed out, someone may use my crate in another crate that is also a test crate. If it is only available in dev-dependencies it wouldn't be exported
  • When I work with workspaces, I want my test crate to be in the dependencies of the workspace (this way I can update it only at one place) and we can't include a dev-dependency in a workspace.

With this said, my original question was to really to "crash everything if not in dev-dependencies" but even if this was possible, it shouldn't be done for the above reasons.

Alternatively the workaround of Chayim Friedman can be used to ensure that we don't include a dev-only dependency by mistake in the real dependencies of the crate.

Upvotes: 0

Chayim Friedman
Chayim Friedman

Reputation: 71430

You can use cargo tree -e=no-dev -i your_crate. This will print your dependency path to this crate, or otherwise:

warning: nothing to print.

To find dependencies that require specific target platforms, try to use option `--target all` first, and then narrow your search scope accordingly.

If this crate is used in dev-dependencies but not in other places, or:

error: package ID specification `your_crate` did not match any packages

If it is not used at all.

You can create a script that will grep for warning: nothing to print and error: package ID specification `your_crate` did not match any packages, and return an error if none are in the output, and run it on your CI or something.

Note however, that the output format of cargo tree is by no way guaranteed, so this can break without warning.

Upvotes: 0

Igor Artamonov
Igor Artamonov

Reputation: 35951

It's impossible to do like you say, but you may do the same in a bit different way. Take a look at Faux idea on how to export test mocks to external crates: https://nrxus.github.io/faux/guide/exporting-mocks.html I think you can do the same with your own mocks as well.

The idea is basically having a feature flag that enables the mocks you created in your crate. Ex. a mocks feature:

#[cfg(feature = "mocks")]
struct Something { ... }

Define it in your crate's Cargo.toml but not enable it by default:

[features]
mocks = []
default = []

And the use your crate from another crate with mocks enabled only in dev:

[dependencies]
my-crate = "1.2.3"

[dev-dependencies]
my-create = { version = "1.2.3", features = "mocks" }

Upvotes: -1

Related Questions