Skip to content

Commit d37dbe3

Browse files
committed
finally fixed all the apply / undo / patch / diff bugs
1 parent 0e53e7f commit d37dbe3

File tree

24 files changed

+526
-516
lines changed

24 files changed

+526
-516
lines changed

refaktor-cli/src/apply.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ pub fn handle_apply(
1111
let result = apply_operation(plan_path, plan_id, commit, force, None)?;
1212
println!("{}", result);
1313
Ok(())
14-
}
14+
}

refaktor-cli/src/history.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ pub fn handle_history(limit: Option<usize>) -> Result<()> {
1111

1212
println!("{}", formatted);
1313
Ok(())
14-
}
14+
}

refaktor-cli/src/main.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ mod rename;
1414
mod status;
1515
mod undo;
1616

17-
1817
/// Smart search & replace for code and files with case-aware transformations
1918
#[derive(Parser, Debug)]
2019
#[command(name = "refaktor")]
@@ -115,6 +114,10 @@ enum Commands {
115114
#[arg(long, value_enum)]
116115
preview: Option<PreviewArg>,
117116

117+
/// Use fixed column widths for table output (useful in CI environments or other non-TTY use cases)
118+
#[arg(long)]
119+
fixed_table_width: bool,
120+
118121
/// Output path for the plan
119122
#[arg(long, default_value = ".refaktor/plan.json")]
120123
plan_out: PathBuf,
@@ -230,6 +233,10 @@ enum Commands {
230233
/// Preview output format (defaults from config if not specified)
231234
#[arg(long, value_enum)]
232235
preview: Option<PreviewArg>,
236+
237+
/// Use fixed column widths for table output (useful in CI environments or other non-TTY use cases)
238+
#[arg(long)]
239+
fixed_table_width: bool,
233240
},
234241

235242
/// Initialize refaktor in the current repository
@@ -459,6 +466,7 @@ fn main() {
459466
only_styles,
460467
exclude_match,
461468
preview,
469+
fixed_table_width,
462470
plan_out,
463471
dry_run,
464472
} => {
@@ -482,6 +490,7 @@ fn main() {
482490
only_styles,
483491
exclude_match,
484492
Some(format),
493+
fixed_table_width,
485494
plan_out,
486495
dry_run,
487496
use_color,
@@ -502,6 +511,7 @@ fn main() {
502511
only_styles,
503512
exclude_match,
504513
preview,
514+
fixed_table_width,
505515
} => {
506516
// Use preview format from CLI arg or config default
507517
let format = preview.map(std::convert::Into::into).unwrap_or_else(|| {
@@ -523,6 +533,7 @@ fn main() {
523533
only_styles,
524534
exclude_match,
525535
Some(format),
536+
fixed_table_width,
526537
PathBuf::from(".refaktor/plan.json"),
527538
true, // Always dry-run
528539
use_color,
@@ -622,8 +633,6 @@ fn main() {
622633
}
623634
}
624635

625-
626-
627636
fn is_refaktor_ignored() -> Result<bool> {
628637
// Check if .refaktor is already ignored in any ignore file
629638

refaktor-cli/src/plan.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,18 @@ pub fn handle_plan(
2121
only_styles: Vec<StyleArg>,
2222
exclude_match: Vec<String>,
2323
preview: Option<Preview>,
24+
fixed_table_width: bool,
2425
plan_out: PathBuf,
2526
dry_run: bool,
2627
use_color: bool,
2728
) -> Result<()> {
29+
// Validate that --fixed-table-width is only used with table preview
30+
if fixed_table_width && preview.is_some() && preview != Some(Preview::Table) {
31+
return Err(anyhow::anyhow!(
32+
"--fixed-table-width can only be used with --preview table"
33+
));
34+
}
35+
2836
// Convert CLI style args to core Style enum
2937
let exclude_styles: Vec<Style> = exclude_styles.into_iter().map(Into::into).collect();
3038
let include_styles: Vec<Style> = include_styles.into_iter().map(Into::into).collect();
@@ -57,9 +65,10 @@ pub fn handle_plan(
5765
Some(plan_out),
5866
preview_format,
5967
dry_run,
68+
fixed_table_width,
6069
use_color,
6170
)?;
6271

6372
println!("{}", result);
6473
Ok(())
65-
}
74+
}

refaktor-cli/src/redo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ pub fn handle_redo(id: &str) -> Result<()> {
55
let result = redo_operation(id, None)?;
66
println!("{}", result);
77
Ok(())
8-
}
8+
}

refaktor-cli/src/rename.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,4 @@ pub fn handle_rename(
7171
// Print the result
7272
println!("{}", result);
7373
Ok(())
74-
}
74+
}

refaktor-cli/src/status.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::PathBuf;
55
pub fn handle_status() -> Result<()> {
66
let refaktor_dir = PathBuf::from(".refaktor");
77
let status = get_status(&refaktor_dir).context("Failed to get status")?;
8-
8+
99
print!("{}", status.format());
1010
Ok(())
11-
}
11+
}

refaktor-cli/src/undo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ pub fn handle_undo(id: &str) -> Result<()> {
55
let result = undo_operation(id, None)?;
66
println!("{}", result);
77
Ok(())
8-
}
8+
}

refaktor-cli/tests/cli_tests.rs

Lines changed: 101 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,23 @@ fn test_plan_command_basic() {
4343
"old_name",
4444
"new_name",
4545
vec![temp_dir.path().to_path_buf()], // paths
46-
vec![], // include
47-
vec![], // exclude
48-
true, // respect_gitignore
49-
0, // unrestricted_level
50-
true, // rename_files
51-
true, // rename_dirs
52-
vec![], // exclude_styles
53-
vec![], // include_styles
54-
vec![], // only_styles
55-
vec![], // exclude_match
56-
None, // plan_out
57-
Some("table".to_string()), // preview_format
58-
true, // dry_run
59-
false, // use_color
60-
).unwrap();
46+
vec![], // include
47+
vec![], // exclude
48+
true, // respect_gitignore
49+
0, // unrestricted_level
50+
true, // rename_files
51+
true, // rename_dirs
52+
vec![], // exclude_styles
53+
vec![], // include_styles
54+
vec![], // only_styles
55+
vec![], // exclude_match
56+
None, // plan_out
57+
Some("table".to_string()), // preview_format
58+
true, // dry_run
59+
true, // fixed_table_width - for consistent test output
60+
false, // use_color
61+
)
62+
.unwrap();
6163

6264
// Verify the result contains the table content
6365
assert!(result.contains("test.rs"));
@@ -76,21 +78,23 @@ fn test_plan_command_with_styles() {
7678
"old-name",
7779
"new-name",
7880
vec![temp_dir.path().to_path_buf()], // paths
79-
vec![], // include
80-
vec![], // exclude
81-
true, // respect_gitignore
82-
0, // unrestricted_level
83-
true, // rename_files
84-
true, // rename_dirs
81+
vec![], // include
82+
vec![], // exclude
83+
true, // respect_gitignore
84+
0, // unrestricted_level
85+
true, // rename_files
86+
true, // rename_dirs
8587
vec![Style::Kebab, Style::Pascal, Style::ScreamingSnake], // exclude_styles
86-
vec![], // include_styles
87-
vec![], // only_styles
88-
vec![], // exclude_match
89-
None, // plan_out
90-
Some("table".to_string()), // preview_format
91-
true, // dry_run
92-
false, // use_color
93-
).unwrap();
88+
vec![], // include_styles
89+
vec![], // only_styles
90+
vec![], // exclude_match
91+
None, // plan_out
92+
Some("table".to_string()), // preview_format
93+
true, // dry_run
94+
true, // fixed_table_width - for consistent test output
95+
false, // use_color
96+
)
97+
.unwrap();
9498

