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

Commit 6656ff4

Browse files
author
Hendrik van Antwerpen
committed
Add analyze flags to aid debugging and profiling
1 parent b7c2a0d commit 6656ff4

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

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

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use stack_graphs::graph::StackGraph;
1313
use stack_graphs::partial::PartialPaths;
1414
use stack_graphs::stitching::Database;
1515
use std::collections::HashMap;
16+
use std::io::Write;
1617
use std::path::Path;
1718
use std::path::PathBuf;
1819
use std::sync::Arc;
@@ -45,6 +46,16 @@ pub struct AnalyzeArgs {
4546
)]
4647
pub source_paths: Vec<PathBuf>,
4748

49+
/// Continue analysis from the given file
50+
#[clap(
51+
long,
52+
value_name = "SOURCE_PATH",
53+
value_hint = ValueHint::AnyPath,
54+
parse(from_os_str),
55+
validator_os = path_exists,
56+
)]
57+
pub continue_from: Option<PathBuf>,
58+
4859
#[clap(long, short = 'v')]
4960
pub verbose: bool,
5061

@@ -55,18 +66,28 @@ pub struct AnalyzeArgs {
5566
parse(try_from_str = duration_from_seconds_str),
5667
)]
5768
pub max_file_time: Option<Duration>,
69+
70+
/// Wait for user input before starting analysis. Useful for profiling.
71+
#[clap(long)]
72+
pub wait_at_start: bool,
5873
}
5974

6075
impl AnalyzeArgs {
6176
pub fn new(source_paths: Vec<PathBuf>) -> Self {
6277
Self {
6378
source_paths,
79+
continue_from: None,
6480
verbose: false,
6581
max_file_time: None,
82+
wait_at_start: false,
6683
}
6784
}
6885

6986
pub fn run(&self, loader: &mut Loader) -> anyhow::Result<()> {
87+
if self.wait_at_start {
88+
self.wait_for_input()?;
89+
}
90+
let mut seen_mark = false;
7091
for source_path in &self.source_paths {
7192
if source_path.is_dir() {
7293
let source_root = source_path;
@@ -77,24 +98,41 @@ impl AnalyzeArgs {
7798
.filter(|e| e.file_type().is_file())
7899
{
79100
let source_path = source_entry.path();
80-
self.analyze_file_with_context(source_root, source_path, loader)?;
101+
self.analyze_file_with_context(
102+
source_root,
103+
source_path,
104+
loader,
105+
&mut seen_mark,
106+
)?;
81107
}
82108
} else {
83109
let source_root = source_path.parent().unwrap();
84-
self.analyze_file_with_context(source_root, source_path, loader)?;
110+
if self.skip(source_path, &mut seen_mark) {
111+
continue;
112+
}
113+
self.analyze_file_with_context(source_root, source_path, loader, &mut seen_mark)?;
85114
}
86115
}
87116
Ok(())
88117
}
89118

119+
fn wait_for_input(&self) -> anyhow::Result<()> {
120+
print!("<press ENTER to continue>");
121+
std::io::stdout().flush()?;
122+
let mut input = String::new();
123+
std::io::stdin().read_line(&mut input)?;
124+
Ok(())
125+
}
126+
90127
/// Analyze file and add error context to any failures that are returned.
91128
fn analyze_file_with_context(
92129
&self,
93130
source_root: &Path,
94131
source_path: &Path,
95132
loader: &mut Loader,
133+
seen_mark: &mut bool,
96134
) -> anyhow::Result<()> {
97-
self.analyze_file(source_root, source_path, loader)
135+
self.analyze_file(source_root, source_path, loader, seen_mark)
98136
.with_context(|| format!("Error analyzing file {}", source_path.display()))
99137
}
100138

@@ -103,9 +141,15 @@ impl AnalyzeArgs {
103141
source_root: &Path,
104142
source_path: &Path,
105143
loader: &mut Loader,
144+
seen_mark: &mut bool,
106145
) -> anyhow::Result<()> {
107146
let mut file_status = FileStatusLogger::new(source_path, self.verbose);
108147

148+
if self.skip(source_path, seen_mark) {
149+
file_status.info("skipped")?;
150+
return Ok(());
151+
}
152+
109153
let mut file_reader = FileReader::new();
110154
let lc = match loader.load_for_file(source_path, &mut file_reader, &NoCancellation) {
111155
Ok(Some(sgl)) => sgl,
@@ -192,4 +236,19 @@ impl AnalyzeArgs {
192236
file_status.ok("success")?;
193237
Ok(())
194238
}
239+
240+
fn skip(&self, path: &Path, seen_mark: &mut bool) -> bool {
241+
if *seen_mark {
242+
false
243+
} else if let Some(mark) = &self.continue_from {
244+
if path != mark {
245+
true
246+
} else {
247+
*seen_mark = true;
248+
false
249+
}
250+
} else {
251+
false
252+
}
253+
}
195254
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ impl<'a> FileStatusLogger<'a> {
189189
Ok(())
190190
}
191191

192+
pub fn info(&mut self, status: &str) -> Result<(), anyhow::Error> {
193+
self.print_path(true)?;
194+
println!("{}", status.dimmed());
195+
self.path_logged = false;
196+
Ok(())
197+
}
198+
192199
pub fn warn(&mut self, status: &str) -> Result<(), anyhow::Error> {
193200
self.print_path(true)?;
194201
println!("{}", status.yellow());

0 commit comments

Comments
 (0)