Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit 33c9e7f

Browse files
author
Hendrik van Antwerpen
committed
Cleanup file status logging
1 parent 30c5546 commit 33c9e7f

File tree

2 files changed

+81
-48
lines changed

2 files changed

+81
-48
lines changed

tree-sitter-stack-graphs/src/cli/analyze.rs

Lines changed: 26 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
// ------------------------------------------------------------------------------------------------
77

88
use anyhow::anyhow;
9+
use anyhow::Context as _;
910
use clap::Args;
1011
use clap::ValueHint;
11-
use colored::Colorize as _;
1212
use stack_graphs::graph::StackGraph;
1313
use stack_graphs::partial::PartialPaths;
1414
use stack_graphs::stitching::Database;
@@ -29,6 +29,8 @@ use crate::CancellationFlag;
2929
use crate::LoadError;
3030
use crate::NoCancellation;
3131

32+
use super::util::FileStatusLogger;
33+
3234
/// Analyze sources
3335
#[derive(Args)]
3436
pub struct AnalyzeArgs {
@@ -75,31 +77,25 @@ impl AnalyzeArgs {
7577
.filter(|e| e.file_type().is_file())
7678
{
7779
let source_path = source_entry.path();
78-
self.run_with_context(source_root, source_path, loader)?;
80+
self.analyze_file_with_context(source_root, source_path, loader)?;
7981
}
8082
} else {
8183
let source_root = source_path.parent().unwrap();
82-
self.run_with_context(source_root, source_path, loader)?;
84+
self.analyze_file_with_context(source_root, source_path, loader)?;
8385
}
8486
}
8587
Ok(())
8688
}
8789