9599
// Verify the result contains the table content
96100
assert!(result.contains("test.rs"));
@@ -101,21 +105,23 @@ fn test_plan_command_with_styles() {
101105
"old-name",
102106
"new-name",
103107
vec![temp_dir.path().to_path_buf()], // paths
104-
vec![], // include
105-
vec![], // exclude
106-
true, // respect_gitignore
107-
0, // unrestricted_level
108-
true, // rename_files
109-
true, // rename_dirs
110-
vec![], // exclude_styles
111-
vec![Style::Title, Style::Train], // include_styles
112-
vec![], // only_styles
113-
vec![], // exclude_match
114-
None, // plan_out
115-
Some("table".to_string()), // preview_format
116-
true, // dry_run
117-
false, // use_color
118-
).unwrap();
108+
vec![], // include
109+
vec![], // exclude
110+
true, // respect_gitignore
111+
0, // unrestricted_level
112+
true, // rename_files
113+
true, // rename_dirs
114+
vec![], // exclude_styles
115+
vec![Style::Title, Style::Train], // include_styles
116+
vec![], // only_styles
117+
vec![], // exclude_match
118+
None, // plan_out
119+
Some("table".to_string()), // preview_format
120+
true, // dry_run
121+
true, // fixed_table_width - for consistent test output
122+
false, // use_color
123+
)
124+
.unwrap();
119125

