-
-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
feature_not_enabled_by_default
lint. (#1051)
It'll catch features that used to be enabled by default, and then stop being defaults. Adds the lint requested by obi1kenobi/cargo-semver-checks-action#91
- Loading branch information
1 parent
f119ecf
commit 442ebf0
Showing
9 changed files
with
191 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
SemverQuery( | ||
id: "feature_not_enabled_by_default", | ||
human_readable_name: "package feature is not enabled by default", | ||
description: "A feature has been removed from this package's set of default features.", | ||
required_update: Major, | ||
lint_level: Deny, | ||
reference_link: Some("https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove-another"), | ||
query: r#" | ||
{ | ||
CrateDiff { | ||
baseline { | ||
default_feature { | ||
# Until cargo ships with support for private and/or unstable feature names, | ||
# we'll rely on feature names to detect whether to flag feature removals. | ||
# | ||
# This lint will ignore features that match any of the following: | ||
# - start with an underscore (`_`) character | ||
# - are named `unstable`, `nightly`, or `bench` | ||
# - have a prefix of `unstable`, `nightly`, or `bench` followed by | ||
# a dash (`-`) or underscore (`_`) character. | ||
# | ||
# Cargo tracking issues: | ||
# - unstable/nightly features: https://github.com/rust-lang/cargo/issues/10881 | ||
# - private/hidden features: https://github.com/rust-lang/cargo/issues/10882 | ||
name @tag | ||
@filter(op: "not_regex", value: ["$unstable_feature_pattern"]) | ||
@filter(op: "not_has_prefix", value: ["$underscore"]) | ||
@output | ||
# An explicit ordering key is needed since we don't have span information, | ||
# which what we usually use to order results in tests. | ||
name @output(name: "ordering_key") | ||
} | ||
} | ||
current { | ||
default_feature @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { | ||
name @filter(op: "=", value: ["%name"]) | ||
} | ||
# Ensure the feature still exists, just isn't enabled by default. | ||
# If the feature is missing entirely, we want to report it | ||
# in the `feature_missing` lint, not here. | ||
feature @fold @transform(op: "count") @filter(op: ">", value: ["$zero"]) { | ||
name @filter(op: "=", value: ["%name"]) | ||
} | ||
} | ||
} | ||
}"#, | ||
arguments: { | ||
"zero": 0, | ||
"unstable_feature_pattern": "^(?:unstable|nightly|bench)(?:[-_].*)?$", | ||
"underscore": "_", | ||
}, | ||
error_message: "A feature is no longer enabled by default for this package. This will break downstream crates which rely on the package's default features and require the functionality of this feature.", | ||
per_result_error_template: Some("feature {{name}} in the package's Cargo.toml"), | ||
// TODO: It's currently not possible to write witnesses for manifest lints, | ||
// since we'd need to generate a *Cargo.toml* witness instead of a Rust code witness. | ||
// Issue: https://github.com/obi1kenobi/cargo-semver-checks/issues/1008 | ||
witness: None, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
[package] | ||
publish = false | ||
name = "feature_not_enabled_by_default" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
# Since `rand` isn't used in a feature with `dep:rand` syntax, | ||
# it defines an implicit feature by that name. | ||
# Removing that implicit feature from the defaults is a breaking change. | ||
rand = { version = "*", optional = true } | ||
|
||
[features] | ||
default = ["still_present", "transitive", "multi_root_transitive"] | ||
still_present = [] | ||
becoming_non_default = [] | ||
|
||
# The `transitive` feature used to depend on `indirect_feature`. | ||
# `transitive` is enabled by default, but removing `indirect_feature` from `transitive` | ||
# means that `indirect_feature` is *no longer enabled by default*. | ||
# This is breaking and should be reported. | ||
transitive = [] | ||
indirect_feature = [] | ||
|
||
# The `root` feature is depended on in multiple ways in the default features. | ||
# Breaking some of those paths, but not all of them, still means that `root` is enabled by default. | ||
# There's no breaking change here, and no lints should trigger. | ||
multi_root_transitive = ["path_a", "path_b"] | ||
path_a = ["root"] | ||
path_b = [] | ||
root = [] | ||
|
||
# We ignore unstable-looking feature names. | ||
# All of the following will be removed from the default features, | ||
# and none of them should be flagged. | ||
unstable = [] | ||
nightly = [] | ||
bench = [] | ||
unstable-dash = [] | ||
unstable_underscore = [] | ||
nightly-dash = [] | ||
nightly_underscore = [] | ||
bench-dash = [] | ||
bench_underscore = [] | ||
_underscore_prefix = [] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
[package] | ||
publish = false | ||
name = "feature_not_enabled_by_default" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
# Since `rand` isn't used in a feature with `dep:rand` syntax, | ||
# it defines an implicit feature by that name. | ||
# Removing that implicit feature from the defaults is a breaking change. | ||
rand = { version = "*", optional = true } | ||
|
||
[features] | ||
default = ["becoming_non_default", "still_present", "missing_entirely", "rand", "transitive", "multi_root_transitive", "unstable", "nightly", "bench", "unstable", "unstable_underscore", "nightly", "nightly_underscore", "bench", "bench_underscore", "_underscore_prefix"] | ||
still_present = [] # No breakage here. | ||
becoming_non_default = [] # Should be reported. | ||
missing_entirely = [] # Flagged only by `feature_missing`, even though it was default too. | ||
|
||
# The `transitive` feature depends on `indirect_feature`. | ||
# `transitive` is enabled by default, but removing `indirect_feature` from `transitive` | ||
# means that `indirect_feature` is *no longer enabled by default*. | ||
# This is breaking and should be reported. | ||
transitive = ["indirect_feature"] | ||
indirect_feature = [] | ||
|
||
# The `root` feature is depended on in multiple ways in the default features. | ||
# Breaking some of those paths, but not all of them, still means that `root` is enabled by default. | ||
# There's no breaking change here, and no lints should trigger. | ||
multi_root_transitive = ["path_a", "path_b"] | ||
path_a = ["root"] | ||
path_b = ["root"] | ||
root = [] | ||
|
||
# We ignore unstable-looking feature names. | ||
# All of the following will be removed from the default features, | ||
# and none of them should be flagged. | ||
unstable = [] | ||
nightly = [] | ||
bench = [] | ||
unstable-dash = [] | ||
unstable_underscore = [] | ||
nightly-dash = [] | ||
nightly_underscore = [] | ||
bench-dash = [] | ||
bench_underscore = [] | ||
_underscore_prefix = [] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
test_outputs/query_execution/feature_not_enabled_by_default.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--- | ||
source: src/query.rs | ||
expression: "&query_execution_results" | ||
snapshot_kind: text | ||
--- | ||
{ | ||
"./test_crates/feature_not_enabled_by_default/": [ | ||
{ | ||
"name": String("becoming_non_default"), | ||
"ordering_key": String("becoming_non_default"), | ||
}, | ||
{ | ||
"name": String("indirect_feature"), | ||
"ordering_key": String("indirect_feature"), | ||
}, | ||
{ | ||
"name": String("rand"), | ||
"ordering_key": String("rand"), | ||
}, | ||
], | ||
"./test_crates/features_simple/": [ | ||
{ | ||
"name": String("foo"), | ||
"ordering_key": String("foo"), | ||
}, | ||
], | ||
} |