Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implicit features out of dependencies #4911

Closed
ignatenkobrain opened this issue Jan 7, 2018 · 10 comments
Closed

Implicit features out of dependencies #4911

ignatenkobrain opened this issue Jan 7, 2018 · 10 comments
Labels
A-documenting-cargo-itself Area: Cargo's documentation

Comments

@ignatenkobrain
Copy link
Contributor

Let's take rand's Cargo.toml, it has

[dependencies]
rustc-serialize = { version = "0.3", optional = true }
serde = { version = "1.0.16", optional = true }
rand = { version = "0.3", optional = true }
sha1 = { version = "0.4", optional = true }
md5 = { version = "0.3", optional = true }

[dev-dependencies]
serde_test = "1.0.19"

[features]
std = []
use_std = ["std"] # deprecated, equivalent to `std`
v1 = ["rand"]
v3 = ["md5"]
v4 = ["rand"]
v5 = ["sha1"]

So strictly speaking it doesn't have serde and rustc-serialize" features, right?

There is tool called stratisd which has

[dependencies.uuid]
version = "0.5"
features = ["serde", "v4"]

in it. Cargo doesn't reject this, but happily passes that feature (serde) and code in uuid handles that just fine.

Does cargo automatically create feature for each dependency (only optional ones?, only non-dev/non-build?), is it expected or should we force people to explicitly specify them? What are the rules here?

This came out of my RPM packaging efforts where we do Provides for each feature crate provides and Requires for everything what is mentioned on the other side. So in this case we get unsatisfied requirement.

@ignatenkobrain ignatenkobrain changed the title Dependencies on implicit features Implicit features out of dependencies Jan 7, 2018
@KodrAus
Copy link

KodrAus commented Jan 7, 2018

Does cargo automatically create feature for each dependency

That's right, cargo will create a feature for each optional dependency in your Cargo.toml. So the set of features available to uuid as per the file above are:

  • rustc-serialize
  • serde
  • rand
  • sha1
  • md5
  • std
  • use_std
  • v1
  • v2
  • v3
  • v4
  • v5

Once a dependency has been added to a Cargo.toml file its name can't be used as a feature anymore, even if that dependency is required. Once a dependency is made optional then its name becomes a feature, and specifying that feature will include the dependency.

@ignatenkobrain
Copy link
Contributor Author

@KodrAus but... why? what's the reason for this? Is it something what it is supposed to do or accidental bug which many developers use?

I can't find any docs on this, tbh.

@KodrAus
Copy link

KodrAus commented Jan 8, 2018

It's definitely intentional, I'm not actually sure where it first came about though. It's a convenient way to toggle optional dependencies when running a build, but unfortunately means you can't just look at the set of features in the manifest to find the ones available to the crate.

You could use a library like cargo_metadata to parse a manifest and collect the set of features and optional dependencies:

extern crate cargo_metadata;

fn main() {
    let metadata = cargo_metadata::metadata(Some("/path/to/Cargo.toml".as_ref())).unwrap();
    let manifest = &metadata.packages[0];

    let features = manifest.dependencies
        .iter()
        .filter_map(|dep| {
            if dep.optional {
                Some(&dep.name)
            }
            else {
                None
            }
        })
        .chain(manifest.features.keys())
        .collect::<Vec<_>>();

    println!("features: {:?}", features);
}

With a Cargo.toml like:

[dependencies]
rand = "*"
uuid = { version = "*", optional = true }

[features]
a = []

You'll get an output of:

features: ["uuid", "a"]

@ignatenkobrain
Copy link
Contributor Author

@KodrAus at this point, rust2rpm is still written in python, so I am relying on cargo read-manifest output... and it doesn't list all those features, so if this is really intentional we need to fix output of read-manifest I suppose.

Also, what's the exact rules here? All optional deps? Or only those which are not included in any other feature? What about build/dev-dependencies?

@KodrAus
Copy link

KodrAus commented Jan 8, 2018

As far as I know the rules are:

  • All optional dependencies have a feature to toggle them
  • Regular dependencies and build dependencies can be optional
  • Dev dependencies can't be optional right now (this shouldn't matter though because read-manifest puts all dependencies in the one array)

I think you'll have to parse the json from read-manifest and use the same idea as my snippet above to concat the names of optional dependencies with the crate features to get the set of 'actual' features available.

@ghost
Copy link

ghost commented Jan 8, 2018

I can't find any docs on this, tbh.

@ignatenkobrain
I've been reading about this recently, docs here: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section

Hope that helps.

@ignatenkobrain
Copy link
Contributor Author

@xftroxgpx after reading those sentences for 30 mins I found mention of that... So I think from this issue I want improvement of those words to mark that optional deps are also "features".

@ghost
Copy link

ghost commented Jan 8, 2018

I mean
untitled
:D

EDIT: hey look, I found the last time something like this happened to me, right here: rust-lang/rust#34444 :)

@alexcrichton alexcrichton added the A-documenting-cargo-itself Area: Cargo's documentation label Jan 8, 2018
AndersBlomdell pushed a commit to AndersBlomdell/rust2rpm that referenced this issue Apr 17, 2018
References: rust-lang/cargo#4911
Signed-off-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
@stale
Copy link

stale bot commented Sep 18, 2018

As there hasn't been any activity here in over 6 months I've marked this as stale and if no further activity happens for 7 days I will close it.

I'm a bot so this may be in error! If this issue should remain open, could someone (the author, a team member, or any interested party) please comment to that effect?

The team would be especially grateful if such a comment included details such as:

  • Is this still relevant?
  • If so, what is blocking it?
  • Is it known what could be done to help move this forward?

Thank you for contributing!

(The cargo team is currently evaluating the use of Stale bot, and using #6035 as the tracking issue to gather feedback.)

If you're reading this comment from the distant future, fear not if this was closed automatically. If you believe it's still an issue please leave a comment and a team member can reopen this issue. Opening a new issue is also acceptable!

@stale stale bot added the stale label Sep 18, 2018
@stale
Copy link

stale bot commented Oct 18, 2018

As I didn't see any updates in 30 days I'm going to close this. Please see the previous comment for more information!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-documenting-cargo-itself Area: Cargo's documentation
Projects
None yet
Development

No branches or pull requests

3 participants