Add baseline command for migration cleanup#13
Conversation
Adds the `migrate baseline <version>` command which marks a specific version as the baseline, allowing old migration files to be deleted while preserving history. Also adds `--baseline` and `--keep` flags to the `up` command. - Add src/baseline.rs for baseline file management - Add src/commands/baseline.rs for CLI command - Update status and up commands to respect baselines - Update documentation in README.md and CLAUDE.md - Bump version to 0.4.0 (new feature) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reorganize documentation to follow the natural migration workflow: creating, writing, applying, checking status, and baselining. Add practical guidance on when to use each feature and what happens under the hood. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| let is_baselined = baseline | ||
| .as_ref() | ||
| .is_some_and(|b| extract_version(&migration.id) <= Some(b.version.clone())); |
There was a problem hiding this comment.
🟡 Malformed migration IDs incorrectly marked as baselined due to Option comparison
In the status command, when checking if a migration is baselined, the code compares extract_version(&migration.id) <= Some(b.version.clone()). The extract_version function returns None for malformed migration IDs (those that don't have a dash at position 5).
Click to expand
Issue Details
In Rust, None < Some(_) is always true due to how Option ordering works. This means if a migration ID in the .history file is malformed (e.g., manually edited), the comparison None <= Some(baseline_version) would evaluate to true, causing that migration to be incorrectly displayed with the (baseline) marker.
// src/commands/status.rs:91-93
let is_baselined = baseline
.as_ref()
.is_some_and(|b| extract_version(&migration.id) <= Some(b.version.clone()));The extract_version function at lines 123-129 returns None when the ID doesn't match the expected format:
fn extract_version(id: &str) -> Option<String> {
if id.len() >= 5 && id.chars().nth(5) == Some('-') {
Some(id[..5].to_string())
} else {
None
}
}Impact
This is a display-only bug affecting the migrate status output. It doesn't affect actual migration behavior or data integrity.
Recommendation: Change the comparison to handle the None case explicitly, e.g., extract_version(&migration.id).map_or(false, |v| v <= b.version)
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
Adds the
migrate baseline <version>command which marks a specific version as the baseline, allowing old migration files to be deleted while preserving history. This enables migration cleanup and reduces repository bloat over time.migrate baseline <version>command to mark versions as applied--baselineand--keepflags onmigrate upfor inline baselining.baselinefile tracks baseline version and optional summaryTest plan
🤖 Generated with Claude Code