88-
/// Run test file and add error context to any failures that are returned.
89-
fn run_with_context(
90+
/// Analyze file and add error context to any failures that are returned.
91+
fn analyze_file_with_context(
9092
&self,
9193
source_root: &Path,
9294
source_path: &Path,
9395
loader: &mut Loader,
9496
) -> anyhow::Result<()> {
95-
let result = self.analyze_file(source_root, source_path, loader);
96-
if result.is_err() {
97-
if !self.verbose {
98-
eprint!("{}: ", source_path.display());
99-
}
100-
eprintln!("{}", "error".red());
101-
}
102-
result
97+
self.analyze_file(source_root, source_path, loader)
98+
.with_context(|| format!("Error analyzing file {}", source_path.display()))
10399
}
104100

105101
fn analyze_file(
@@ -108,38 +104,31 @@ impl AnalyzeArgs {
108104
source_path: &Path,
109105
loader: &mut Loader,
110106
) -> anyhow::Result<()> {
111-
let mut cancellation_flag: Arc<dyn CancellationFlag> = Arc::new(NoCancellation);
112-
if let Some(max_file_time) = self.max_file_time {
113-
cancellation_flag = CancelAfterDuration::new(max_file_time);
114-
}
107+
let mut file_status = FileStatusLogger::new(source_path, self.verbose);
115108

116109
let source = std::fs::read_to_string(source_path)?;
117-
let lc = match loader.load_for_file(source_path, Some(&source), cancellation_flag.as_ref())
118-
{
110+
let lc = match loader.load_for_file(source_path, Some(&source), &NoCancellation) {
119111
Ok(Some(sgl)) => sgl,
120112
Ok(None) => return Ok(()),
121113
Err(crate::loader::LoadError::Cancelled(_)) => {
122-
eprintln!(
123-
"{}: {}",
124-
source_path.display(),
125-
"language loading timed out".yellow()
126-
);
114+
file_status.warn("language loading timed out")?;
127115
return Ok(());
128116
}
129-
Err(e) => {
130-
eprint!("{}: ", source_path.display());
131-
return Err(e.into());
132-
}
117+
Err(e) => return Err(e.into()),
133118
};
134119

135-
if self.verbose {
136-
eprint!("{}: ", source_path.display());
120+
let mut cancellation_flag: Arc<dyn CancellationFlag> = Arc::new(NoCancellation);
121+
if let Some(max_file_time) = self.max_file_time {
122+
cancellation_flag = CancelAfterDuration::new(max_file_time);
137123
}
138124

125+
file_status.processing()?;
126+
139127
let mut graph = StackGraph::new();
140-
let file = graph
141-
.add_file(&source_path.to_string_lossy())
142-
.map_err(|_| anyhow!("Duplicate file {}", source_path.display()))?;
128+
let file = match graph.add_file(&source_path.to_string_lossy()) {
129+
Ok(file) => file,
130+
Err(_) => return Err(anyhow!("Duplicate file {}", source_path.display())),
131+
};
143132

144133
let relative_source_path = source_path.strip_prefix(source_root).unwrap();
145134
let result = if let Some(fa) = source_path
@@ -168,18 +157,12 @@ impl AnalyzeArgs {
168157
match result {
169158
Err(LoadError::ParseErrors(parse_errors)) => {
170159
let parse_error = map_parse_errors(source_path, &parse_errors, &source, "");
171-
if !self.verbose {
172-
eprint!("{}: ", source_path.display());
173-
}
174-
eprintln!("{}", "parsing failed".red());
160+
file_status.error("parsing failed")?;
175161
eprintln!("{}", parse_error);
176162
return Ok(());
177163
}
178164
Err(LoadError::Cancelled(_)) => {
179-
if !self.verbose {
180-
eprint!("{}: ", source_path.display());
181-
}
182-
eprintln!("{}", "parsing timed out".yellow());
165+
file_status.warn("parsing timed out")?;
183166
return Ok(());
184167
}
185168
Err(e) => return Err(e.into()),
@@ -200,17 +183,12 @@ impl AnalyzeArgs {
200183
) {
201184
Ok(_) => {}
202185
Err(_) => {
203-
if !self.verbose {
204-
eprint!("{}: ", source_path.display());
205-
}
206-
eprintln!("{}", "path computation timed out".yellow());
186+
file_status.warn("path computation timed out")?;
207187
return Ok(());
208188
}
209189
}
210190

211-
if self.verbose {
212-
eprintln!("{}", "success".green());
213-
}
191+
file_status.ok("success")?;
214192
Ok(())
215193
}
216194
}

tree-sitter-stack-graphs/src/cli/util.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
// ------------------------------------------------------------------------------------------------
77

88
use anyhow::anyhow;
9+
use colored::Colorize;
910
use std::ffi::OsStr;
1011
use std::ffi::OsString;
12+
use std::io::Write;
1113
use std::path::Path;
1214
use std::path::PathBuf;
1315
use std::time::Duration;
@@ -157,3 +159,56 @@ pub fn map_parse_errors(
157159
pub fn duration_from_seconds_str(s: &str) -> Result<Duration, anyhow::Error> {
158160
Ok(Duration::new(s.parse()?, 0))
159161
}
162+
163+
pub struct FileStatusLogger<'a> {
164+
path: &'a Path,
165+
verbose: bool,
166+
path_logged: bool,
167+
}
168+
169+
impl<'a> FileStatusLogger<'a> {
170+
pub fn new(path: &'a Path, verbose: bool) -> Self {
171+
Self {
172+
path,
173+
verbose,
174+
path_logged: false,
175+
}
176+
}
177+
178+
pub fn processing(&mut self) -> Result<(), anyhow::Error> {
179+
self.print_path(false)?;
180+
Ok(())
181+
}
182+
183+
pub fn ok(&mut self, status: &str) -> Result<(), anyhow::Error> {
184+
self.print_path(false)?;
185+
if self.verbose {
186+
println!("{}", status.green());
187+
self.path_logged = false;
188+
}
189+
Ok(())
190+
}
191+
192+
pub fn warn(&mut self, status: &str) -> Result<(), anyhow::Error> {
193+
self.print_path(true)?;
194+
println!("{}", status.yellow());
195+
self.path_logged = false;
196+
Ok(())
197+
}
198+
199+
pub fn error(&mut self, status: &str) -> Result<(), anyhow::Error> {
200+
self.print_path(true)?;
201+
println!("{}", status.red());
202+
self.path_logged = false;
203+
Ok(())
204+
}
205+
206+
fn print_path(&mut self, force: bool) -> Result<(), anyhow::Error> {
207+
if (self.verbose || force) && !self.path_logged {
208+
print!("{}: ", self.path.display());
209+
std::io::stdout().flush()?;
210+
self.path_logged = true;
211+
}
212+
Ok(())
213+
}
214+
}

0 commit comments

Comments
 (0)