@@ -4,35 +4,65 @@ use std::path::{Path, PathBuf};
44
55use crate :: allocators:: { AllocatorKind , AllocatorLib } ;
66
7- /// Walk upward from current directory to find build directories.
7+ /// Walk upward and downward from current directory to find build directories.
88/// Returns all found build directories in order of preference.
99fn find_build_dirs ( ) -> Vec < PathBuf > {
1010 let mut dirs = Vec :: new ( ) ;
11- let Ok ( mut current_dir) = std:: env:: current_dir ( ) else {
11+ let Ok ( current_dir) = std:: env:: current_dir ( ) else {
1212 return dirs;
1313 } ;
1414
15- loop {
16- // Check for Cargo/Rust build directory
17- let cargo_analysis = current_dir. join ( "target" ) . join ( "codspeed" ) . join ( "analysis" ) ;
18- if cargo_analysis. is_dir ( ) {
19- dirs. push ( cargo_analysis) ;
15+ let patterns = [ "target/codspeed/analysis" , "bazel-bin" , "build" ] ;
16+ let mut check_patterns = |dir : & Path | {
17+ for pattern in & patterns {
18+ let path = dir. join ( pattern) ;
19+ if path. is_dir ( ) {
20+ dirs. push ( path) ;
21+ }
2022 }
23+ } ;
24+
25+ // Walk upward from current directory
26+ let mut current = current_dir. clone ( ) ;
27+ loop {
28+ check_patterns ( & current) ;
2129
22- // Check for Bazel build directory
23- let bazel_bin = current_dir. join ( "bazel-bin" ) ;
24- if bazel_bin. is_dir ( ) {
25- dirs. push ( bazel_bin) ;
30+ if !current. pop ( ) {
31+ break ;
2632 }
33+ }
2734
28- // Check for CMake build directory
29- let cmake_build = current_dir. join ( "build" ) ;
30- if cmake_build. is_dir ( ) {
31- dirs. push ( cmake_build) ;
35+ // Walk downward from current directory
36+ let mut stack = vec ! [ ( current_dir, 0 ) ] ;
37+ while let Some ( ( dir, depth) ) = stack. pop ( ) {
38+ const MAX_SEARCH_DEPTH : usize = 4 ;
39+ if depth > MAX_SEARCH_DEPTH {
40+ continue ;
3241 }
42+ check_patterns ( & dir) ;
3343
34- if !current_dir. pop ( ) {
35- break ;
44+ // Read subdirectories
45+ let Ok ( entries) = fs:: read_dir ( & dir) else {
46+ continue ;
47+ } ;
48+
49+ for entry in entries. filter_map ( Result :: ok) {
50+ let path = entry. path ( ) ;
51+
52+ let Some ( name) = path. file_name ( ) . and_then ( |n| n. to_str ( ) ) else {
53+ continue ;
54+ } ;
55+
56+ // Skip hidden dirs and common excludes
57+ if name. starts_with ( '.' ) || matches ! ( name, "node_modules" | "vendor" | "venv" ) {
58+ continue ;
59+ }
60+
61+ if path. is_file ( ) {
62+ continue ;
63+ }
64+
65+ stack. push ( ( path, depth + 1 ) ) ;
3666 }
3767 }
3868
0 commit comments