Clippier
Monorepo workspace analysis and automation tool for managing multi-package projects, with focus on CI/CD pipeline generation and dependency analysis.
Overview
Clippier is a command-line utility designed to analyze monorepo workspaces and automate various development tasks. It supports multiple workspace types including Cargo (Rust) and Node.js (npm, pnpm, bun):
- CI/CD Pipeline Generation: Generate feature matrices for testing
- Dependency Analysis: Analyze workspace dependencies and relationships
- Feature Management: Generate feature combinations for comprehensive testing
- Selective Package Processing: Filter operations to specific packages for targeted analysis
- Feature Propagation Validation: Ensure features are correctly propagated across workspace dependencies
- Parent Package Validation: Validate that parent packages expose all features from their workspace dependencies
- Unified Linting & Formatting: Auto-detect and run multiple linters and formatters with
checkandfmtcommands - Docker Integration: Generate optimized Dockerfiles for workspace packages
- Change Impact Analysis: Determine which packages are affected by file changes
- External Dependency Tracking: Detect changes in external dependencies via git diff analysis
- Multi-Workspace Support: Native support for Cargo and Node.js (npm, pnpm, bun) monorepos
Supported Workspace Types
Clippier supports multiple monorepo workspace types with automatic detection:
Cargo Workspaces (Rust)
- Detection:
Cargo.tomlwith[workspace]section - Lockfile:
Cargo.lock - Package manifest:
Cargo.toml
Node.js Workspaces
Clippier supports three Node.js package managers:
| Package Manager | Workspace Config | Lockfile |
|---|---|---|
| npm | package.json with workspaces field |
package-lock.json |
| pnpm | pnpm-workspace.yaml |
pnpm-lock.yaml |
| bun | package.json with workspaces field |
bun.lock |
Auto-Detection and Priority
When multiple workspace types exist in the same directory:
- Cargo workspaces take priority by default
- Use
--workspace-type nodeto explicitly select Node.js workspace - Use
--workspace-type cargoto explicitly select Cargo workspace
# Auto-detect (Cargo takes priority if both exist)
# Explicitly use Node.js workspace
# Explicitly use Cargo workspace
Installation
From Source
Features
Clippier supports optional features:
cargo-workspace(default): Enable support for Cargo (Rust) workspacesnode-workspace(default): Enable support for Node.js workspaces (npm, pnpm, bun)check(default): Enable thecheckcommand for running lintersformat(default): Enable thefmtcommand for running formattersgit-diff(default): Enhanced change analysis using git diff to detect external dependency changespublish(default): Enable thepublishcommand for Cargo workspace crate publishingtransforms-vendored(default): Enable Lua transform scripts with vendored Lua runtimetransforms-system: Enable Lua transform scripts using system Lua installationfail-on-warnings: Fail build on warnings
Usage
Clippier provides several subcommands for different analysis tasks:
Dependencies Analysis
Analyze workspace dependencies for a specific package:
With specific OS and feature filters:
Environment Configuration
Generate environment configurations:
CI Steps Generation
Generate CI pipeline steps for testing:
Feature Matrix Analysis
Analyze and generate feature combinations for testing:
Wildcard Pattern Support in skip-features
The --skip-features flag supports powerful wildcard patterns and negation:
Wildcard Patterns:
# Skip all features ending with -default
# Skip all features starting with test-
# Skip features with single character after prefix (v1, v2, but not v10)
# Combine multiple patterns
Negation Patterns (Skip All Except):
# Skip everything except enable-bob
# Skip everything except features starting with enable-
# Complex: skip *-default and test-* features, but keep test-utils
Pattern Syntax:
| Pattern | Matches | Example |
|---|---|---|
* |
Zero or more characters | *-default matches bob-default, sally-default |
? |
Exactly one character | v? matches v1, v2 but not v10 |
!pattern |
Negation (excludes matching items) | *,!enable-bob includes all except enable-bob |
| Exact match | No wildcards | default matches only default |
Pattern Evaluation:
- Patterns are evaluated in order from left to right
- For
--skip-features: The last matching pattern determines if a feature is skipped - For
--features,--packages,--required-features: Negations remove items from the result set - Negation (
!) works in all wildcard-supporting arguments
Configuration File Usage:
[[]]
= "ubuntu"
= { = ["*-default", "test-*", "!test-utils"] }
Wildcard Pattern Support in --features
The --features flag supports wildcard patterns and negation for selecting features:
# Include all features starting with enable-
# Include multiple wildcard patterns
# Mix exact features with wildcards
# Use negation to include all except specific features
# Include enable-* features except enable-experimental
# Combine with skip-features for powerful filtering
Note: The --features flag uses inclusion (expand matching features), while --skip-features uses exclusion (remove matching features). Both support negation with ! prefix. They can be combined for precise control.
Wildcard Pattern Support in --required-features
The --required-features flag supports wildcard patterns and negation for specifying required features. These patterns are expanded to concrete feature names in the JSON output, making them suitable for consumption by CI tools and scripts.
# Require all features starting with enable-
# Require multiple wildcard patterns
# Mix exact features with wildcards
# Use negation to require enable-* except enable-experimental
# Combine with other feature flags
Important: Unlike --skip-features (which removes features) and --features (which selects features to process), --required-features is metadata that gets included in the JSON output. Wildcards and negations are expanded so downstream consumers receive concrete feature names, not glob patterns.
Example output:
Configuration File Usage:
[[]]
= "ubuntu"
= { = ["enable-*", "production"] }
The wildcards will be expanded when the configuration is processed, ensuring the JSON output contains concrete feature names.
Deterministic Randomization with Seed
Use a specific seed for reproducible randomized feature combinations:
When --randomize is used without --seed, a random seed is generated and printed to stderr (not affecting JSON output):
# Outputs: Generated seed: 1234567890 (to stderr)
This enables replaying the same randomized distribution by using the printed seed value.
Package Filtering
Filter feature matrix generation to specific packages by name or by Cargo.toml properties:
Wildcard Pattern Support:
The --packages flag supports wildcard patterns for selecting packages:
# Process all packages starting with moosicbox_
# Process all server packages except test servers
# Process specific API packages
# Mix wildcards with exact names
Property-Based Filtering:
# Filter by package properties (exclude unpublished and examples)
# Include only packages with specific characteristics
Combined Filtering:
# Combine wildcards with other filters
This is particularly useful for:
- Focused testing: Test only specific packages during development
- CI optimization: Build matrix for selected components based on criteria
- Monorepo management: Process subsets of large workspaces with naming conventions
- Quality gates: Filter by documentation completeness, categories, etc.
Enhanced Change Impact Analysis
Include only features for packages affected by specific file changes:
Git-Based External Dependency Analysis (Requires git-diff feature)
Analyze feature matrices considering both file changes and external dependency changes:
Packages Command
Generate a list of workspace packages (useful for CI matrix generation with one job per package):
# List all packages in workspace
# List packages for specific OS
# Filter to specific packages
# Limit number of packages (useful for parallel job limits)
With Change Detection (Requires git-diff feature)
List only packages affected by file changes:
# Using manual changed files
# Using git diff
# Combined: manual files + git diff + external dependency tracking
Node.js Workspaces
The packages command works with Node.js monorepos (npm, pnpm, bun):
# List packages in a Node.js monorepo (auto-detected from lockfile)
# Explicitly use Node.js workspace type
# With change detection using lockfile changes
The packages command provides:
- Package enumeration: List all workspace packages with metadata
- Change-based filtering: Only include packages affected by specific changes
- Git integration: Automatically detect changed files from git commits
- External dependency tracking: Detect packages affected by lockfile changes (Cargo.lock, pnpm-lock.yaml, package-lock.json, bun.lock)
- CI matrix optimization: Generate one job per package instead of per feature
- Multi-workspace support: Works with Cargo, npm, pnpm, and bun workspaces
Output format:
Use cases:
- CI/CD: Generate job matrices for parallel package testing
- Change analysis: Identify which packages need rebuilding
- Monorepo management: List subsets of packages for targeted operations
- Documentation: Generate package inventories for workspace documentation
Publish Cargo Workspace Crates
Publish all crates in a Cargo workspace, skipping versions that already exist on crates.io and ordering unpublished crates by normal/build workspace dependencies:
# Publish from the current directory
# Preview what would be published
# Publish one package plus its normal/build workspace dependencies
# Use an explicit workspace path
clippier publish ignores dev-dependencies when computing publish order so dev-dependency cycles do not block publication. It publishes from a temporary sanitized manifest with workspace dev-dependencies removed and workspace dependency inheritance resolved. It defaults to cargo publish --no-verify; pass --verify to run Cargo's local verification step.
Workspace Dependencies
Find all workspace dependencies for a package:
Include specific features:
All Potential Dependencies Mode
Include all potential workspace dependencies (useful for Docker builds):
This mode includes all workspace dependencies regardless of feature activation, ensuring Docker builds have access to all required packages for build compatibility.
Generate Dockerfile
Automatically generate optimized multi-stage Dockerfiles:
The generated Dockerfiles include:
- Multi-stage builds for optimized layer caching
- Automatic system dependency detection from
clippier.tomlfiles - Workspace member optimization
- Build artifact caching
- Runtime dependency installation
Affected Packages Analysis
Determine which packages are affected by file changes:
Enhanced Git-Based Analysis (Requires git-diff feature)
Analyze impact including external dependency changes from Cargo.lock:
This enhanced mode:
- Detects changes in external dependencies by analyzing lockfile diff (Cargo.lock, pnpm-lock.yaml, package-lock.json, bun.lock)
- Maps external dependency changes to affected workspace packages
- Provides comprehensive impact analysis for both internal and external changes
- Works with both Cargo and Node.js workspaces
Node.js Workspaces
# Analyze affected packages in a Node.js monorepo
Feature Propagation Validation
Validate that features are correctly propagated across workspace dependencies to ensure consistent builds and prevent feature-related compilation failures:
# Quick validation of fail-on-warnings feature
# Auto-detect and validate all matching features
# Validate specific packages only
The feature validator ensures that when a package depends on another workspace package that has a specific feature, that feature is correctly propagated. This prevents build failures where features are inconsistently enabled across the dependency graph.
Common Use Cases
Validate fail-on-warnings propagation:
Auto-detect features that need propagation:
# Automatically finds features that exist in multiple packages
CI/CD Integration:
Get detailed JSON report:
Understanding Validation Results
The validator provides clear feedback about feature propagation issues:
Successful validation:
✅ All packages correctly propagate features!
Total packages checked: 147
Valid packages: 147
Validation with errors:
❌ Found 2 packages with incorrect feature propagation:
📦 Package: moosicbox_server
Feature: fail-on-warnings
Missing propagations:
- moosicbox_tcp/fail-on-warnings (Dependency 'moosicbox_tcp' has feature but it's not propagated)
Error Types and Meanings
The validator detects two types of issues:
Missing Propagations:
- A dependency has a feature but it's not propagated
- Example:
pkg_adepends onpkg_bwhich hasfail-on-warnings, butpkg_adoesn't propagate it - Fix: Add
"pkg_b/fail-on-warnings"to the feature definition inpkg_a
Incorrect Propagations:
- A feature is propagated to a non-existent dependency or feature
- Example:
pkg_apropagatespkg_b/featurebutpkg_bdoesn't havefeature - Fix: Remove the incorrect propagation or add the missing feature to the dependency
Optional Dependencies:
The validator correctly handles optional dependencies using the ? syntax:
dep?/feature- Propagates feature only when the optional dependency is activated- Required for dependencies marked with
optional = truein Cargo.toml
Overriding Validation Errors
Sometimes you need to suppress specific validation errors on a case-by-case basis. Clippier supports three methods for overriding validation failures, with clear precedence rules:
Override Precedence (Highest to Lowest):
- CLI arguments (temporary overrides for testing)
- Package-level
clippier.toml(package-specific configuration) - Package-level
Cargo.tomlmetadata (inline configuration) - Workspace-level
clippier.toml(workspace-wide defaults)
CLI Overrides (Quick Testing):
# Allow a specific missing propagation
# Allow missing propagation for all packages
# Ignore specific packages entirely
# Ignore specific features globally
Package-Level clippier.toml (Recommended for Persistent Overrides):
# packages/server/clippier.toml
[]
[[]]
= "fail-on-warnings"
= "legacy_tcp"
= "allow-missing"
= "Legacy dependency doesn't support fail-on-warnings - tracked in #123"
= "2025-12-31"
[[]]
= "async-*"
= "sync_util"
= "allow-missing"
= "Utility crate is intentionally synchronous"
Workspace-Level clippier.toml (Workspace-Wide Policies):
# {workspace_root}/clippier.toml
[]
[[]]
= "*"
= "external_vendor_*"
= "allow-missing"
= "Vendor dependencies don't follow our feature conventions"
Package Cargo.toml Metadata (Inline Configuration):
# packages/server/Cargo.toml
[]
[[]]
= "fail-on-warnings"
= "some_dep"
= "allow-missing"
= "Dependency issue tracked in #456"
Override Types:
allow-missing- Allow a specific missing propagationallow-incorrect- Allow a specific incorrect propagationsuppress- Suppress all validation for matching cases
Wildcard Support:
Overrides support wildcard patterns for flexible matching:
[[]]
= "async-*" # Matches async-io, async-runtime, etc.
= "*_sync" # Matches util_sync, core_sync, etc.
= "allow-missing"
= "Sync dependencies don't support async features"
Expiration Dates:
Add expiration dates to temporary overrides to ensure they're revisited:
[[]]
= "fail-on-warnings"
= "legacy_dep"
= "allow-missing"
= "Migration in progress"
= "2025-12-31" # RFC 3339 or YYYY-MM-DD format
Output with Overrides:
When overrides are applied, the validation output includes a summary:
🔍 Feature Propagation Validation Results
=========================================
Total packages checked: 147
Valid packages: 147
📋 Override Summary:
Applied: 3 overrides
- cli: 1
- package-clippier-toml: 2
🔕 Overridden Errors (3):
📦 server:fail-on-warnings:legacy_tcp
Reason: Legacy dependency migration in progress
Source: PackageClippierToml
Expires: 2025-12-31
✅ All packages correctly propagate features (with 3 overrides)!
Advanced Override Options:
# Fail if any overrides have expired
# Show detailed override information
Parent Package Validation
Parent packages are packages that aggregate and re-export features from their workspace dependencies. The validator can ensure that parent packages correctly expose all features from their dependencies with appropriate naming conventions.
What is a Parent Package?
A parent package typically:
- Depends on multiple workspace packages
- Re-exports features from those dependencies using a prefix pattern
- Acts as a facade for a subsystem of the workspace
For example, if moosicbox_app depends on moosicbox_audio which has features mp3, flac, and aac, the parent should expose them as audio-mp3, audio-flac, and audio-aac.
CLI Usage:
# Validate specific packages as parent packages
# Limit depth of dependency chain checking
# Skip additional features during parent validation
# Override prefix for specific dependencies
# Disable loading parent config from clippier.toml
Package-Level Configuration (clippier.toml):
# packages/moosicbox_app/clippier.toml
[]
# Declare this package as a parent package
[]
= true
= 2 # Only check direct deps and their deps (optional)
= ["internal-*", "test-*"] # Additional features to skip
# Override prefixes for specific dependencies
[[]]
= "moosicbox_audio"
= "audio"
[[]]
= "moosicbox_video"
= "video"
Workspace-Level Configuration (clippier.toml):
# {workspace_root}/clippier.toml
[]
# Declare parent packages at workspace level
[[]]
= "moosicbox_app"
= 2
[[]]
= "moosicbox_server"
# Global prefix overrides
[[]]
= "moosicbox_audio"
= "audio"
Understanding Prefix Inference:
By default, the validator infers the prefix from the dependency name:
moosicbox_audio→audioswitchy_database→databasemy_lib→lib
The prefix is derived by taking the last segment after underscores. You can override this with explicit prefix configuration.
Validation Output:
🔍 Feature Propagation Validation Results
=========================================
Total packages checked: 147
Valid packages: 147
📦 Parent Package Validation
=============================
📦 Package: moosicbox_app
Dependencies checked: 5
Features checked: 42
Features correctly exposed: 40
❌ Missing Feature Exposures:
Dependency: moosicbox_audio
Feature: experimental-codec
Expected parent feature: audio-experimental-codec
Expected propagation: moosicbox_audio?/experimental-codec
Depth: 1
Dependency: moosicbox_video (via moosicbox_media)
Feature: av1
Expected parent feature: video-av1
Expected propagation: moosicbox_video?/av1
Depth: 2
Chain: moosicbox_app -> moosicbox_media -> moosicbox_video
Parent Validation Options:
| Option | Description | Default |
|---|---|---|
--parent-packages |
Packages to validate as parent packages | From config |
--parent-depth |
Max depth for nested dependency checking (None = all) | None (unlimited) |
--parent-skip-features |
Additional features to skip | ["default", "_*"] |
--parent-prefix |
Override prefix for dependencies (dep:prefix) |
Auto-inferred |
--no-parent-config |
Disable loading parent config from clippier.toml | false |
Check Command (Linting)
Run all available linters in your workspace with automatic tool detection:
# Run all detected linters
# Run in a specific directory
# Run only specific tools
# List available tools without running them
# Include execution metadata in JSON output (`cargo` / `binary` / `runner`)
# Require specific tools (fail if not installed)
# Skip specific tools
# JSON output for CI integration
check/fmt also load default tool settings from a clippier.toml in the working directory:
[]
= ["gofmt"]
= ["rustfmt", "taplo"]
= true
= true
= true
[[]]
= "format"
= ["biome", "prettier"]
= ["md", "mdx"]
CLI values are additive: --skip and --required are merged with config values.
The check command automatically detects and runs:
- Rust:
cargo clippy(with-D warningsfor zero-warnings policy) - TOML:
taplo fmt --check - JavaScript/TypeScript:
biome format,eslint - Markdown/MDX:
clippier_mdstrict check - YAML:
dprint check - Python:
ruff check,black --check - Go:
gofmt -l - Shell:
shfmt -d,shellcheck
Tools run in parallel by default for maximum performance.
By default, check auto-selects tools based on manifest/config files in the working directory:
Cargo.toml->clippy,rustfmt,taplopackage.json->eslint,biomepyproject.toml,requirements.txt, orsetup.py->ruff,blackgo.mod->gofmttaplo.toml->taplo.shellcheckrc->shellcheckdprint.json/dprint.jsonc->dprint- workspace includes
packages/clippier/md/Cargo.toml->clippier_md
Fmt Command (Formatting)
Run all available formatters to fix formatting issues:
# Format all files
# Check formatting without modifying files
# Run in a specific directory
# Run only specific formatters
# List available formatters without running them
# Include execution metadata in JSON output (`cargo` / `binary` / `runner`)
# Require specific formatters (fail if not installed)
# Skip specific formatters
# JSON output for CI integration
The fmt command automatically detects and runs:
- Rust:
cargo fmt - TOML:
taplo fmt - JavaScript/TypeScript:
biome format --write - Markdown/MDX:
clippier_md fmt - YAML:
dprint fmt - Python:
ruff format,black - Go:
gofmt -w - Shell:
shfmt -w
By default, fmt auto-selects tools based on manifest/config files in the working directory:
Cargo.toml->rustfmt,taplopackage.json->biomepyproject.toml,requirements.txt, orsetup.py->ruff,blackgo.mod->gofmttaplo.toml->taplo.shfmt.conf->shfmtdprint.json/dprint.jsonc->dprint- workspace includes
packages/clippier/md/Cargo.toml->clippier_md
Clippier only selects and runs tools that are already installed; it never installs tools or modifies your system environment.
Tool resolution precedence (for prettier, biome, eslint, dprint, remark, and clippier_md) is:
- CLI
--tool-path key=valueoverride - Configured path in
tools.paths.<tool> node_modules/.bin/<tool>in the working directory or ancestors- Standalone
<tool>in PATH - Package-manager runner fallback (enabled by default):
bunx, thenpnpm dlx, thennpx --yes
Use --no-runner-fallback to disable runner fallback for a command.
Prettier is invoked with --ignore-unknown for unsupported file types. Use .prettierignore for parser-supported files you want excluded from formatting.
clippier_md provides native strict check behavior for markdown in fmt --check and is the default markdown formatter in this workspace.
When both biome and prettier are explicitly selected, clippier emits overlap warnings when they can target the same extensions.
Overlap warnings are computed dynamically from files currently present in the working directory plus relevant tool config filters (biome.json files.includes and .prettierignore).
Suppress overlap warnings with pair-specific config rules (case-insensitive tool/extension matching):
[]
[[]]
= "format"
= ["biome", "prettier"]
= ["md", "mdx"]
Use extensions = [] (or omit extensions) to suppress all overlap warnings for a pair/capability.
Biome uses .editorconfig by default (--use-editorconfig=true). You can opt out via config (tools.biome-use-editorconfig = false) or CLI (--no-biome-use-editorconfig).
Biome also uses VCS ignore semantics by default (--vcs-enabled=true --vcs-use-ignore-file=true --vcs-root <working-dir>). You can opt out via config (tools.biome-use-vcs-ignore = false) or CLI (--no-biome-use-vcs-ignore).
Precedence for tool selection is:
--tools(explicit tool list)- Auto-detected manifest/config defaults
- CLI/config
required skip
When a tool appears in both required and skip, skip wins. When a tool appears in both --tools and skip, --tools wins.
Color behavior for tool output:
--color autofollows terminal detection--color alwaysforces colors in child tool output--color neverdisables colors in child tool output- For
--output jsonwith--color auto, clippier disables colors to keep JSON payloads clean
TUI behavior for tool output:
- In interactive terminals,
checkandfmtauto-enable a live pane TUI while tools are running - Use
--no-tuito disable live panes and keep non-interactive streaming behavior - Pane output renders ANSI SGR colors/styles from tool output directly in the TUI
- Carriage-return updates (progress/spinner style output) are rendered as in-place line updates in focused panes
- Pane titles show
updatingwhile recent carriage-return updates are active - Press
qorCtrl-Cwhile TUI is visible to close only the TUI view - Use
Tab/Shift+Tab(or left/right arrows) to switch focused pane; usej/k, up/down, page up/down, home/end to scroll focused output - After the TUI view closes, pressing
Ctrl-Ccancels running tools and exits clippier - After tools complete, clippier exits the TUI and prints full sectioned raw output as usual
Supported Tools
| Tool | Language/Format | Capabilities | Detection |
|---|---|---|---|
rustfmt |
Rust | Format | cargo in PATH |
clippy |
Rust | Lint | cargo in PATH |
taplo |
TOML | Format, Lint | taplo binary |
prettier |
JS/TS/JSON/MD/YAML/etc. | Format | prettier from explicit path, local bin, PATH, or bunx/pnpm/npx fallback |
biome |
JS/TS/JSON | Format, Lint | biome from explicit path, local bin, PATH, or bunx/pnpm/npx fallback |
eslint |
JS/TS | Lint | eslint from explicit path, local bin, PATH, or bunx/pnpm/npx fallback |
dprint |
Multi-language | Format, Lint | dprint from explicit path, local bin, PATH, or bunx/pnpm/npx fallback |
clippier_md |
Markdown/MDX | Format | cargo run -p clippier_md -- fmt |
remark |
Markdown/MDX | Format | remark from explicit path, local bin, PATH, or bunx/pnpm/npx fallback |
mdformat |
Markdown | Format | mdformat binary, uvx fallback, or Nix ephemeral fallback |
yamlfmt |
YAML | Format | yamlfmt binary or Nix ephemeral fallback |
ruff |
Python | Format, Lint | ruff binary |
black |
Python | Format | black binary |
gofmt |
Go | Format | gofmt binary |
shfmt |
Shell | Format | shfmt binary |
shellcheck |
Shell | Lint | shellcheck binary |
Output Format (JSON)
CI Integration Example
name: Lint & Format Check
on:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install tools
run: |
cargo install clippier taplo-cli
npm install -g prettier
- name: Check formatting
run: clippier fmt --check
- name: Run linters
run: clippier check
Docker Deployment
Generate production-ready Dockerfiles with comprehensive dependency analysis:
# Generate Dockerfile for server package with all potential dependencies
Change Impact Analysis
Determine test scope based on changed files and external dependencies:
# Find affected packages from git changes including external deps
CHANGED=
Smart Workspace Dependency Management
Analyze workspace dependencies with different levels of detail:
# Get minimal dependencies for current features
# Get all potential dependencies for Docker builds
Workspace Toolchains
Aggregate toolchains and dependencies from all workspace packages for CI setup:
# Get aggregated toolchain information for CI setup
This command scans all packages in the workspace and collects their toolchains, dependencies, CI steps, and environment variables for the specified OS. Useful for workspace-level CI setup.
Output format:
Command Line Options
Common Command Options
These options are shared across multiple subcommands (they are not top-level global flags).
| Option | Description |
|---|---|
--output |
Output format: json, raw |
--workspace-type |
Workspace type to use: cargo, node (auto-detect if not specified) |
Features Command Options
| Option | Description | Default |
|---|---|---|
--os |
Target operating system | - |
--workspace-type |
Workspace type: cargo, node (auto-detect if not specified) |
Auto-detect |
--offset |
Skip first N features | 0 |
--max |
Maximum number of features | All |
--max-parallel |
Maximum parallel jobs | - |
--chunked |
Group features into chunks | - |
--spread |
Spread features across jobs | false |
--randomize |
Randomize features before chunking/spreading | false |
--seed |
Seed for deterministic randomization | - |
--features |
Features to include (supports wildcards *, ? and negation !) |
- |
--skip-features |
Features to exclude (supports wildcards *, ? and negation !) |
- |
--required-features |
Always-required features (supports wildcards *, ? and negation !) |
- |
--packages |
Packages to process (supports wildcards *, ? and negation !) |
All packages |
--changed-files |
Filter by changed files | - |
--git-base |
Git base commit for external dep analysis | - |
--git-head |
Git head commit for external dep analysis | - |
--skip-if |
Skip packages matching manifest filter | - |
--include-if |
Include only packages matching filter | - |
--ignore |
Glob patterns to ignore when detecting affected packages | - |
Packages Command Options
| Option | Description | Default |
|---|---|---|
--os |
Target operating system | ubuntu |
--workspace-type |
Workspace type: cargo, node (auto-detect if not specified) |
Auto-detect |
--packages |
Packages to include (supports wildcards *, ? and negation !) |
All packages |
--changed-files |
Filter by changed files | - |
--git-base |
Git base commit for change detection | - |
--git-head |
Git head commit for change detection | - |
--include-reasoning |
Include reasoning for affected packages | false |
--max-parallel |
Maximum number of packages to return | - |
--skip-if |
Skip packages matching manifest filter | - |
--include-if |
Include only packages matching filter | - |
--ignore |
Glob patterns to ignore when detecting affected packages | - |
--output |
Output format: json, raw |
json |
Workspace Dependencies Options
| Option | Description | Default |
|---|---|---|
--features |
Features to enable | - |
--format |
Output format: json, text |
text |
--all-potential-deps |
Include all potential dependencies | false |
Docker Generation Options
| Option | Description | Default |
|---|---|---|
--git-ref |
Git ref when workspace is a git URL | master |
--features |
Features to enable for target package | - |
--no-default-features |
Do not activate default features | false |
--base-image |
Docker builder image | rust:1-bookworm |
--final-image |
Docker runtime image | debian:bookworm-slim |
--build-args |
Cargo build arguments | - |
--generate-dockerignore |
Generate .dockerignore | true |
--env |
Runtime environment variables | - |
--build-env |
Build-time environment variables | - |
--arg |
Arguments to pass to binary | - |
--bin |
Specify binary name | Auto-detect |
Affected Packages Options
| Option | Description | Default |
|---|---|---|
--workspace-type |
Workspace type: cargo, node (auto-detect if not specified) |
Auto-detect |
--changed-files |
List of changed files | Required |
--target-package |
Specific package to check | - |
--git-base |
Git base commit for external dep analysis | - |
--git-head |
Git head commit for external dep analysis | - |
--ignore |
Glob patterns to ignore when detecting changes | - |
--output |
Output format: json, raw |
json |
Feature Validation Options
| Option | Description | Default |
|---|---|---|
--features |
Comma-separated list of features to validate | Auto-detect |
--skip-features |
Features to skip during validation (supports wildcards) | ["default", "_*"] |
--workspace-only |
Only validate workspace packages | true |
--output |
Output format: json, raw |
raw |
--path |
Workspace root path | Current directory |
--fail-on-error |
Exit with error code if validation fails | true |
--strict-optional |
Require dep?/feature syntax for optional deps |
false |
--allow-missing |
Allow specific missing propagations | - |
--allow-incorrect |
Allow specific incorrect propagations | - |
--ignore-package |
Suppress validation for specific packages | - |
--ignore-feature |
Suppress validation for specific features | - |
--use-config-overrides |
Load overrides from clippier.toml files | true |
--use-cargo-metadata-overrides |
Load overrides from Cargo.toml metadata | true |
--warn-expired |
Warn about expired overrides | true |
--fail-on-expired |
Fail validation if expired overrides exist | false |
--verbose-overrides |
Show detailed override information | false |
--parent-packages |
Packages to validate as parent packages | From config |
--parent-depth |
Max depth for nested dependency checking | None (unlimited) |
--parent-skip-features |
Additional features to skip for parent validation | - |
--parent-prefix |
Override prefix for dependencies (dep:prefix) |
Auto-inferred |
--no-parent-config |
Disable loading parent config from clippier.toml | false |
Workspace Toolchains Options
| Option | Description | Default |
|---|---|---|
--os |
Target operating system (required) | - |
--output |
Output format: json, raw |
json |
Check Command Options
| Option | Description | Default |
|---|---|---|
--working-dir |
Working directory to run in | Current directory |
--tools |
Specific tools to run (comma-separated) | All detected |
--list |
List available tools instead of running them | false |
--required |
Tools that MUST be installed (error if missing) | - |
--skip |
Tools to skip even if detected | - |
--color |
Color mode: auto, always, never |
auto |
--no-tui |
Disable real-time pane TUI output | false |
--no-runner-fallback |
Disable bunx/pnpm/npx fallback for tools | false |
--tool-path |
Override tool path (key=value, repeatable) |
- |
--biome-use-editorconfig |
Force Biome .editorconfig support |
false |
--no-biome-use-editorconfig |
Disable Biome .editorconfig support |
false |
--biome-use-vcs-ignore |
Force Biome VCS ignore semantics | false |
--no-biome-use-vcs-ignore |
Disable Biome VCS ignore semantics | false |
--output |
Output format: json, raw |
raw |
Fmt Command Options
| Option | Description | Default |
|---|---|---|
--working-dir |
Working directory to run in | Current directory |
--check |
Only check formatting without modifying files | false |
--tools |
Specific tools to run (comma-separated) | All detected |
--list |
List available tools instead of running them | false |
--required |
Tools that MUST be installed (error if missing) | - |
--skip |
Tools to skip even if detected | - |
--color |
Color mode: auto, always, never |
auto |
--no-tui |
Disable real-time pane TUI output | false |
--no-runner-fallback |
Disable bunx/pnpm/npx fallback for tools | false |
--tool-path |
Override tool path (key=value, repeatable) |
- |
--biome-use-editorconfig |
Force Biome .editorconfig support |
false |
--no-biome-use-editorconfig |
Disable Biome .editorconfig support |
false |
--biome-use-vcs-ignore |
Force Biome VCS ignore semantics | false |
--no-biome-use-vcs-ignore |
Disable Biome VCS ignore semantics | false |
--output |
Output format: json, raw |
raw |
Configuration
Clippier can be configured using clippier.toml files at two levels:
Workspace-Level Configuration
Place a clippier.toml at the workspace root to define defaults for all packages:
# {workspace_root}/clippier.toml
# Workspace-level defaults apply to all packages unless overridden
[]
= ["gofmt"]
= ["rustfmt", "taplo"]
# Rust-specific configuration (workspace-wide defaults)
[]
= false
= ["--locked"]
[]
= "1"
= "always"
# Default OS matrix for packages that do not define local [[config]] entries
[[]]
= "ubuntu"
[[]]
= "macos"
[[]]
= "windows"
[[]]
= "cargo fmt --check"
[[]]
= "sudo apt-get update"
[[]]
= "sudo apt-get install -y pkg-config libssl-dev"
Package-Level Configuration
Place a clippier.toml in individual package directories to override or extend workspace defaults:
# packages/{package}/clippier.toml
# Package-level config merges with workspace defaults.
# Local [[config]] entries replace the workspace default OS matrix for this package.
[]
= "custom_value"
# Root-level Rust config (applies to all OS configs unless overridden)
[]
= true
[[]]
= "ubuntu-latest"
# Per-OS Rust config using inline table
= { = ["simd"], = ["build", "test", "clippy"] }
[]
= "1"
= "always"
# System dependencies for Docker generation
[[]]
= "sudo apt-get update"
[[]]
= "sudo apt-get install -y pkg-config libssl-dev libasound2-dev"
# Feature-specific dependencies
[[]]
= "sudo apt-get install -y libsqlite3-dev"
= ["database"]
[[]]
= "windows"
# Skip certain features on Windows
= { = ["asio"] }
[]
= 4
Rust-Specific Configuration
Rust/Cargo-specific options are now namespaced under [rust] (workspace/package level) or rust = {...} (OS config level):
| Option | Description | Example |
|---|---|---|
nightly |
Use nightly toolchain | nightly = true |
cargo |
Cargo command arguments | cargo = ["--locked"] |
skip-features |
Features to skip in CI | skip-features = ["simd", "test-*"] |
required-features |
Features required for CI | required-features = ["production"] |
Examples:
# Workspace-level Rust config
[]
= false
= ["--locked"]
= ["dev", "test-*"]
# Per-OS config with Rust overrides
[[]]
= "ubuntu"
= { = true, = ["simd"] }
[[]]
= "windows"
= { = ["asio"] }
[[]]
= "macos"
# Uses workspace defaults (no rust override)
Node.js-Specific Configuration
Node.js-specific options are namespaced under [node] (workspace/package level) or node = {...} (OS config level):
| Option | Description | Example |
|---|---|---|
package-manager |
Preferred package manager | package-manager = "pnpm" |
node-version |
Node.js version to use | node-version = "20" |
skip-packages |
Packages to skip in CI | skip-packages = ["@myorg/deprecated-*"] |
args |
Additional package manager arguments | args = ["--frozen-lockfile"] |
Examples:
# Workspace-level Node config
[]
= "pnpm"
= "20"
= ["@myorg/deprecated-*"]
# Per-OS config with Node overrides
[[]]
= "ubuntu"
= { = "pnpm", = ["--frozen-lockfile"] }
[[]]
= "windows"
= { = "npm" }
Configuration Precedence
Configuration values are resolved in the following order (highest to lowest priority):
- Config-specific -
[[config]]section in package'sclippier.toml - Package-level - Top-level values in package's
clippier.toml - Workspace defaults - Values in workspace root
clippier.toml - Built-in defaults - Hardcoded fallback values
For matrix generation, package-local [[config]] entries are an override for workspace [[config]] entries. If a package has no local [[config]], Clippier uses the workspace root [[config]] entries. If neither exists, Clippier falls back to a single Ubuntu config.
Configuration Features
- Workspace-level defaults: Set organization-wide configuration once
- Package-level overrides: Customize specific packages as needed
- Feature-specific dependencies: Dependencies can be conditionally included based on enabled features
- Multiple OS configurations: Support for different operating systems
- Environment variable management: Configurable environment variables at workspace and package levels
- CI step customization: Custom CI pipeline steps
- Toolchain specification: Custom Rust toolchains per configuration
Advanced Package Filtering
Clippier supports powerful property-based filtering to include or exclude packages based on their Cargo.toml properties using --skip-if and --include-if flags.
Filter Syntax
Format: property[.nested]<operator>value
Filters can access any property in a package's Cargo.toml, including nested metadata.
Available Operators
Scalar Operators
Match against string, boolean, or integer values:
| Operator | Description | Example |
|---|---|---|
= |
Exact match | package.publish=false |
!= |
Not equal | package.version!=0.1.0 |
^= |
Starts with | package.name^=moosicbox_ |
$= |
Ends with | package.name$=_example |
*= |
Contains substring | package.description*=audio |
~= |
Regex match | package.name~=^moosicbox_.*_server$ |
Array Operators
Match against array properties (keywords, categories, authors, etc.):
| Operator | Description | Example |
|---|---|---|
@= |
Array contains exact element | package.categories@=audio |
@*= |
Array contains element with substring | package.keywords@*=music |
@^= |
Array contains element starting with | package.keywords@^=api- |
@~= |
Array contains element matching regex | package.categories@~=^multimedia |
@! |
Array is empty | package.keywords@! |
@#= |
Array length equals | package.keywords@#=3 |
@#> |
Array length greater than | package.authors@#>1 |
@#< |
Array length less than | package.categories@#<5 |
!@= |
Array does NOT contain | package.keywords!@=deprecated |
Existence Operators
Check if properties exist:
| Operator | Description | Example |
|---|---|---|
? |
Property exists | package.readme? |
!? |
Property does NOT exist | package.homepage!? |
Logical Operators and Expressions
You can combine multiple filter conditions using logical operators to create complex expressions:
| Operator | Description | Example |
|---|---|---|
AND |
Both conditions must be true | package.publish=false AND version^=0.1 |
OR |
At least one condition is true | package.publish=false OR name$=_example |
NOT |
Inverts the condition | NOT package.publish=false |
( ) |
Groups conditions for precedence | (package.publish=false OR package.name$=_test) AND package.version^=0.1 |
Operator Precedence (highest to lowest):
NOTANDOR
Case Insensitive: Keywords can be written as AND, and, And, etc.
Quoted Values: Use double quotes for values containing spaces or special characters:
package.name="my package"- Matches packages with spaces in namepackage.description="This AND that"- Quotes prevent "AND" from being treated as operator
Escape Sequences in quoted strings:
\"- Double quote\\- Backslash\n- Newline\t- Tab
Usage Examples
Skip Unpublished Packages
# Exclude packages with publish = false
Include Only Specific Package Prefixes
# Only process moosicbox packages
# Exclude example packages
Filter by Categories or Keywords
# Only packages with audio category
# Packages containing "api" in keywords
# Skip packages with empty keywords
Array Length Filtering
# Only packages with 3+ keywords (well-documented)
# Packages with exactly 2 categories
Nested Metadata Access
# Only independent workspace packages
# Skip packages with custom CI configuration
Combining Multiple Filters
Using separate filter arguments (OR logic for skip, AND logic for include):
# Include moosicbox packages, exclude examples and unpublished
# Audio packages with sufficient documentation
Using logical expressions within a single filter:
# Exclude examples OR unpublished packages
# Include published moosicbox packages that are NOT examples
# Complex: audio/video packages with good docs
# Skip test packages or packages with specific metadata
Filter Logic
Skip Filters (--skip-if):
- Multiple skip filter arguments use OR logic
- Each filter argument can be a complex expression with
AND,OR,NOT - If ANY skip filter matches, the package is excluded
- Processed after include filters
Include Filters (--include-if):
- Multiple include filter arguments use AND logic
- Each filter argument can be a complex expression with
AND,OR,NOT - ALL include filters must match for a package to be included
Expression Evaluation:
Within each filter argument:
ANDrequires both sides to be trueORrequires at least one side to be trueNOTinverts the result- Parentheses
()control precedence
Examples:
# Skip: Exclude if name ends with _example OR publish is false
# Equivalent to separate args: --skip-if "package.name$=_example" --skip-if "package.publish=false"
# Include: Must match name prefix AND (one of the categories)
# Complex: Skip unpublished non-library packages
# Multiple arguments with AND logic between them
# Both filters must match: name must start with moosicbox_ AND have audio category
Property Paths
Access any Cargo.toml property using dot notation with the full path:
package.name,package.version,package.edition- Standard package propertiespackage.publish,package.categories,package.keywords- Package metadatapackage.metadata.custom.field- Custom nested metadatadependencies.serde.version- Dependency informationfeatures.default- Feature configurationworkspace.members- Workspace configuration
Practical Use Cases
CI/CD Optimization
# Test only published, non-example packages
Monorepo Component Isolation
# Test only frontend packages (by naming convention)
# Backend services only
Documentation Quality Checks
# Find packages missing documentation
# Well-documented packages only
Dependency Auditing
# Packages with specific metadata flags
Use Cases
CI/CD Pipeline Generation
Generate feature matrices for GitHub Actions with intelligent change detection:
# Generate feature combinations for testing only affected packages
The --randomize flag shuffles features before chunking, creating different feature combinations across CI runs. This helps catch issues with various feature groupings that might not be discovered with deterministic chunking.
Reproducible CI Builds
For reproducible builds (useful for debugging specific feature combinations), use the --seed parameter:
# Generate reproducible feature combinations using a specific seed
This ensures the same feature distribution is generated every time, enabling reproduction of specific CI failures.
Selective Package Processing
Process specific packages in large workspaces:
# Generate feature matrix for specific packages only
# Useful for:
# - Development: Focus on packages you're actively working on
# - CI/CD: Create targeted test matrices
# - Performance: Reduce processing time for large workspaces
Combining with Change Detection
# Process specific packages AND filter by changes
When both --packages and --changed-files are specified:
- First filters to specified packages
- Then applies change detection within those packages
- Results in highly targeted feature matrices
Docker Deployment
Generate production-ready Dockerfiles with comprehensive dependency analysis:
# Generate Dockerfile for server package with all potential dependencies
Smart Workspace Dependency Management
Analyze workspace dependencies with different levels of detail:
# Get minimal dependencies for current features
# Get all potential dependencies for Docker builds
Core Functionality
- Feature Combination Generation: Creates combinations of Cargo features for testing
- Feature Propagation Validation: Ensures features are correctly propagated across workspace dependencies
- Workspace Dependency Analysis: Maps dependencies between workspace packages
- CI Configuration Generation: Produces CI/CD pipeline configurations
- Docker File Generation: Creates optimized multi-stage Dockerfiles
- Impact Analysis: Determines which packages are affected by code changes
- External Dependency Tracking: Monitors changes in external dependencies via git analysis
- Smart Filtering: Reduces test scope by analyzing only affected packages
- Selective Package Processing: Filter operations to specific packages for improved performance
Advanced Features
Selective Package Processing
The --packages flag enables targeted processing of specific workspace packages:
- Performance optimization: Process only relevant packages instead of entire workspace
- Development workflow: Focus on packages under active development
- CI/CD flexibility: Create custom test matrices for different components
- Monorepo management: Handle subsets of large multi-package repositories
Example workflow for package groups:
# Frontend packages
# Backend services
# Core libraries
Package names should match exactly as defined in Cargo.toml files. For packages with prefixes (e.g., moosicbox_server), use the full name.
External Dependency Analysis
When the git-diff feature is enabled (default), Clippier can:
- Parse Cargo.lock changes: Detect version updates in external dependencies
- Map external to internal dependencies: Understand which workspace packages use which external dependencies
- Provide comprehensive impact analysis: Include both file-based and dependency-based changes
- Optimize CI/CD pipelines: Test only packages actually affected by changes
Intelligent Docker Generation
The Docker generation feature provides:
- System dependency detection: Automatically includes required system packages
- Multi-stage optimization: Separates build and runtime environments
- Layer caching optimization: Structures Dockerfiles for maximum cache efficiency
- Feature-aware builds: Includes only dependencies needed for specified features
- Comprehensive dependency inclusion: Uses
--all-potential-depsmode for build compatibility
Workspace Relationship Mapping
- Dependency graph generation: Complete workspace dependency mapping
- Circular dependency detection: identify problematic dependency cycles
- Build order optimization: Determine optimal build sequences
- Feature dependency resolution: Handle complex feature interactions
Output Formats
JSON Output
Structured data suitable for programmatic processing:
For affected packages analysis:
For feature validation results:
Raw/Text Output
Human-readable text format for direct use in scripts:
server
auth
database
Package Selection Examples
Development Workflow
Focus on packages you're actively developing:
# Working on authentication system
# Testing database layer changes
CI/CD Pipeline with Package Groups
name: Component Testing
on:
workflow_dispatch:
inputs:
component:
description: 'Component to test'
required: true
type: choice
options:
- frontend
- backend
- core
jobs:
test-component:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set package list
id: packages
run: |
case "${{ github.event.inputs.component }}" in
frontend)
echo "list=ui,web,app" >> $GITHUB_OUTPUT
;;
backend)
echo "list=server,api,auth" >> $GITHUB_OUTPUT
;;
core)
echo "list=core,utils,common" >> $GITHUB_OUTPUT
;;
esac
- name: Generate test matrix
run: |
clippier features . \
--packages "${{ steps.packages.outputs.list }}" \
--max 10 \
--output json
Performance Comparison
# Full workspace analysis (slow for large workspaces)
# Targeted package analysis (much faster)
# Measure the improvement
Integration Examples
GitHub Actions Workflow with Smart Change Detection
name: CI
on:
jobs:
analyze-changes:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.matrix.outputs.matrix }}
analysis-method: ${{ steps.analysis.outputs.method }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build clippier
run: cargo build --release --package clippier
- name: Validate feature propagation
run: |
./target/release/clippier validate-feature-propagation . \
--features "fail-on-warnings"
- name: Analyze changes and generate matrix
id: analysis
run: |
# Get changed files
CHANGED_FILES=$(git diff --name-only ${{ github.event.before }}..${{ github.sha }} | tr '\n' ',' | sed 's/,$//')
# Use enhanced analysis if Cargo.lock changed
if echo "$CHANGED_FILES" | grep -q "Cargo.lock"; then
echo "method=hybrid" >> $GITHUB_OUTPUT
matrix=$(./target/release/clippier features Cargo.toml \
--changed-files "$CHANGED_FILES" \
--git-base "${{ github.event.before }}" \
--git-head "${{ github.sha }}" \
--max 15 --output json)
else
echo "method=file-based" >> $GITHUB_OUTPUT
matrix=$(./target/release/clippier features Cargo.toml \
--changed-files "$CHANGED_FILES" \
--max 15 --output json)
fi
echo "matrix=$matrix" >> $GITHUB_OUTPUT
test:
needs: analyze-changes
if: needs.analyze-changes.outputs.matrix != '[]'
strategy:
matrix: ${{ fromJson(needs.analyze-changes.outputs.matrix) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Test with features (${{ needs.analyze-changes.outputs.analysis-method }})
run: cargo test --package ${{ matrix.name }} --features "${{ matrix.features }}"
Docker Build Pipeline with Dependency Optimization
#!/bin/bash
# Generate optimized Dockerfiles for all binary packages
PACKAGES=("server" "tunnel-server" "load-balancer")
for; do
# Show dependency analysis
# Generate Dockerfile
done
Advanced Change Analysis Script
#!/bin/bash
# Comprehensive change impact analysis
BASE_COMMIT=
HEAD_COMMIT=
# Get changed files
CHANGED_FILES=
# Analyze affected packages
if | ; then
AFFECTED=
else
AFFECTED=
fi
# Validate feature propagation before testing
if ! ; then
fi
# Generate test matrix for affected packages only
MATRIX=
Feature Validation in CI Pipeline
#!/bin/bash
# Comprehensive feature validation script for CI/CD
# First, validate that fail-on-warnings is properly propagated
if ! ; then
fi
# Auto-detect and validate all features that might need propagation
VALIDATION_RESULT=
ERRORS=
if [; then
|
else
VALID_PACKAGES=
fi
Best Practices
Feature Propagation Validation
-
Run in CI/CD pipelines: Catch propagation issues early before they cause build failures
# In your CI pipeline -
Use auto-detection mode: Finds all features that might need propagation across your workspace
# Discovers features that exist in multiple packages -
Validate after adding dependencies: Ensure new workspace dependencies don't break feature propagation
# Quick check after adding a new workspace dependency -
Use workspace-only mode: Focus validation on packages you control, excluding external dependencies
# Avoids false positives from external dependencies -
Document required features: Make feature propagation requirements explicit in your workspace
# In Cargo.toml, document why features are propagated [] = [ "dep_a/fail-on-warnings", # Required for consistent builds "dep_b?/fail-on-warnings", # Optional dep - only when enabled ]
Package Selection Best Practices
-
Use exact package names: Specify packages exactly as they appear in Cargo.toml
# Correct # Incorrect (unless packages are actually named this way) -
Combine with other filters for precision: Layer multiple filters for targeted analysis
-
Use in CI/CD for component testing: Create separate workflows for different components
# Test only affected services -
Performance optimization for large workspaces: Process packages in groups
# Process in batches for very large workspaces BATCH1="pkg1,pkg2,pkg3,pkg4,pkg5" BATCH2="pkg6,pkg7,pkg8,pkg9,pkg10"
General Workspace Management
- Regular dependency analysis: Run
workspace-depsto understand your dependency graph - Impact-driven testing: Use
affected-packagesto optimize CI runs - Feature matrix optimization: Use
--changed-filesto test only what matters - Docker build optimization: Use
--all-potential-depsfor complete build contexts
Troubleshooting
Feature Validation Issues
"Feature not found" errors:
- Ensure the feature exists in at least one workspace package
- Check spelling and case sensitivity in feature names
- Use auto-detection mode to see which features are available
Too many false positives:
- Use
--workspace-onlyto exclude external dependencies - Specify exact features with
--featuresinstead of auto-detection - Check that external dependencies actually need the features
Missing optional dependency syntax:
- Use
dep?/featuresyntax for optional dependencies - Ensure the dependency is marked as
optional = truein Cargo.toml - Verify the optional dependency actually has the feature you're propagating
CI/CD integration issues:
- Use
--output jsonfor programmatic output parsing - Use
--fail-on-errorto control exit codes in CI pipelines - Verify the clippier binary is built and available in the workflow
Performance issues with large workspaces:
- Use
--featuresto validate specific features instead of auto-detection - Consider
--workspace-onlyto reduce scope - Run validation in parallel with other CI steps
Package Selection Issues
"Package not found" warnings:
- Verify package names match exactly as in Cargo.toml
- Check for typos or incorrect prefixes
- Use
cargo metadatato list all workspace packages - Remember packages are case-sensitive
Empty results with --packages:
- Ensure packages exist in the workspace
- Check that packages have Cargo.toml files
- Verify workspace members list includes the packages
- Try without --packages flag to see all available packages
Combining --packages with --changed-files:
- Both filters are applied (packages AND changes)
- May result in empty set if no changes affect selected packages
- Use one or the other for broader results
- Check package paths match changed file paths
General Troubleshooting
Command not found errors:
- Ensure clippier is built:
cargo build --release --package clippier - Check the binary path:
./target/release/clippier - Verify you're in the workspace root directory
Git-related errors (external dependency analysis):
- Ensure git history is available (use
fetch-depth: 0in GitHub Actions) - Check that base and head commits exist
- Verify you have the
git-difffeature enabled (default)
JSON parsing errors:
- Verify JSON output with
jqor similar tools - Check for proper shell escaping in CI environments
- Ensure output is captured correctly in scripts
Quick Reference
Feature Skip Patterns (Wildcards & Negation)
# Wildcard patterns
# Negation patterns (skip all except)
# Complex combinations
# In configuration files
Pattern Syntax:
*- Matches zero or more characters?- Matches exactly one character!pattern- Negation (excludes matching items from the result set)- Supported in:
--features,--skip-features,--required-features,--packages - Patterns evaluated left-to-right
Feature Inclusion Patterns (--features)
# Include all features starting with enable-
# Include multiple wildcard patterns
# Mix wildcards with exact names
# Use negation to include all except specific features
# Include enable-* except enable-experimental
# Combine with skip-features for precise control
Note: --features expands wildcards to include matching features. Supports negation with ! prefix to exclude specific patterns.
Required Features Patterns (--required-features)
# Require all features starting with enable-
# Require multiple wildcard patterns
# Mix wildcards with exact names
# Use negation to require enable-* except enable-experimental
Note: Wildcards and negations are expanded to concrete feature names in the JSON output. This is metadata that gets included for downstream consumers.
Output example:
Package Selection Patterns (--packages)
# Include all packages starting with moosicbox_
# Include all server packages
# Mix wildcards with exact names
# Use negation to include all except test packages
# Include all server packages except test servers
# Select specific API packages
Note: --packages supports negation with ! prefix to exclude specific packages from the selection.
Property-Based Filter Syntax
# Scalar operators
# Array operators
# Existence operators
# Nested properties
# Combining filters
Packages Command Patterns
# List all workspace packages
# List packages for specific OS
# Filter to specific packages
# Property-based filtering
# Only packages affected by changes
# Only packages affected by git changes
# Combined with max parallel limit
# Raw output (package names only)
Common Package Selection Patterns (Features Command)
# Single package
# Multiple packages (exact names)
# Wildcard patterns - all packages with prefix
# Wildcard patterns - all server packages
# Wildcard patterns - all API packages
# Mix wildcards with exact names
# Combined with OS filter
# Combined with feature wildcards
# Combined with all wildcard features (comprehensive example)
# Combined with change detection
# With chunking for CI
# For Docker generation
# For affected packages
See Also
- MoosicBox Server - Example of complex workspace package
- Cargo Workspaces - Rust workspace documentation
- GitHub Actions - CI/CD platform integration
- Docker Multi-stage Builds - Docker optimization techniques