Skip to content

Commit e171052

Browse files
Add stdout output and quiet mode support
- Add support for '-' as output filename to write to stdout (UNIX convention) - Add --quiet/-q flag to suppress progress and success messages - Automatically disable clipboard when outputting to stdout - Update write_to_file function to handle stdout and quiet mode Fixes #115 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 9f71f06 commit e171052

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
#[arg(long, hide = true)]
102106
pub clipboard_daemon: bool,
103107
}

crates/code2prompt/src/main.rs

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

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

121125
// ~~~ Code2Prompt ~~~
122126
let mut session = Code2PromptSession::new(configuration.build()?);
123-
let spinner = setup_spinner("Traversing directory and building tree...");
127+
let spinner = if !args.quiet {
128+
Some(setup_spinner("Traversing directory and building tree..."))
129+
} else {
130+
None
131+
};
124132

125133
// ~~~ Gather Repository Data ~~~
126134
// Load Codebase
127135
session.load_codebase().unwrap_or_else(|e| {
128-
spinner.finish_with_message("Failed!".red().to_string());
136+
if let Some(ref s) = spinner {
137+
s.finish_with_message("Failed!".red().to_string());
138+
}
129139
error!("Failed to build directory tree: {}", e);
130140
std::process::exit(1);
131141
});
132-
spinner.finish_with_message("Done!".green().to_string());
142+
if let Some(ref s) = spinner {
143+
s.finish_with_message("Done!".green().to_string());
144+
}
133145

134146
// ~~~ Git Related ~~~
135147
// Git Diff
136148
if session.config.diff_enabled {
137-
spinner.set_message("Generating git diff...");
149+
if let Some(ref s) = spinner {
150+
s.set_message("Generating git diff...");
151+
}
138152
session.load_git_diff().unwrap_or_else(|e| {
139-
spinner.finish_with_message("Failed!".red().to_string());
153+
if let Some(ref s) = spinner {
154+
s.finish_with_message("Failed!".red().to_string());
155+
}
140156
error!("Failed to generate git diff: {}", e);
141157
std::process::exit(1);
142158
});
143159
}
144160

145161
// Load Git diff between branches if provided
146162
if session.config.diff_branches.is_some() {
147-
spinner.set_message("Generating git diff between two branches...");
163+
if let Some(ref s) = spinner {
164+
s.set_message("Generating git diff between two branches...");
165+
}
148166
session
149167
.load_git_diff_between_branches()
150168
.unwrap_or_else(|e| {
151-
spinner.finish_with_message("Failed!".red().to_string());
169+
if let Some(ref s) = spinner {
170+
s.finish_with_message("Failed!".red().to_string());
171+
}
152172
error!("Failed to generate git diff: {}", e);
153173
std::process::exit(1);
154174
});
155175
}
156176

157177
// Load Git log between branches if provided
158178
if session.config.log_branches.is_some() {
159-
spinner.set_message("Generating git log between two branches...");
179+
if let Some(ref s) = spinner {
180+
s.set_message("Generating git log between two branches...");
181+
}
160182
session.load_git_log_between_branches().unwrap_or_else(|e| {
161-
spinner.finish_with_message("Failed!".red().to_string());
183+
if let Some(ref s) = spinner {
184+
s.finish_with_message("Failed!".red().to_string());
185+
}
162186
error!("Failed to generate git log: {}", e);
163187
std::process::exit(1);
164188
});
165189
}
166190

167-
spinner.finish_with_message("Done!".green().to_string());
191+
if let Some(ref s) = spinner {
192+
s.finish_with_message("Done!".green().to_string());
193+
}
168194

169195
// ~~~ Template ~~~
170196

@@ -190,17 +216,19 @@ fn main() -> Result<()> {
190216
};
191217
let model_info = rendered.model_info;
192218

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

202230
// ~~~ Copy to Clipboard ~~~
203-
if !args.no_clipboard {
231+
if !no_clipboard {
204232
#[cfg(target_os = "linux")]
205233
{
206234
use clipboard::spawn_clipboard_daemon;
@@ -211,22 +239,27 @@ fn main() -> Result<()> {
211239
use crate::clipboard::copy_text_to_clipboard;
212240
match copy_text_to_clipboard(&rendered.prompt) {
213241
Ok(_) => {
214-
println!(
215-
"{}{}{} {}",
216-
"[".bold().white(),
217-
"✓".bold().green(),
218-
"]".bold().white(),
219-
"Copied to clipboard successfully.".green()
220-
);
242+
if !args.quiet {
243+
println!(
244+
"{}{}{} {}",
245+
"[".bold().white(),
246+
"✓".bold().green(),
247+
"]".bold().white(),
248+
"Copied to clipboard successfully.".green()
249+
);
250+
}
221251
}
222252
Err(e) => {
223-
eprintln!(
224-
"{}{}{} {}",
225-
"[".bold().white(),
226-
"!".bold().red(),
227-
"]".bold().white(),
228-
format!("Failed to copy to clipboard: {}", e).red()
229-
);
253+
if !args.quiet {
254+
eprintln!(
255+
"{}{}{} {}",
256+
"[".bold().white(),
257+
"!".bold().red(),
258+
"]".bold().white(),
259+
format!("Failed to copy to clipboard: {}", e).red()
260+
);
261+
}
262+
// Always print the prompt if clipboard fails, regardless of quiet mode
230263
println!("{}", &rendered.prompt);
231264
}
232265
}
@@ -235,7 +268,7 @@ fn main() -> Result<()> {
235268

236269
// ~~~ Output File ~~~
237270
if let Some(output_path) = &args.output_file {
238-
write_to_file(output_path, &rendered.prompt)?;
271+
write_to_file(output_path, &rendered.prompt, args.quiet)?;
239272
}
240273

241274
Ok(())

0 commit comments

Comments
 (0)