@@ -93,27 +93,37 @@ function loadRunfilesManifest(manifestPath) {
93
93
const runfilesManifest = Object . create ( null ) ;
94
94
const reverseRunfilesManifest = Object . create ( null ) ;
95
95
const input = fs . readFileSync ( manifestPath , { encoding : 'utf-8' } ) ;
96
- let workspaceRoot ;
96
+
97
+ // Absolute path that refers to the local workspace path. We need to determine the absolute
98
+ // path to the local workspace because it allows us to support absolute path resolving
99
+ // for runfiles.
100
+ let localWorkspacePath = null ;
101
+
97
102
for ( const line of input . split ( '\n' ) ) {
98
103
if ( ! line ) continue ;
99
104
const [ runfilesPath , realPath ] = line . split ( ' ' ) ;
100
105
runfilesManifest [ runfilesPath ] = realPath ;
101
106
reverseRunfilesManifest [ realPath ] = runfilesPath ;
102
107
103
- // Determine workspace root to convert absolute paths into runfile paths.
104
- // This only works if there is at least one runfile in the workspace root, but that is
105
- // also the only case when we need to map back to the runfiles.
106
- // See https://github.com/bazelbuild/bazel/issues/5926 for more information.
107
- if ( ! workspaceRoot &&
108
- runfilesPath . startsWith ( USER_WORKSPACE_NAME )
109
- // TODO(gregmagolan): should not be needed when --nolegacy_external_runfiles is default
110
- && ! runfilesPath . startsWith ( `${ USER_WORKSPACE_NAME } /external/` ) ) {
111
- // Plus one to include the slash at the end.
112
- const runfilesPathRemainder = runfilesPath . slice ( USER_WORKSPACE_NAME . length + 1 ) ;
113
- if ( realPath . endsWith ( runfilesPathRemainder ) ) {
114
- workspaceRoot = realPath . slice ( 0 , realPath . length - runfilesPathRemainder . length ) ;
115
- }
108
+ // We don't need to try determining the local workspace path for the current runfile
109
+ // mapping in case we already determined the local workspace path, the current
110
+ // runfile refers to a different workspace, or the current runfile resolves to a file
111
+ // in the bazel-out directory (bin/genfiles directory).
112
+ if ( localWorkspacePath || ! runfilesPath . startsWith ( USER_WORKSPACE_NAME ) ||
113
+ realPath . includes ( BIN_DIR ) || realPath . includes ( GEN_DIR ) ) {
114
+ continue ;
115
+ }
116
+
117
+ // Relative path for the runfile. We can compute that path by removing the leading
118
+ // workspace name. e.g. `my_workspace/src/my-runfile.js` becomes `src/my-runfile.js`.
119
+ const relativeWorkspacePath = runfilesPath . slice ( USER_WORKSPACE_NAME . length + 1 ) ;
120
+
121
+ // TODO(gregmagolan): should not be needed when --nolegacy_external_runfiles is default
122
+ if ( relativeWorkspacePath . startsWith ( 'external/' ) ) {
123
+ continue ;
116
124
}
125
+
126
+ localWorkspacePath = realPath . slice ( 0 , - relativeWorkspacePath . length ) ;
117
127
}
118
128
119
129
// Determine bin and gen root to convert absolute paths into runfile paths.
@@ -127,11 +137,11 @@ function loadRunfilesManifest(manifestPath) {
127
137
128
138
if ( DEBUG ) console . error ( `node_loader: using binRoot ${ binRoot } ` ) ;
129
139
if ( DEBUG ) console . error ( `node_loader: using genRoot ${ genRoot } ` ) ;
130
- if ( DEBUG ) console . error ( `node_loader: using workspaceRoot ${ workspaceRoot } ` ) ;
140
+ if ( DEBUG ) console . error ( `node_loader: using localWorkspacePath ${ localWorkspacePath } ` ) ;
131
141
132
- return { runfilesManifest, reverseRunfilesManifest, binRoot, genRoot, workspaceRoot } ;
142
+ return { runfilesManifest, reverseRunfilesManifest, binRoot, genRoot, localWorkspacePath } ;
133
143
}
134
- const { runfilesManifest, reverseRunfilesManifest, binRoot, genRoot, workspaceRoot } =
144
+ const { runfilesManifest, reverseRunfilesManifest, binRoot, genRoot, localWorkspacePath } =
135
145
// On Windows, Bazel sets RUNFILES_MANIFEST_ONLY=1.
136
146
// On every platform, Bazel also sets RUNFILES_MANIFEST_FILE, but on Linux
137
147
// and macOS it's faster to use the symlinks in RUNFILES_DIR rather than resolve
@@ -272,15 +282,15 @@ function resolveRunfiles(parent, ...pathSegments) {
272
282
runfilesEntry = path . join ( path . dirname ( parentRunfile ) , runfilesEntry ) ;
273
283
}
274
284
} else if ( runfilesEntry . startsWith ( binRoot ) || runfilesEntry . startsWith ( genRoot )
275
- || runfilesEntry . startsWith ( workspaceRoot ) ) {
276
- // For absolute paths, replace binRoot, genRoot or workspaceRoot with USER_WORKSPACE_NAME
277
- // to enable lookups.
285
+ || runfilesEntry . startsWith ( localWorkspacePath ) ) {
286
+ // For absolute paths, replace binRoot, genRoot or localWorkspacePath with
287
+ // USER_WORKSPACE_NAME to enable lookups.
278
288
// It's OK to do multiple replacements because all of these are absolute paths with drive
279
289
// names (e.g. C:\), and on Windows you can't have drive names in the middle of paths.
280
290
runfilesEntry = runfilesEntry
281
291
. replace ( binRoot , `${ USER_WORKSPACE_NAME } /` )
282
292
. replace ( genRoot , `${ USER_WORKSPACE_NAME } /` )
283
- . replace ( workspaceRoot , `${ USER_WORKSPACE_NAME } /` ) ;
293
+ . replace ( localWorkspacePath , `${ USER_WORKSPACE_NAME } /` ) ;
284
294
}
285
295
286
296
// Normalize and replace path separators to conform to the ones in the manifest.
0 commit comments