120126
assert!(result2.contains("test.rs"));
121127
}
@@ -1230,15 +1236,22 @@ fn test_undo_after_rename() {
12301236

12311237
// Now undo the operation
12321238
let mut cmd = Command::cargo_bin("refaktor").unwrap();
1233-
let output = cmd.current_dir(temp_dir.path())
1239+
let output = cmd
1240+
.current_dir(temp_dir.path())
12341241
.args(["undo", id])
12351242
.assert()
12361243
.success()
12371244
.get_output()
12381245
.clone();
1239-
1240-
eprintln!("DEBUG test_undo_after_rename undo stdout: {}", String::from_utf8_lossy(&output.stdout));
1241-
eprintln!("DEBUG test_undo_after_rename undo stderr: {}", String::from_utf8_lossy(&output.stderr));
1246+
1247+
eprintln!(
1248+
"DEBUG test_undo_after_rename undo stdout: {}",
1249+
String::from_utf8_lossy(&output.stdout)
1250+
);
1251+
eprintln!(
1252+
"DEBUG test_undo_after_rename undo stderr: {}",
1253+
String::from_utf8_lossy(&output.stderr)
1254+
);
12421255

12431256
// Verify files are back to original state
12441257
let test_rs_content = std::fs::read_to_string(temp_dir.path().join("test.rs")).unwrap();
@@ -1268,28 +1281,58 @@ fn test_undo_latest() {
12681281

12691282
// Verify the rename was applied correctly
12701283
let content_after_rename = std::fs::read_to_string(temp_dir.path().join("test.rs")).unwrap();
1271-
eprintln!("DEBUG test_undo_latest: content after rename = {:?}", content_after_rename);
1272-
assert!(content_after_rename.contains("bar"), "Expected 'bar' in content after rename: {:?}", content_after_rename);
1273-
assert!(!content_after_rename.contains("foo"), "Did not expect 'foo' in content after rename: {:?}", content_after_rename);
1274-
assert!(!content_after_rename.ends_with('\n'), "Expected no trailing newline after rename: {:?}", content_after_rename);
1284+
eprintln!(
1285+
"DEBUG test_undo_latest: content after rename = {:?}",
1286+
content_after_rename
1287+
);
1288+
assert!(
1289+
content_after_rename.contains("bar"),
1290+
"Expected 'bar' in content after rename: {:?}",
1291+
content_after_rename
1292+
);
1293+
assert!(
1294+
!content_after_rename.contains("foo"),
1295+
"Did not expect 'foo' in content after rename: {:?}",
1296+
content_after_rename
1297+
);
1298+
assert!(
1299+
!content_after_rename.ends_with('\n'),
1300+
"Expected no trailing newline after rename: {:?}",
1301+
content_after_rename
1302+
);
12751303

12761304
// Undo using "latest"
12771305
let mut cmd = Command::cargo_bin("refaktor").unwrap();
1278-
let output = cmd.current_dir(temp_dir.path())
1306+
let output = cmd
1307+
.current_dir(temp_dir.path())
12791308
.args(["undo", "latest"])
12801309
.assert()
12811310
.success()
12821311
.get_output()
12831312
.clone();
1284-
1285-
eprintln!("DEBUG undo stdout: {}", String::from_utf8_lossy(&output.stdout));
1286-
eprintln!("DEBUG undo stderr: {}", String::from_utf8_lossy(&output.stderr));
1313+
1314+
eprintln!(
1315+
"DEBUG undo stdout: {}",
1316+
String::from_utf8_lossy(&output.stdout)
1317+
);
1318+
eprintln!(
1319+
"DEBUG undo stderr: {}",
1320+
String::from_utf8_lossy(&output.stderr)
1321+
);
12871322

12881323
// Verify revert
12891324
let content = std::fs::read_to_string(temp_dir.path().join("test.rs")).unwrap();
12901325
eprintln!("DEBUG test_undo_latest: actual content = {:?}", content);
1291-
assert!(content.contains("foo"), "Expected 'foo' in content: {:?}", content);
1292-
assert!(!content.contains("bar"), "Did not expect 'bar' in content: {:?}", content);
1326+
assert!(
1327+
content.contains("foo"),
1328+
"Expected 'foo' in content: {:?}",
1329+
content
1330+
);
1331+
assert!(
1332+
!content.contains("bar"),
1333+
"Did not expect 'bar' in content: {:?}",
1334+
content
1335+
);
12931336
}
12941337

12951338
#[test]

0 commit comments

Comments
 (0)