@@ -472,94 +472,55 @@ export async function main(args: string[], runfiles: Runfiles) {
472
472
// lined to node_modules folders at the root or in sub-directories
473
473
for ( const packagePath of Object . keys ( roots ) ) {
474
474
const workspace = roots [ packagePath ] ;
475
- if ( workspace ) {
476
- const workspaceNodeModules = await resolveWorkspaceNodeModules (
477
- workspace , startCwd , isExecroot , execroot , runfiles ) ;
475
+ let workspaceNodeModules : string | undefined = await resolveWorkspaceNodeModules (
476
+ workspace , startCwd , isExecroot , execroot , runfiles ) ;
477
+ if ( await exists ( workspaceNodeModules ) ) {
478
478
log_verbose ( `resolved ${ workspace } workspace node modules path to ${ workspaceNodeModules } ` ) ;
479
+ } else {
480
+ // There are no third party node_modules to symlink to
481
+ workspaceNodeModules = undefined ;
482
+ }
479
483
480
- if ( packagePath ) {
481
- // sub-directory node_modules
482
- if ( await exists ( workspaceNodeModules ) ) {
483
- // in some cases packagePath may not exist in sandbox if there are no source deps
484
- // and only generated file deps. we create it so that we that we can link to
485
- // packagePath/node_modules since packagePathBin/node_modules is a symlink to
486
- // packagePath/node_modules and is unguarded in launcher.sh as we allow symlinks to fall
487
- // through to from output tree to source tree to prevent resolving the same npm package to
488
- // multiple locations on disk
489
- await mkdirp ( packagePath ) ;
490
- await symlinkWithUnlink ( workspaceNodeModules , `${ packagePath } /node_modules` ) ;
491
- if ( ! isExecroot ) {
492
- // Under runfiles, we symlink into the package in runfiles as well.
493
- // When inside the sandbox, the execroot location will not exist to symlink to.
494
- const runfilesPackagePath = `${ startCwd } /${ packagePath } ` ;
495
- if ( await exists ( runfilesPackagePath ) ) {
496
- await symlinkWithUnlink (
497
- `${ packagePath } /node_modules` , `${ runfilesPackagePath } /node_modules` ) ;
498
- }
499
- }
500
- const packagePathBin = `${ bin } /${ packagePath } ` ;
501
- if ( await exists ( packagePathBin ) ) {
502
- // if bin path exists, symlink bin/package/node_modules -> package/node_modules
503
- // NB: this location is unguarded in launcher.sh to allow symlinks to fall-throught
504
- // package/node_modules to prevent resolving the same npm package to multiple locations
505
- // on disk
506
- await symlinkWithUnlink (
507
- `${ packagePath } /node_modules` , `${ packagePathBin } /node_modules` ) ;
508
- }
509
- } else {
510
- // Special case if there no target to symlink to for the root workspace, create a
511
- // root node_modules folder for 1st party deps
512
- log_verbose ( `no npm workspace node_modules folder under ${
513
- packagePath } to link to; creating node_modules directories in ${ process . cwd ( ) } for ${
514
- packagePath } 1p deps`) ;
515
- await mkdirp ( `${ packagePath } /node_modules` ) ;
516
- if ( ! isExecroot ) {
517
- // Under runfiles, we symlink into the package in runfiles as well.
518
- // When inside the sandbox, the execroot location will not exist to symlink to.
519
- const runfilesPackagePath = `${ startCwd } /${ packagePath } ` ;
520
- await mkdirp ( `${ runfilesPackagePath } /node_modules` ) ;
521
- await symlinkWithUnlink (
522
- `${ packagePath } /node_modules` , `${ runfilesPackagePath } /node_modules` ) ;
523
- }
524
- const packagePathBin = `${ bin } /${ packagePath } ` ;
525
- await mkdirp ( `${ packagePathBin } /node_modules` ) ;
526
- await symlinkWithUnlink ( `${ packagePath } /node_modules` , `${ packagePathBin } /node_modules` ) ;
527
- }
528
- } else {
529
- // root node_modules
530
- if ( await exists ( workspaceNodeModules ) ) {
531
- await symlinkWithUnlink ( workspaceNodeModules , `node_modules` ) ;
532
- } else {
533
- // Special case if there no target to symlink to for the root workspace, create a
534
- // root node_modules folder for 1st party deps
535
- log_verbose (
536
- `no root npm workspace node_modules folder to link to; creating node_modules directory in ${
537
- process . cwd ( ) } `) ;
538
- await mkdirp ( 'node_modules' ) ;
539
- }
540
- }
484
+ if ( packagePath ) {
485
+ // In some cases packagePath may not exist in sandbox if there are no source deps
486
+ // and only generated file deps. we create it so that we that we can link to
487
+ // packagePath/node_modules since packagePathBin/node_modules is a symlink to
488
+ // packagePath/node_modules and is unguarded in launcher.sh as we allow symlinks to fall
489
+ // through to from output tree to source tree to prevent resolving the same npm package to
490
+ // multiple locations on disk
491
+ await mkdirp ( packagePath ) ;
492
+ }
493
+
494
+ // There are third party modules at this package path
495
+ const execrootNodeModules = path . posix . join ( packagePath , `node_modules` ) ;
496
+
497
+ if ( workspaceNodeModules ) {
498
+ // Execroot symlink -> external workspace node_modules
499
+ await symlinkWithUnlink ( workspaceNodeModules , execrootNodeModules ) ;
541
500
} else {
542
- if ( packagePath ) {
543
- // Special case if there for first party node_modules at root only
544
- log_verbose ( `no 3p deps at ${ packagePath } ; creating node_modules directories in ${
545
- process . cwd ( ) } for ${ packagePath } 1p deps`) ;
546
- await mkdirp ( `${ packagePath } /node_modules` ) ;
547
- if ( ! isExecroot ) {
548
- // Under runfiles, we symlink into the package in runfiles as well.
549
- // When inside the sandbox, the execroot location will not exist to symlink to.
550
- const runfilesPackagePath = `${ startCwd } /${ packagePath } ` ;
551
- await mkdirp ( `${ runfilesPackagePath } /node_modules` ) ;
552
- await symlinkWithUnlink (
553
- `${ packagePath } /node_modules` , `${ runfilesPackagePath } /node_modules` ) ;
554
- }
555
- const packagePathBin = `${ bin } /${ packagePath } ` ;
556
- await mkdirp ( `${ packagePathBin } /node_modules` ) ;
557
- await symlinkWithUnlink ( `${ packagePath } /node_modules` , `${ packagePathBin } /node_modules` ) ;
558
- } else {
559
- // Special case if there for first party node_modules at root only
560
- log_verbose ( `no 3p deps at root; creating node_modules directory in ${
561
- process . cwd ( ) } for root 1p deps`) ;
562
- await mkdirp ( 'node_modules' ) ;
501
+ // Create an execroot node_modules directory since there are no third party node_modules to symlink to
502
+ await mkdirp ( execrootNodeModules ) ;
503
+ }
504
+
505
+ // Bin symlink -> execroot node_modules
506
+ const packagePathBin = path . posix . join ( bin , packagePath ) ;
507
+ await mkdirp ( `${ packagePathBin } ` ) ;
508
+ await symlinkWithUnlink ( execrootNodeModules , `${ packagePathBin } /node_modules` ) ;
509
+
510
+ // Start CWD symlink -> execroot node_modules
511
+ if ( ! isExecroot ) {
512
+ const runfilesPackagePath = path . posix . join ( startCwd , packagePath ) ;
513
+ await mkdirp ( `${ runfilesPackagePath } ` ) ;
514
+ await symlinkWithUnlink ( execrootNodeModules , `${ runfilesPackagePath } /node_modules` ) ;
515
+ }
516
+
517
+ // RUNFILES symlink -> execroot node_modules
518
+ if ( process . env [ 'RUNFILES' ] ) {
519
+ const stat = await gracefulLstat ( process . env [ 'RUNFILES' ] ) ;
520
+ if ( stat && stat . isDirectory ( ) ) {
521
+ const runfilesPackagePath = path . posix . join ( process . env [ 'RUNFILES' ] , packagePath ) ;
522
+ await mkdirp ( `${ runfilesPackagePath } ` ) ;
523
+ await symlinkWithUnlink ( execrootNodeModules , `${ runfilesPackagePath } /node_modules` ) ;
563
524
}
564
525
}
565
526
}
0 commit comments