@@ -3,25 +3,25 @@ use crate::transformers::custom_format_to_resource;
33
44use langcodec:: Codec ;
55use std:: fs:: File ;
6- use std:: io:: Write ;
6+ use std:: io:: { self , Write } ;
77
88/// Run the debug command: read a localization file and output as JSON.
99pub fn run_debug_command ( input : String , lang : Option < String > , output : Option < String > ) {
1010 // Read the input file
11- println ! ( "Reading input file..." ) ;
11+ eprintln ! ( "Reading input file..." ) ;
1212 let mut codec = Codec :: new ( ) ;
1313 // Try standard format first
1414 if let Ok ( ( ) ) = codec. read_file_by_extension ( & input, lang. clone ( ) ) {
1515 // Standard format succeeded
1616 } else if input. ends_with ( ".json" ) || input. ends_with ( ".yaml" ) || input. ends_with ( ".yml" ) {
1717 // Try custom format for JSON/YAML files
1818 if let Err ( e) = try_custom_format_debug ( & input, lang. clone ( ) , & mut codec) {
19- println ! ( "❌ Error reading input file" ) ;
19+ eprintln ! ( "❌ Error reading input file" ) ;
2020 eprintln ! ( "Error reading {}: {}" , input, e) ;
2121 std:: process:: exit ( 1 ) ;
2222 }
2323 } else {
24- println ! ( "❌ Error reading input file" ) ;
24+ eprintln ! ( "❌ Error reading input file" ) ;
2525 // Provide a hint about encoding issues for common Apple .strings files
2626 eprintln ! (
2727 "Error reading {}: unsupported format or invalid text encoding" ,
@@ -31,56 +31,78 @@ pub fn run_debug_command(input: String, lang: Option<String>, output: Option<Str
3131 }
3232
3333 // Validate the codec using the new validation method
34- println ! ( "Validating resources..." ) ;
34+ eprintln ! ( "Validating resources..." ) ;
3535 if let Err ( validation_error) = codec. validate ( ) {
36- println ! ( "⚠️ Validation warnings found" ) ;
36+ eprintln ! ( "⚠️ Validation warnings found" ) ;
3737 eprintln ! ( "Warning: {}" , validation_error) ;
3838 // Continue anyway for debug purposes
3939 } else {
40- println ! ( "✅ Resources validated successfully" ) ;
40+ eprintln ! ( "✅ Resources validated successfully" ) ;
4141 }
4242
4343 // Convert to JSON
44- println ! ( "Converting to JSON..." ) ;
44+ eprintln ! ( "Converting to JSON..." ) ;
4545 let json = serde_json:: to_string_pretty ( & * codec. resources ) . unwrap_or_else ( |e| {
46- println ! ( "❌ Error serializing to JSON" ) ;
46+ eprintln ! ( "❌ Error serializing to JSON" ) ;
4747 eprintln ! ( "Error serializing to JSON: {}" , e) ;
4848 std:: process:: exit ( 1 ) ;
4949 } ) ;
5050
5151 // Output to file or stdout
5252 let output_to_file = match output {
5353 Some ( output_path) => {
54- println ! ( "Writing output file..." ) ;
54+ eprintln ! ( "Writing output file..." ) ;
5555 if let Err ( e) =
5656 File :: create ( & output_path) . and_then ( |mut f| f. write_all ( json. as_bytes ( ) ) )
5757 {
58- println ! ( "❌ Error writing output file" ) ;
58+ eprintln ! ( "❌ Error writing output file" ) ;
5959 eprintln ! ( "Error writing to {}: {}" , output_path, e) ;
6060 std:: process:: exit ( 1 ) ;
6161 }
62- println ! ( "✅ Debug output written to: {}" , output_path) ;
62+ eprintln ! ( "✅ Debug output written to: {}" , output_path) ;
6363 true
6464 }
6565 None => {
66- println ! ( "✅ Debug output:" ) ;
67- println ! ( "{}" , json) ;
66+ // Write marker + JSON to stdout and gracefully handle Broken Pipe
67+ let mut stdout = io:: stdout ( ) . lock ( ) ;
68+ if let Err ( e) = stdout. write_all ( "✅ Debug output:\n " . as_bytes ( ) ) {
69+ if e. kind ( ) == io:: ErrorKind :: BrokenPipe {
70+ std:: process:: exit ( 0 ) ;
71+ }
72+ eprintln ! ( "Error writing to stdout: {}" , e) ;
73+ std:: process:: exit ( 1 ) ;
74+ }
75+ if let Err ( e) = stdout. write_all ( json. as_bytes ( ) ) {
76+ if e. kind ( ) == io:: ErrorKind :: BrokenPipe {
77+ // Downstream closed the pipe (e.g., `| head`). Exit quietly.
78+ std:: process:: exit ( 0 ) ;
79+ }
80+ eprintln ! ( "Error writing to stdout: {}" , e) ;
81+ std:: process:: exit ( 1 ) ;
82+ }
83+ if let Err ( e) = stdout. flush ( ) {
84+ if e. kind ( ) == io:: ErrorKind :: BrokenPipe {
85+ std:: process:: exit ( 0 ) ;
86+ }
87+ eprintln ! ( "Error flushing stdout: {}" , e) ;
88+ std:: process:: exit ( 1 ) ;
89+ }
6890 false
6991 }
7092 } ;
7193
7294 // Show additional debug information using the new high-level methods
7395 if !output_to_file {
74- println ! ( "\n === Debug Summary ===" ) ;
75- println ! (
96+ eprintln ! ( "\n === Debug Summary ===" ) ;
97+ eprintln ! (
7698 "Languages: {}" ,
7799 codec. languages( ) . collect:: <Vec <_>>( ) . join( ", " )
78100 ) ;
79- println ! ( "Total entries: {}" , codec. all_keys( ) . count( ) ) ;
101+ eprintln ! ( "Total entries: {}" , codec. all_keys( ) . count( ) ) ;
80102
81103 for lang in codec. languages ( ) {
82104 let count = codec. entry_count ( lang) ;
83- println ! ( " {}: {} entries" , lang, count) ;
105+ eprintln ! ( " {}: {} entries" , lang, count) ;
84106 }
85107 }
86108}
0 commit comments