Skip to content

Commit 4edda04

Browse files
committed
cargo-rail:
feat: safety and correctness improvements Affected/Test correctness: - Handle deletes/renames/copies in change detection (git diff --name-status) - Fix file-to-crate mapping for paths that no longer exist Config validation: - Add --strict/--no-strict flags for CI vs local behavior (ugly, but important) - Auto strict in CI environments (GITHUB_ACTIONS, etc.) - Validate unknown keys and surface parse errors before WorkspaceContext Release safety: - Replace `cargo update --workspace` with targeted `--package <crate>` updates - Refuse release from detached HEAD - Require --yes flag when releasing from non-default branch
1 parent 8130c95 commit 4edda04

File tree

17 files changed

+1229
-176
lines changed

17 files changed

+1229
-176
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<a href="https://crates.io/crates/cargo-rail"><img src="https://img.shields.io/crates/v/cargo-rail.svg" alt="Crates.io"></a>
1313
<a href="https://crates.io/crates/cargo-rail"><img src="https://img.shields.io/crates/d/cargo-rail.svg" alt="Downloads"></a>
1414
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
15-
<a href="https://www.rust-lang.org"><img src="https://img.shields.io/badge/rust-1.92.0%2B-orange.svg" alt="Rust 1.92.0+"></a>
15+
<a href="https://www.rust-lang.org"><img src="https://img.shields.io/badge/rust-1.91.0%2B-orange.svg" alt="Rust 1.91.0+"></a>
1616
</p>
1717

1818
<p align="center">
@@ -130,6 +130,7 @@ What it does:
130130
- **Unifies versions** based on Cargo's resolver output
131131
- **Computes MSRV** from the dependency graph
132132
- **Prunes dead features** that are never enabled
133+
- **Fixes undeclared features** that don't exist on the dependency
133134
- **Detects unused deps** (opt-in)
134135
- **Pins transitives** — replaces `cargo-hakari` without a workspace-hack crate
135136

docs/commands.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,8 @@ Examples:
703703
```
704704
Validate the configuration file
705705
706+
Checks for parse errors, unknown keys, and semantic issues. By default, unknown keys warn locally but error in CI environments (detected via CI, GITHUB_ACTIONS, GITLAB_CI, or CIRCLECI env vars).
707+
706708
Usage: cargo rail config validate [OPTIONS]
707709
708710
Options:
@@ -726,6 +728,12 @@ Options:
726728
--json
727729
Output in JSON format (shorthand for -f json)
728730
731+
--strict
732+
Treat warnings as errors (auto-enabled in CI)
733+
734+
--no-strict
735+
Never treat warnings as errors (overrides CI auto-detection)
736+
729737
-h, --help
730738
Print help (see a summary with '-h')
731739

docs/config.md

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -675,23 +675,49 @@ paths = [{ crate = "crates/server" }]
675675

676676
## Validation
677677

678-
cargo-rail validates configuration on load:
678+
cargo-rail provides comprehensive configuration validation via `cargo rail config validate`:
679679

680680
```bash
681-
# Check configuration validity
682-
cargo rail init --check
681+
cargo rail config validate # Validate rail.toml
682+
cargo rail config validate --strict # Treat warnings as errors
683+
cargo rail config validate --no-strict # Force warnings-only mode
684+
cargo rail config validate -f json # JSON output for CI integration
685+
```
686+
687+
### What Gets Validated
688+
689+
1. **Syntax** - TOML parse errors with line/column information
690+
2. **Unknown keys** - Typos like `mrsv_source` instead of `msrv_source`
691+
3. **Semantic validation** - Split config requirements, target triple formats
692+
4. **Deprecation warnings** - Future-proofing for config migrations
693+
694+
### CI Auto-Strict Mode
695+
696+
By default, validation runs in **strict mode** when CI is detected (via `CI`, `GITHUB_ACTIONS`, `GITLAB_CI`, or `CIRCLECI` environment variables):
683697

684-
# Commands will error on invalid config
685-
cargo rail unify # Validates config before running
698+
- **In CI**: Unknown keys and other warnings become errors (exit code 2)
699+
- **Locally**: Unknown keys are warnings only
700+
701+
Override with `--strict` or `--no-strict` flags.
702+
703+
### Example CI Usage
704+
705+
```yaml
706+
# .github/workflows/ci.yml
707+
- name: Validate config
708+
run: cargo rail config validate
709+
# Auto-strict in CI - fails on unknown keys
686710
```
687711

688-
Common validation errors:
712+
### Common Validation Errors
689713

690-
- **Invalid glob patterns** in `change-detection`
691-
- **Single mode with multiple paths** in split config
692-
- **Combined mode with one path** in split config
693-
- **Empty remote** in split config
694-
- **Unknown crate names** in `skip_changelog_for`
714+
| Error | Cause |
715+
|-------|-------|
716+
| TOML parse error at line X | Syntax error (missing quotes, invalid structure) |
717+
| Unknown top-level key 'foo' | Typo in section name |
718+
| Unknown key 'bar' in [unify] | Typo in field name or deprecated option |
719+
| Missing required field: remote | Split config without remote URL |
720+
| 'foo' doesn't look like a valid target | Target triple missing architecture separator |
695721

696722
## Migration
697723

src/commands/cli.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,20 @@ pub enum Commands {
298298
#[derive(Subcommand)]
299299
pub enum ConfigCommand {
300300
/// Validate the configuration file
301+
///
302+
/// Checks for parse errors, unknown keys, and semantic issues.
303+
/// By default, unknown keys warn locally but error in CI environments
304+
/// (detected via CI, GITHUB_ACTIONS, GITLAB_CI, or CIRCLECI env vars).
301305
Validate {
302306
/// Output format
303307
#[arg(long, short = 'f', default_value_t, value_enum)]
304308
format: OutputFormat,
309+
/// Treat warnings as errors (auto-enabled in CI)
310+
#[arg(long, conflicts_with = "no_strict")]
311+
strict: bool,
312+
/// Never treat warnings as errors (overrides CI auto-detection)
313+
#[arg(long, conflicts_with = "strict")]
314+
no_strict: bool,
305315
},
306316
/// Sync configuration: add missing fields and update targets
307317
///
@@ -396,6 +406,9 @@ pub enum ReleaseCommand {
396406
/// Skip git tag creation
397407
#[arg(long)]
398408
skip_tag: bool,
409+
/// Skip confirmation prompts and allow non-default branch
410+
#[arg(short = 'y', long)]
411+
yes: bool,
399412
/// Output format
400413
#[arg(long, short = 'f', default_value_t, value_enum)]
401414
format: OutputFormat,
@@ -441,7 +454,7 @@ impl Commands {
441454
ReleaseCommand::Run { format, .. } | ReleaseCommand::Check { format, .. } => format.is_json_like(),
442455
},
443456
Commands::Config { command } => match command {
444-
ConfigCommand::Validate { format } | ConfigCommand::Sync { format, .. } => format.is_json_like(),
457+
ConfigCommand::Validate { format, .. } | ConfigCommand::Sync { format, .. } => format.is_json_like(),
445458
},
446459
_ => false,
447460
}
@@ -463,7 +476,7 @@ impl Commands {
463476
} => *format = OutputFormat::Json,
464477
Commands::Release { .. } => {}
465478
Commands::Config { command } => match command {
466-
ConfigCommand::Validate { format } | ConfigCommand::Sync { format, .. } => *format = OutputFormat::Json,
479+
ConfigCommand::Validate { format, .. } | ConfigCommand::Sync { format, .. } => *format = OutputFormat::Json,
467480
},
468481
_ => {}
469482
}

0 commit comments

Comments
 (0)