Skip to content

Commit

Permalink
Merge #141
Browse files Browse the repository at this point in the history
141: Do not add --all-features to combinations if it is already covered by another combination r=taiki-e a=taiki-e

This fixes an issue where `--feature-powerset` and `--each-feature` add `--all-features` as one of the combinations, even if it is already covered by another combination. (The initial work on this fix was included in #140.)

Hopefully, the new behavior should be explained almost exactly in the long help message.

https://github.com/taiki-e/cargo-hack/blob/4234b37e670368067b64dba249ac41616fe2da85/tests/long-help.txt#L30-L37

https://github.com/taiki-e/cargo-hack/blob/4234b37e670368067b64dba249ac41616fe2da85/tests/long-help.txt#L39-L47

Follow-up: #42

Co-authored-by: Taiki Endo <te316e89@gmail.com>
  • Loading branch information
bors[bot] and taiki-e committed Dec 29, 2021
2 parents 55fd69a + b868cbf commit 7260fc3
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 158 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com

- Add `--keep-going` flag. ([#140](https://github.com/taiki-e/cargo-hack/pull/140))

- Fix an issue where `--feature-powerset` and `--each-feature` add `--all-features` as one of the combinations, even if it is already covered by another combination. ([#141](https://github.com/taiki-e/cargo-hack/pull/141))

## [0.5.8] - 2021-10-13

- Distribute statically linked binary on Windows MSVC. ([#131](https://github.com/taiki-e/cargo-hack/pull/131))
Expand Down
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,21 @@ OPTIONS:
--each-feature
Perform for each feature of the package.

This also includes runs with just --no-default-features flag, --all-features flag, and
default features.
This also includes runs with just --no-default-features flag, and default features.

When this flag is not used together with --exclude-features (--skip) and
--include-features and there are multiple features, this also includes runs with just
--all-features flag.

--feature-powerset
Perform for the feature powerset of the package.

This also includes runs with just --no-default-features flag, --all-features flag, and
default features.
This also includes runs with just --no-default-features flag, and default features.

When this flag is used together with --depth or namespaced features (-Z
namespaced-features) and not used together with --exclude-features (--skip) and
--include-features and there are multiple features, this also includes runs with just
--all-features flag.

--optional-deps [DEPS]...
Use optional dependencies as features.
Expand Down Expand Up @@ -209,6 +216,8 @@ this purpose, it is recommended to use with `--no-dev-deps` to avoid
cargo hack check --each-feature --no-dev-deps
```

See also [Options for adjusting the behavior of --each-feature and --feature-powerset](#options-for-adjusting-the-behavior-of---each-feature-and---feature-powerset) section.

### --feature-powerset

Perform for the feature powerset which includes `--no-default-features` and
Expand All @@ -222,6 +231,12 @@ properly. (When used for this purpose, it is recommended to use with
cargo hack check --feature-powerset --no-dev-deps
```

cargo-hack deduplicate any fully equivalent feature combinations based on how the cargo features work. Therefore, it may be more efficient than checking all feature combinations in other ways.

When using this flag results in a very large number of feature combinations, consider using [`--depth`](#--depth) option.

See also [Options for adjusting the behavior of --each-feature and --feature-powerset](#options-for-adjusting-the-behavior-of---each-feature-and---feature-powerset) section.

### --no-dev-deps

Perform without dev-dependencies.
Expand Down Expand Up @@ -296,6 +311,13 @@ The following flags can be used with `--each-feature` and `--feature-powerset`.

Use optional dependencies as features.

This flag treats all option dependencies as features by default.
To treat only specific dependencies as features, pass a space or comma separated list.

```sh
cargo hack check --feature-powerset --optional-deps deps1,deps2
```

#### --exclude-features, --skip

Space-separated list of features to exclude.
Expand Down
74 changes: 59 additions & 15 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,13 @@ pub(crate) fn parse_args<'a>(raw: &'a [String], cargo: &OsStr) -> Result<Args<'a
);
}

// https://github.com/taiki-e/cargo-hack/issues/42
// https://github.com/rust-lang/cargo/pull/8799
let namespaced_features = has_z_flag(&leading, "namespaced-features");
exclude_no_default_features |= !include_features.is_empty();
exclude_all_features |= !include_features.is_empty() || !exclude_features.is_empty();
exclude_all_features |= !include_features.is_empty()
|| !exclude_features.is_empty()
|| (feature_powerset && !namespaced_features && depth.is_none());
exclude_features.extend_from_slice(&features);

term::set_verbose(verbose);
Expand Down Expand Up @@ -520,6 +525,25 @@ pub(crate) fn parse_args<'a>(raw: &'a [String], cargo: &OsStr) -> Result<Args<'a
})
}

fn has_z_flag(args: &[&str], name: &str) -> bool {
let mut iter = args.iter().copied();
while let Some(mut arg) = iter.next() {
if arg == "-Z" {
arg = iter.next().unwrap();
} else if let Some(a) = arg.strip_prefix("-Z") {
arg = a
} else {
continue;
}
if let Some(rest) = arg.strip_prefix(name) {
if rest.is_empty() || rest.starts_with('=') {
return true;
}
}
}
false
}

fn parse_opt<'a>(
arg: &'a str,
args: &mut Peekable<impl Iterator<Item = &'a str>>,
Expand Down Expand Up @@ -565,27 +589,40 @@ const HELP: &[HelpText<'_>] = &[
("", "--manifest-path", "<PATH>", "Path to Cargo.toml", &[]),
("", "--features", "<FEATURES>...", "Space-separated list of features to activate", &[]),
("", "--each-feature", "", "Perform for each feature of the package", &[
"This also includes runs with just --no-default-features flag, --all-features flag, and default features.",
"This also includes runs with just --no-default-features flag, and default features.",
"When this flag is not used together with --exclude-features (--skip) and \
--include-features and there are multiple features, this also includes runs with \
just --all-features flag."
]),
("", "--feature-powerset", "", "Perform for the feature powerset of the package", &[
"This also includes runs with just --no-default-features flag, --all-features flag, and default features.",
"This also includes runs with just --no-default-features flag, and default features.",
// https://github.com/rust-lang/cargo/pull/8799
"When this flag is used together with --depth or namespaced features \
(-Z namespaced-features) and not used together with --exclude-features (--skip) and \
--include-features and there are multiple features, this also includes runs with just \
--all-features flag."
]),
("", "--optional-deps", "[DEPS]...", "Use optional dependencies as features", &[
"If DEPS are not specified, all optional dependencies are considered as features.",
"This flag can only be used together with either --each-feature flag or --feature-powerset flag.",
"This flag can only be used together with either --each-feature flag or --feature-powerset \
flag.",
]),
("", "--skip", "<FEATURES>...", "Alias for --exclude-features", &[]),
("", "--exclude-features", "<FEATURES>...", "Space-separated list of features to exclude", &[
"To exclude run of default feature, using value `--exclude-features default`.",
"To exclude run of just --no-default-features flag, using --exclude-no-default-features flag.",
"To exclude run of just --no-default-features flag, using --exclude-no-default-features \
flag.",
"To exclude run of just --all-features flag, using --exclude-all-features flag.",
"This flag can only be used together with either --each-feature flag or --feature-powerset flag.",
"This flag can only be used together with either --each-feature flag or --feature-powerset \
flag.",
]),
("", "--exclude-no-default-features", "", "Exclude run of just --no-default-features flag", &[
"This flag can only be used together with either --each-feature flag or --feature-powerset flag.",
"This flag can only be used together with either --each-feature flag or --feature-powerset \
flag.",
]),
("", "--exclude-all-features", "", "Exclude run of just --all-features flag", &[
"This flag can only be used together with either --each-feature flag or --feature-powerset flag.",
"This flag can only be used together with either --each-feature flag or --feature-powerset \
flag.",
]),
(
"",
Expand All @@ -598,26 +635,31 @@ const HELP: &[HelpText<'_>] = &[
],
),
("", "--group-features", "<FEATURES>...", "Space-separated list of features to group", &[
"To specify multiple groups, use this option multiple times: `--group-features a,b --group-features c,d`",
"To specify multiple groups, use this option multiple times: `--group-features a,b \
--group-features c,d`",
"This flag can only be used together with --feature-powerset flag.",
]),
(
"",
"--include-features",
"<FEATURES>...",
"Include only the specified features in the feature combinations instead of package features",
"Include only the specified features in the feature combinations instead of package \
features",
&[
"This flag can only be used together with either --each-feature flag or --feature-powerset flag.",
"This flag can only be used together with either --each-feature flag or \
--feature-powerset flag.",
],
),
("", "--no-dev-deps", "", "Perform without dev-dependencies", &[
"Note that this flag removes dev-dependencies from real `Cargo.toml` while cargo-hack is running and restores it when finished.",
"Note that this flag removes dev-dependencies from real `Cargo.toml` while cargo-hack is \
running and restores it when finished.",
]),
(
"",
"--remove-dev-deps",
"",
"Equivalent to --no-dev-deps flag except for does not restore the original `Cargo.toml` after performed",
"Equivalent to --no-dev-deps flag except for does not restore the original `Cargo.toml` \
after performed",
&[],
),
("", "--ignore-private", "", "Skip to perform on `publish = false` packages", &[]),
Expand All @@ -634,7 +676,8 @@ const HELP: &[HelpText<'_>] = &[
"<START>..[END]",
"Perform commands on a specified (inclusive) range of Rust versions",
&[
"If the given range is unclosed, the latest stable compiler is treated as the upper bound.",
"If the given range is unclosed, the latest stable compiler is treated as the upper \
bound.",
"Note that ranges are always inclusive ranges.",
],
),
Expand All @@ -646,7 +689,8 @@ const HELP: &[HelpText<'_>] = &[
&["This flag can only be used together with --version-range flag."],
),
("", "--clean-per-run", "", "Remove artifacts for that package before running the command", &[
"If used this flag with --workspace, --each-feature, or --feature-powerset, artifacts will be removed before each run.",
"If used this flag with --workspace, --each-feature, or --feature-powerset, artifacts will \
be removed before each run.",
"Note that dependencies artifacts will be preserved.",
]),
("", "--clean-per-version", "", "Remove artifacts per Rust version", &[
Expand Down
15 changes: 11 additions & 4 deletions tests/long-help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,21 @@ OPTIONS:
--each-feature
Perform for each feature of the package.

This also includes runs with just --no-default-features flag, --all-features flag, and
default features.
This also includes runs with just --no-default-features flag, and default features.

When this flag is not used together with --exclude-features (--skip) and
--include-features and there are multiple features, this also includes runs with just
--all-features flag.

--feature-powerset
Perform for the feature powerset of the package.

This also includes runs with just --no-default-features flag, --all-features flag, and
default features.
This also includes runs with just --no-default-features flag, and default features.

When this flag is used together with --depth or namespaced features (-Z
namespaced-features) and not used together with --exclude-features (--skip) and
--include-features and there are multiple features, this also includes runs with just
--all-features flag.

--optional-deps [DEPS]...
Use optional dependencies as features.
Expand Down
Loading

0 comments on commit 7260fc3

Please sign in to comment.