Zepter
Analyze, Fix and Format features in your Rust workspace. The goal of this tool is to have this CI ready to prevent common errors with Rust features.
Install
Commands
zepter
- format
- features: Format features layout and remove duplicates.
- trace: Trace dependencies paths.
- lint
- propagate-features: Check that features are passed down.
- never-enables: A feature should never enable another other.
- never-implies (⚠️ unstable): A feature should never transitively imply another one.
- only-enables (⚠️ unstable): A features should exclusively enable another one.
- why-enables (⚠️ unstable): Find out why a specific feature is enables.
Example - Feature Formatting
To ensure that your features are in canonical formatting, just run:
# Or shorter:
The output will tell you which features are missing formatting:
Found 3 crates with unformatted features:
polkadot-cli
polkadot-runtime-common
polkadot-runtime-parachains
...
Run again without --check to format them.
You can then re-run without the check/c flag to get it fixed automatically:
Found 3 crates with unformatted features:
polkadot-cli
polkadot-parachain
polkadot-core-primitives
polkadot-primitives
...
Formatted 37 crates (all fixed).
Looking at the diff that this command produces; Zepter assumes a default line width of 80. For one-lined features they will just be padded with spaces:
-default = [
- "static_assertions",
-]
+default = [ "static_assertions" ]
Entries are sorted, comments are kept and indentation is one tab for your convenience 😊
- # Hi
- "xcm/std",
"xcm-builder/std",
+ # Hi
+ "xcm/std",
Example - Fixing feature propagation
Let's check that the runtime-benchmarks feature is properly passed down to all the dependencies of the frame-support crate in the workspace of Substrate. You can use commit 395853ac15 to verify it yourself:
The output reveals that some dependencies expose the feature but don't get it passed down:
crate 'frame-support'
feature 'runtime-benchmarks'
must propagate to:
frame-system
sp-runtime
sp-staking
Found 3 issues and fixed 0 issues.
Without the -p it will detect many more problems. You can verify this for the frame-support which is indeed missing the feature for sp-runtime while sp-runtime clearly supports it 🤔.
This can be fixed by appending the --fix flag, which results in this diff:
-runtime-benchmarks = []
+runtime-benchmarks = [
+ "frame-system/runtime-benchmarks",
+ "sp-runtime/runtime-benchmarks",
+ "sp-staking/runtime-benchmarks",
+]
The auto-fix can be configured to enable specific optional dependencies as non-optional via --feature-enables-dep="runtime-benchmarks:frame-benchmarking" for example. In this case the frame-benchmarking dependency would enabled as non-optional if the runtime-benchmarks feature is enabled.
Example - Feature tracing
Let's say you want to ensure that specific features are never enabled by default. For this example, we will use the try-runtime feature of Substrate. Check out branch oty-faulty-feature-demo and try:
The precondition defines the feature on the left side of the implication and stays-disabled expressing that the precondition never enables this.
Errors correctly with:
Feature 'default' implies 'try-runtime' via path:
frame-benchmarking/default -> frame-benchmarking/std -> frame-system/std -> frame-support/wrong -> frame-support/wrong2 -> frame-support/try-runtime
Only the first path is shown in case there are multiple.
Example - Dependency tracing
Recently there was a build error in the Substrate master CI which was caused by a downstream dependency snow. To investigate this, it is useful to see how Substrate depends on it.
Let's find out how node-cli depends on snow (example on commit dd6aedee3b8d5):
It reports that snow is pulled in from libp2p - good to know. In this case, all paths are displayed.
node-cli -> try-runtime-cli -> substrate-rpc-client -> sc-rpc-api -> sc-chain-spec -> sc-telemetry -> libp2p -> libp2p-webrtc -> libp2p-noise -> snow
CI Usage
Zepter is currently being used experimentially in the Substrate CI to spot missing features. Usage in the Polkadot repository will be added soon as well.
When these two experiments proove the usefulness and reliability of Zepter for CI application, then a more streamlined process will be introduced (possibly in the form of CI actions).
Testing
UI and integration tests are run with the normal cargo test.
Environment overwrites exist for:
OVERWRITE: Update thecoutanddifflocks.UI_FILTER: Regex to selectively run files.KEEP_GOING: PrintFAILEDbut don't abort. TODO: It's buggy
Planned Features
- Add feature information to the enabled deps
- Optimize
shortest_pathfunction - Add support for config files
- Feature sorting and deduplication