@@ -108,18 +108,6 @@ async function deleteDirectory(p: string) {
108
108
async function symlink ( target : string , p : string ) : Promise < boolean > {
109
109
log_verbose ( `symlink( ${ p } -> ${ target } )` ) ;
110
110
111
- // Check if the target exists before creating the symlink.
112
- // This is an extra filesystem access on top of the symlink but
113
- // it is necessary for the time being.
114
- if ( ! await exists ( target ) ) {
115
- // This can happen if a module mapping is propogated from a dependency
116
- // but the target that generated the mapping in not in the deps. We don't
117
- // want to create symlinks to non-existant targets as this will
118
- // break any nested symlinks that may be created under the module name
119
- // after this.
120
- return false ;
121
- }
122
-
123
111
// Use junction on Windows since symlinks require elevated permissions.
124
112
// We only link to directories so junctions work for us.
125
113
try {
@@ -714,7 +702,7 @@ export async function main(args: string[], runfiles: Runfiles) {
714
702
715
703
if ( m . link ) {
716
704
const [ root , modulePath ] = m . link ;
717
- let target : string = '<package linking failed>' ;
705
+ let target : string | undefined ;
718
706
switch ( root ) {
719
707
case 'execroot' :
720
708
if ( isExecroot ) {
@@ -749,25 +737,30 @@ export async function main(args: string[], runfiles: Runfiles) {
749
737
throw e ;
750
738
}
751
739
}
752
- } catch {
753
- target = '<runfiles resolution failed>' ;
740
+ } catch ( err ) {
741
+ target = undefined ;
742
+ log_verbose ( `runfiles resolve failed for module '${ m . name } ': ${ err . message } ` ) ;
754
743
}
755
744
break ;
756
745
}
757
746
758
- const stats = await gracefulLstat ( m . name ) ;
759
- // In environments where runfiles are not symlinked (e.g. Windows), existing linked
760
- // modules are preserved. This could cause issues when a link is created at higher level
761
- // as a conflicting directory is already on disk. e.g. consider in a previous run, we
762
- // linked the modules `my-pkg/overlay`. Later on, in another run, we have a module mapping
763
- // for `my-pkg` itself. The linker cannot create `my-pkg` because the directory `my-pkg`
764
- // already exists. To ensure that the desired link is generated, we create the new desired
765
- // link and move all previous nested links from the old module into the new link. Read more
766
- // about this in the description of `createSymlinkAndPreserveContents`.
767
- if ( stats !== null && await isLeftoverDirectoryFromLinker ( stats , m . name ) ) {
768
- await createSymlinkAndPreserveContents ( stats , m . name , target ) ;
747
+ if ( target ) {
748
+ const stats = await gracefulLstat ( m . name ) ;
749
+ // In environments where runfiles are not symlinked (e.g. Windows), existing linked
750
+ // modules are preserved. This could cause issues when a link is created at higher level
751
+ // as a conflicting directory is already on disk. e.g. consider in a previous run, we
752
+ // linked the modules `my-pkg/overlay`. Later on, in another run, we have a module mapping
753
+ // for `my-pkg` itself. The linker cannot create `my-pkg` because the directory `my-pkg`
754
+ // already exists. To ensure that the desired link is generated, we create the new desired
755
+ // link and move all previous nested links from the old module into the new link. Read more
756
+ // about this in the description of `createSymlinkAndPreserveContents`.
757
+ if ( stats !== null && await isLeftoverDirectoryFromLinker ( stats , m . name ) ) {
758
+ await createSymlinkAndPreserveContents ( stats , m . name , target ) ;
759
+ } else {
760
+ await symlink ( target , m . name ) ;
761
+ }
769
762
} else {
770
- await symlink ( target , m . name ) ;
763
+ log_verbose ( `no symlink target found for module ${ m . name } ` ) ;
771
764
}
772
765
}
773
766
0 commit comments