@@ -9,6 +9,10 @@ import * as path from 'path';
99// Run Bazel with --define=VERBOSE_LOGS=1 to enable this logging
1010const VERBOSE_LOGS = ! ! process . env [ 'VERBOSE_LOGS' ] ;
1111
12+ // NB: on windows thanks to legacy 8-character path segments it might be like
13+ // c:/b/ojvxx6nx/execroot/build_~1/bazel-~1/x64_wi~1/bin/internal/npm_in~1/test
14+ const BAZEL_OUT_REGEX = / ( \/ b a z e l - o u t \/ | \/ b a z e l - ~ 1 \/ x 6 4 _ w i ~ 1 \/ ) / ;
15+
1216function log_verbose ( ...m : string [ ] ) {
1317 if ( VERBOSE_LOGS ) console . error ( '[link_node_modules.js]' , ...m ) ;
1418}
@@ -175,9 +179,7 @@ async function resolveRoot(
175179 // runfiles on rbe, bazel runs the process in a directory such as
176180 // `/b/f/w/bazel-out/k8-fastbuild/bin/path/to/pkg/some_test.sh.runfiles/my_wksp`. From here we can
177181 // determine the execroot `b/f/w` by finding the first instance of bazel-out.
178- // NB: on windows thanks to legacy 8-character path segments it might be like
179- // c:/b/ojvxx6nx/execroot/build_~1/bazel-~1/x64_wi~1/bin/internal/npm_in~1/test
180- const match = startCwd . match ( / ( \/ b a z e l - o u t \/ | \/ b a z e l - ~ 1 \/ x 6 4 _ w i ~ 1 \/ ) / ) ;
182+ const match = startCwd . match ( BAZEL_OUT_REGEX ) ;
181183 if ( ! match ) {
182184 // No execroot found. This can happen if we are inside a nodejs_image or a nodejs_binary is
183185 // run manually.
@@ -278,6 +280,7 @@ export class Runfiles {
278280 lookupDirectory ( dir : string ) : string | undefined {
279281 if ( ! this . manifest ) return undefined ;
280282
283+ let result : string | undefined ;
281284 for ( const [ k , v ] of this . manifest ) {
282285 // Account for Bazel --legacy_external_runfiles
283286 // which pollutes the workspace with 'my_wksp/external/...'
@@ -289,9 +292,15 @@ export class Runfiles {
289292 // calculate l = length(`/semver/LICENSE`)
290293 if ( k . startsWith ( dir ) ) {
291294 const l = k . length - dir . length ;
292- return v . substring ( 0 , v . length - l ) ;
295+ const maybe = v . substring ( 0 , v . length - l ) ;
296+ if ( maybe . match ( BAZEL_OUT_REGEX ) ) {
297+ return maybe ;
298+ } else {
299+ result = maybe ;
300+ }
293301 }
294302 }
303+ return result ;
295304 }
296305
297306
@@ -731,6 +740,15 @@ export async function main(args: string[], runfiles: Runfiles) {
731740 }
732741 try {
733742 target = runfiles . resolve ( runfilesPath ) ;
743+ // if we're resolving from a manifest then make sure we don't resolve
744+ // into the source tree when we are expecting the output tree
745+ if ( runfiles . manifest && root == 'execroot' && modulePath . startsWith ( `${ bin } /` ) ) {
746+ if ( ! target . includes ( `/${ bin } /` ) ) {
747+ const e = new Error ( `could not resolve modulePath ${ modulePath } ` ) ;
748+ ( e as any ) . code = 'MODULE_NOT_FOUND' ;
749+ throw e ;
750+ }
751+ }
734752 } catch {
735753 target = '<runfiles resolution failed>' ;
736754 }
0 commit comments