Skip to content

Commit 22506a5

Browse files
authored
Merge pull request #163 from williamjameshandley/feature/stdout-quiet-output
Add stdout output and quiet mode support
2 parents cc2eb20 + 578f915 commit 22506a5

File tree

3 files changed

+94
-47
lines changed

3 files changed

+94
-47
lines changed

crates/code2prompt-core/src/template.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,27 +68,37 @@ pub fn render_template(
6868
Ok(rendered.trim().to_string())
6969
}
7070

71-
/// Writes the rendered template to a specified output file.
71+
/// Writes the rendered template to a specified output file or stdout.
7272
///
7373
/// # Arguments
7474
///
75-
/// * `output_path` - The path to the output file.
75+
/// * `output_path` - The path to the output file, or "-" for stdout.
7676
/// * `rendered` - The rendered template string.
77+
/// * `quiet` - If true, suppress success messages.
7778
///
7879
/// # Returns
7980
///
8081
/// * `Result<()>` - An empty result indicating success or an error.
81-
pub fn write_to_file(output_path: &str, rendered: &str) -> Result<()> {
82-
let file = std::fs::File::create(output_path)?;
83-
let mut writer = std::io::BufWriter::new(file);
84-
write!(writer, "{}", rendered)?;
85-
println!(
86-
"{}{}{} {}",
87-
"[".bold().white(),
88-
"✓".bold().green(),
89-
"]".bold().white(),
90-
format!("Prompt written to file: {}", output_path).green()
91-
);
82+
pub fn write_to_file(output_path: &str, rendered: &str, quiet: bool) -> Result<()> {
83+
if output_path == "-" {
84+
// Write to stdout
85+
print!("{}", rendered);
86+
std::io::stdout().flush()?;
87+
} else {
88+
// Write to file
89+
let file = std::fs::File::create(output_path)?;
90+
let mut writer = std::io::BufWriter::new(file);
91+
write!(writer, "{}", rendered)?;
92+
if !quiet {
93+
println!(
94+
"{}{}{} {}",
95+
"[".bold().white(),
96+
"✓".bold().green(),
97+
"]".bold().white(),
98+
format!("Prompt written to file: {}", output_path).green()
99+
);
100+
}
101+
}
92102
Ok(())
93103
}
94104

crates/code2prompt/src/args.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ pub struct Cli {
9898
#[clap(long)]
9999
pub sort: Option<String>,
100100

101+
/// Suppress progress and success messages
102+
#[clap(short, long)]
103+
pub quiet: bool,
104+
101105
/// Display a visual token map of files (similar to disk usage tools)
102106
#[clap(long)]
103107
pub token_map: bool,

crates/code2prompt/src/main.rs

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ fn main() -> Result<()> {
3434
std::process::exit(1);
3535
}
3636

37+
// Disable clipboard when outputting to stdout (unless clipboard is explicitly enabled)
38+
let no_clipboard = args.no_clipboard ||
39+
args.output_file.as_ref().map_or(false, |f| f == "-");
40+
3741
// ~~~ Clipboard Daemon ~~~
3842
#[cfg(target_os = "linux")]
3943
{
@@ -122,51 +126,73 @@ fn main() -> Result<()> {
122126

123127
// ~~~ Code2Prompt ~~~
124128
let mut session = Code2PromptSession::new(configuration.build()?);
125-
let spinner = setup_spinner("Traversing directory and building tree...");
129+
let spinner = if !args.quiet {
130+
Some(setup_spinner("Traversing directory and building tree..."))
131+
} else {
132+
None
133+
};
126134

127135
// ~~~ Gather Repository Data ~~~
128136
// Load Codebase
129137
session.load_codebase().unwrap_or_else(|e| {
130-
spinner.finish_with_message("Failed!".red().to_string());
138+
if let Some(ref s) = spinner {
139+
s.finish_with_message("Failed!".red().to_string());
140+
}
131141
error!("Failed to build directory tree: {}", e);
132142
std::process::exit(1);
133143
});
134-
spinner.finish_with_message("Done!".green().to_string());
144+
if let Some(ref s) = spinner {
145+
s.finish_with_message("Done!".green().to_string());
146+
}
135147

136148
// ~~~ Git Related ~~~
137149
// Git Diff
138150
if session.config.diff_enabled {
139-
spinner.set_message("Generating git diff...");
151+
if let Some(ref s) = spinner {
152+
s.set_message("Generating git diff...");
153+
}
140154
session.load_git_diff().unwrap_or_else(|e| {
141-
spinner.finish_with_message("Failed!".red().to_string());
155+
if let Some(ref s) = spinner {
156+
s.finish_with_message("Failed!".red().to_string());
157+
}
142158
error!("Failed to generate git diff: {}", e);
143159
std::process::exit(1);
144160
});
145161
}
146162

147163
// Load Git diff between branches if provided
148164
if session.config.diff_branches.is_some() {
149-
spinner.set_message("Generating git diff between two branches...");
165+
if let Some(ref s) = spinner {
166+
s.set_message("Generating git diff between two branches...");
167+
}
150168
session
151169
.load_git_diff_between_branches()
152170
.unwrap_or_else(|e| {
153-
spinner.finish_with_message("Failed!".red().to_string());
171+
if let Some(ref s) = spinner {
172+
s.finish_with_message("Failed!".red().to_string());
173+
}
154174
error!("Failed to generate git diff: {}", e);
155175
std::process::exit(1);
156176
});
157177
}
158178

159179
// Load Git log between branches if provided
160180
if session.config.log_branches.is_some() {
161-
spinner.set_message("Generating git log between two branches...");
181+
if let Some(ref s) = spinner {
182+
s.set_message("Generating git log between two branches...");
183+
}
162184
session.load_git_log_between_branches().unwrap_or_else(|e| {
163-
spinner.finish_with_message("Failed!".red().to_string());
185+
if let Some(ref s) = spinner {
186+
s.finish_with_message("Failed!".red().to_string());
187+
}
164188
error!("Failed to generate git log: {}", e);
165189
std::process::exit(1);
166190
});
167191
}
168192

169-
spinner.finish_with_message("Done!".green().to_string());
193+
if let Some(ref s) = spinner {
194+
s.finish_with_message("Done!".green().to_string());
195+
}
170196

171197
// ~~~ Template ~~~
172198

@@ -192,14 +218,16 @@ fn main() -> Result<()> {
192218
};
193219
let model_info = rendered.model_info;
194220

195-
println!(
196-
"{}{}{} Token count: {}, Model info: {}",
197-
"[".bold().white(),
198-
"i".bold().blue(),
199-
"]".bold().white(),
200-
formatted_token_count,
201-
model_info
202-
);
221+
if !args.quiet {
222+
println!(
223+
"{}{}{} Token count: {}, Model info: {}",
224+
"[".bold().white(),
225+
"i".bold().blue(),
226+
"]".bold().white(),
227+
formatted_token_count,
228+
model_info
229+
);
230+
}
203231

204232
// ~~~ Token Map Display ~~~
205233
if args.token_map {
@@ -241,7 +269,7 @@ fn main() -> Result<()> {
241269
}
242270

243271
// ~~~ Copy to Clipboard ~~~
244-
if !args.no_clipboard {
272+
if !no_clipboard {
245273
#[cfg(target_os = "linux")]
246274
{
247275
use clipboard::spawn_clipboard_daemon;
@@ -252,22 +280,27 @@ fn main() -> Result<()> {
252280
use crate::clipboard::copy_text_to_clipboard;
253281
match copy_text_to_clipboard(&rendered.prompt) {
254282
Ok(_) => {
255-
println!(
256-
"{}{}{} {}",
257-
"[".bold().white(),
258-
"✓".bold().green(),
259-
"]".bold().white(),
260-
"Copied to clipboard successfully.".green()
261-
);
283+
if !args.quiet {
284+
println!(
285+
"{}{}{} {}",
286+
"[".bold().white(),
287+
"✓".bold().green(),
288+
"]".bold().white(),
289+
"Copied to clipboard successfully.".green()
290+
);
291+
}
262292
}
263293
Err(e) => {
264-
eprintln!(
265-
"{}{}{} {}",
266-
"[".bold().white(),
267-
"!".bold().red(),
268-
"]".bold().white(),
269-
format!("Failed to copy to clipboard: {}", e).red()
270-
);
294+
if !args.quiet {
295+
eprintln!(
296+
"{}{}{} {}",
297+
"[".bold().white(),
298+
"!".bold().red(),
299+
"]".bold().white(),
300+
format!("Failed to copy to clipboard: {}", e).red()
301+
);
302+
}
303+
// Always print the prompt if clipboard fails, regardless of quiet mode
271304
println!("{}", &rendered.prompt);
272305
}
273306
}
@@ -276,7 +309,7 @@ fn main() -> Result<()> {
276309

277310
// ~~~ Output File ~~~
278311
if let Some(output_path) = &args.output_file {
279-
write_to_file(output_path, &rendered.prompt)?;
312+
write_to_file(output_path, &rendered.prompt, args.quiet)?;
280313
}
281314

282315
Ok(())

0 commit comments

Comments
 (0)