@@ -46,70 +46,88 @@ fn find_metadata_file(execroot: &Path, runfiles_dir: &Path, path: &str) -> PathB
4646 runfiles_dir. join ( path)
4747}
4848
49- fn find_test_binary ( execroot : & Path , runfiles_dir : & Path ) -> PathBuf {
50- let test_binary = runfiles_dir
51- . join ( env:: var ( "TEST_WORKSPACE" ) . unwrap ( ) )
52- . join ( env:: var ( "TEST_BINARY" ) . unwrap ( ) ) ;
53-
54- if !test_binary. exists ( ) {
55- let configuration = runfiles_dir
56- . strip_prefix ( execroot)
57- . expect ( "RUNFILES_DIR should be relative to ROOT" )
58- . components ( )
59- . enumerate ( )
60- . filter_map ( |( i, part) | {
61- // Keep only `bazel-out/<configuration>/bin`
62- if i < 3 {
63- Some ( PathBuf :: from ( part. as_os_str ( ) ) )
64- } else {
65- None
66- }
67- } )
68- . fold ( PathBuf :: new ( ) , |mut path, part| {
69- path. push ( part) ;
70- path
71- } ) ;
49+ /// Derive the bindir (e.g., "bazel-out/k8-fastbuild/bin") from a bazel output path.
50+ /// Works with paths like "bazel-out/k8-fastbuild/testlogs/..." or runfiles paths.
51+ fn get_bindir ( path : & Path , execroot : & Path ) -> Option < PathBuf > {
52+ let relative = path. strip_prefix ( execroot) . unwrap_or ( path) ;
53+ let components: Vec < _ > = relative. components ( ) . take ( 2 ) . collect ( ) ;
54+ if components. len ( ) >= 2 {
55+ let base: PathBuf = components. iter ( ) . collect ( ) ;
56+ Some ( base. join ( "bin" ) )
57+ } else {
58+ None
59+ }
60+ }
7261
73- let test_binary = execroot
74- . join ( configuration)
75- . join ( env:: var ( "TEST_BINARY" ) . unwrap ( ) ) ;
62+ fn find_test_binary ( execroot : & Path , runfiles_dir : Option < & Path > , coverage_dir : & Path ) -> PathBuf {
63+ let test_binary_env = env:: var ( "TEST_BINARY" ) . unwrap ( ) ;
7664
77- debug_log ! (
78- "TEST_BINARY is not found in runfiles. Falling back to: {}" ,
79- test_binary. display( )
80- ) ;
65+ // Try runfiles first if available
66+ if let Some ( runfiles) = runfiles_dir {
67+ let test_binary = runfiles
68+ . join ( env:: var ( "TEST_WORKSPACE" ) . unwrap_or_default ( ) )
69+ . join ( & test_binary_env) ;
70+ if test_binary. exists ( ) {
71+ return test_binary;
72+ }
73+ // Try deriving bindir from runfiles path
74+ if let Some ( bindir) = get_bindir ( runfiles, execroot) {
75+ let test_binary = execroot. join ( bindir) . join ( & test_binary_env) ;
76+ if test_binary. exists ( ) {
77+ return test_binary;
78+ }
79+ }
80+ }
8181
82- test_binary
83- } else {
84- test_binary
82+ // Derive bindir from coverage_dir
83+ if let Some ( bindir) = get_bindir ( coverage_dir, execroot) {
84+ let test_binary = execroot. join ( & bindir) . join ( & test_binary_env) ;
85+ debug_log ! ( "Using test binary: {}" , test_binary. display( ) ) ;
86+ return test_binary;
8587 }
88+
89+ execroot. join ( & test_binary_env)
8690}
8791
8892fn main ( ) {
8993 let coverage_dir = PathBuf :: from ( env:: var ( "COVERAGE_DIR" ) . unwrap ( ) ) ;
9094 let execroot = PathBuf :: from ( env:: var ( "ROOT" ) . unwrap ( ) ) ;
91- let mut runfiles_dir = PathBuf :: from ( env:: var ( "RUNFILES_DIR" ) . unwrap ( ) ) ;
9295
93- if !runfiles_dir. is_absolute ( ) {
94- runfiles_dir = execroot. join ( runfiles_dir) ;
95- }
96+ // RUNFILES_DIR may not be set in newer Bazel versions during coverage post-processing.
97+ // Try BAZEL_COVERAGE_INTERNAL_RUNFILES_DIR as fallback.
98+ let runfiles_dir = env:: var ( "RUNFILES_DIR" )
99+ . ok ( )
100+ . filter ( |s| !s. is_empty ( ) )
101+ . or_else ( || {
102+ env:: var ( "BAZEL_COVERAGE_INTERNAL_RUNFILES_DIR" )
103+ . ok ( )
104+ . filter ( |s| !s. is_empty ( ) )
105+ } )
106+ . map ( |dir| {
107+ let path = PathBuf :: from ( dir) ;
108+ if path. is_absolute ( ) {
109+ path
110+ } else {
111+ execroot. join ( path)
112+ }
113+ } ) ;
96114
97115 debug_log ! ( "ROOT: {}" , execroot. display( ) ) ;
98- debug_log ! ( "RUNFILES_DIR: {}" , runfiles_dir. display ( ) ) ;
116+ debug_log ! ( "RUNFILES_DIR: {:? }" , runfiles_dir) ;
99117
100118 let coverage_output_file = coverage_dir. join ( "coverage.dat" ) ;
101119 let profdata_file = coverage_dir. join ( "coverage.profdata" ) ;
102120 let llvm_cov = find_metadata_file (
103121 & execroot,
104- & runfiles_dir,
122+ runfiles_dir. as_deref ( ) . unwrap_or ( & execroot ) ,
105123 & env:: var ( "RUST_LLVM_COV" ) . unwrap ( ) ,
106124 ) ;
107125 let llvm_profdata = find_metadata_file (
108126 & execroot,
109- & runfiles_dir,
127+ runfiles_dir. as_deref ( ) . unwrap_or ( & execroot ) ,
110128 & env:: var ( "RUST_LLVM_PROFDATA" ) . unwrap ( ) ,
111129 ) ;
112- let test_binary = find_test_binary ( & execroot, & runfiles_dir) ;
130+ let test_binary = find_test_binary ( & execroot, runfiles_dir. as_deref ( ) , & coverage_dir ) ;
113131 let profraw_files: Vec < PathBuf > = fs:: read_dir ( coverage_dir)
114132 . unwrap ( )
115133 . flatten ( )
0 commit comments