From ddd2cb47f2aa1c06ec4fcfe7525b03f8d713ce9a Mon Sep 17 00:00:00 2001 From: bdbch Date: Fri, 22 May 2026 22:11:49 +0200 Subject: [PATCH] feat(cli): improve output formatting with aligned columns and unicode arrows - Version bumps now shown in aligned columns (left-aligned names, right-aligned versions) - Status output shows filenames instead of full paths - Private bump_type_str made pub for use in status output --- .oxrls/5e41-wavy-wagon.md | 5 +++++ src/bump.rs | 22 ++++++++++++---------- src/main.rs | 29 ++++++++++++++++++++++------- 3 files changed, 39 insertions(+), 17 deletions(-) create mode 100644 .oxrls/5e41-wavy-wagon.md diff --git a/.oxrls/5e41-wavy-wagon.md b/.oxrls/5e41-wavy-wagon.md new file mode 100644 index 0000000..e174a0b --- /dev/null +++ b/.oxrls/5e41-wavy-wagon.md @@ -0,0 +1,5 @@ +--- +"@bdbchgg/oxrls": "patch" +--- + +Improve CLI output formatting with aligned columns and unicode arrows \ No newline at end of file diff --git a/src/bump.rs b/src/bump.rs index 4d9b80a..efd40dd 100644 --- a/src/bump.rs +++ b/src/bump.rs @@ -689,14 +689,16 @@ pub fn apply_release_plan( /// Print the release plan without making changes. pub fn print_plan(plan: &ReleasePlan) { + let max_name = plan.bumps.values().map(|b| b.package_name.len()).max().unwrap_or(20); println!("Bumped packages:"); for (_name, bump) in &plan.bumps { println!( - " {} {} -> {} ({})", + " {:12} -> {:<12} ({})", bump.package_name, - bump.old_version, - bump.new_version, - bump.bump_type_str() + bump.old_version.to_string(), + bump.new_version.to_string(), + bump.bump_type_str(), + width = max_name ); } @@ -754,7 +756,7 @@ pub fn find_release_files(release_dir: &Path) -> Result> { } impl PlannedBump { - fn bump_type_str(&self) -> &str { + pub fn bump_type_str(&self) -> &str { match self.bump_type { BumpType::Patch => "patch", BumpType::Minor => "minor", @@ -1079,7 +1081,7 @@ Breaking change."#; let plan = build_release_plan(&workspace, &config, &release_dir, false).unwrap(); let core = plan.bumps.get("@scope/core").unwrap(); - // Major bump from 1.2.3 → 2.0.0-rc.1 + // Major bump from 1.2.3 -> 2.0.0-rc.1 assert_eq!(core.new_version.to_string(), "1.2.3-rc.1"); assert_eq!(core.old_version.to_string(), "1.2.3"); } @@ -1159,7 +1161,7 @@ Fix bug."#; let utils = plan.bumps.get("@scope/utils").unwrap(); assert_eq!(core.new_version, utils.new_version); - // Highest old version is @scope/core 1.2.3, patched → 1.2.4 + // Highest old version is @scope/core 1.2.3, patched -> 1.2.4 assert_eq!(core.new_version, semver::Version::new(1, 2, 4)); assert_eq!(utils.new_version, semver::Version::new(1, 2, 4)); } @@ -1245,7 +1247,7 @@ Add feature."#; // Both should be minor bumps assert_eq!(core.bump_type, BumpType::Minor); assert_eq!(react.bump_type, BumpType::Minor); - // Core: 1.2.3 → 1.3.0, React: 1.0.0 → 1.1.0 + // Core: 1.2.3 -> 1.3.0, React: 1.0.0 -> 1.1.0 assert_eq!(core.new_version, semver::Version::new(1, 3, 0)); assert_eq!(react.new_version, semver::Version::new(1, 1, 0)); } @@ -1372,9 +1374,9 @@ Mixed changes for pre-release and stable."#; assert!(plan.bumps.contains_key("@scope/core")); assert!(plan.bumps.contains_key("@scope/react")); - // Core is in pre-mode → should have a pre-release version + // Core is in pre-mode -> should have a pre-release version assert!(plan.bumps.get("@scope/core").unwrap().new_version.to_string().contains("beta")); - // React is not in pre-mode → should have a normal version + // React is not in pre-mode -> should have a normal version assert!(!plan.bumps.get("@scope/react").unwrap().new_version.to_string().contains("beta")); // Apply the release plan diff --git a/src/main.rs b/src/main.rs index 530d224..5b9811d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -237,11 +237,11 @@ fn cmd_status() -> Result<()> { for file_path in &files { match parse_release_file(file_path) { Ok(rf) => { - println!(" {}", rf.path.display()); + let fname = file_path.file_name().map(|n| n.to_string_lossy()).unwrap_or_default(); + println!(" {}", fname); for (pkg, bump) in &rf.releases { println!(" {} {}", pkg, bump); } - println!(); } Err(e) => { eprintln!(" ERROR parsing {}: {}", file_path.display(), e); @@ -252,14 +252,18 @@ fn cmd_status() -> Result<()> { // Show calculated bumps match build_release_plan(&workspace, &config, &release_dir, true) { Ok(plan) => { - println!("Calculated bumps:\n"); + let max_name = plan.bumps.values().map(|b| b.package_name.len()).max().unwrap_or(20); + println!("Calculated bumps:"); for (_name, bump) in &plan.bumps { println!( - " {} {} -> {}", - bump.package_name, bump.old_version, bump.new_version + " {:12} → {:<12} ({})", + bump.package_name, + bump.old_version.to_string(), + bump.new_version.to_string(), + bump.bump_type_str(), + width = max_name ); } - if !plan.internal_dep_updates.is_empty() { println!("\nInternal dependency updates:\n"); for update in &plan.internal_dep_updates { @@ -294,7 +298,18 @@ fn cmd_bump(dry_run: bool, archive: bool) -> Result<()> { return Ok(()); } - println!("Bumped packages:\n"); + println!("Bumped packages:"); + let max_name = plan.bumps.values().map(|b| b.package_name.len()).max().unwrap_or(20); + for (_name, bump) in &plan.bumps { + println!( + " {:12} → {:<12} ({})", + bump.package_name, + bump.old_version.to_string(), + bump.new_version.to_string(), + bump.bump_type_str(), + width = max_name + ); + } let plan_clone = plan.clone(); apply_release_plan(&workspace, &plan, &config, &release_dir, false, archive)?; -- 2.51.2