From e36e18bf4aa13613e187103c8af240120b868638 Mon Sep 17 00:00:00 2001 From: Simeon Visotskiy Date: Tue, 12 Aug 2025 17:04:26 +0300 Subject: [PATCH 1/3] Fix repo mapping for bzlmod detection --- packages/runfiles/runfiles.ts | 68 +++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/packages/runfiles/runfiles.ts b/packages/runfiles/runfiles.ts index 1d3a98bcd6..169952677a 100644 --- a/packages/runfiles/runfiles.ts +++ b/packages/runfiles/runfiles.ts @@ -144,19 +144,75 @@ export class Runfiles { const repoMappings: RepoMappings = Object.create(null); const mappings = fs.readFileSync(repoMappingPath, { encoding: "utf-8" }); - // Each line of the repository mapping manifest has the form: - // canonical name of source repo,apparent name of target repo,target repo runfiles directory - // https://cs.opensource.google/bazel/bazel/+/1b073ac0a719a09c9b2d1a52680517ab22dc971e:src/main/java/com/google/devtools/build/lib/analysis/RepoMappingManifestAction.java;l=117 for (const line of mappings.split("\n")) { if (!line) continue; - const [sourceRepo, targetRepoApparentName, targetRepoDirectory] = line.split(","); - - (repoMappings[sourceRepo] ??= Object.create(null))[targetRepoApparentName] = targetRepoDirectory; + try { + const parsed = this.parseBzlmodRepoMappingLine(line) || this.parseLegacyRepoMappingLine(line); + + if (parsed) { + const { sourceRepo, targetRepoApparentName, targetRepoDirectory } = parsed; + (repoMappings[sourceRepo] ??= Object.create(null))[targetRepoApparentName] = targetRepoDirectory; + } + } catch (error) { + console.warn(`Failed to parse repo mapping line: "${line}"`); + } } return repoMappings; } + private parseBzlmodRepoMappingLine(line: string): { + sourceRepo: string; + targetRepoApparentName: string; + targetRepoDirectory: string; + } | null { + const trimmedLine = line.trim(); + if (!trimmedLine || trimmedLine.startsWith('#')) { + return null; + } + + const parts = trimmedLine.split(','); + if (parts.length < 3) { + return null; + } + + const [sourceRepo, targetRepoApparentName, targetRepoDirectory] = parts; + + if (!sourceRepo.trim() || !targetRepoApparentName.trim() || !targetRepoDirectory.trim()) { + return null; + } + + return { + sourceRepo: sourceRepo.trim(), + targetRepoApparentName: targetRepoApparentName.trim(), + targetRepoDirectory: targetRepoDirectory.trim() + }; + } + + private parseLegacyRepoMappingLine(line: string): { + sourceRepo: string; + targetRepoApparentName: string; + targetRepoDirectory: string; + } | null { + const trimmedLine = line.trim(); + if (!trimmedLine) { + return null; + } + + const parts = trimmedLine.split(','); + if (parts.length !== 3) { + return null; + } + + const [sourceRepo, targetRepoApparentName, targetRepoDirectory] = parts; + + return { + sourceRepo, + targetRepoApparentName, + targetRepoDirectory + }; + } + /** Resolves the given module path. */ resolve(modulePath: string, sourceRepo?: string): string { this._assertRunfilesResolved(); From 63f4123fb47e82d6f06acdeeaede078c92b6b891 Mon Sep 17 00:00:00 2001 From: Mihail Vratchanski Date: Mon, 18 Aug 2025 19:44:31 +0300 Subject: [PATCH 2/3] fix just the issue at hand --- packages/runfiles/runfiles.ts | 71 ++++++----------------------------- 1 file changed, 11 insertions(+), 60 deletions(-) diff --git a/packages/runfiles/runfiles.ts b/packages/runfiles/runfiles.ts index 169952677a..9797fa3a8a 100644 --- a/packages/runfiles/runfiles.ts +++ b/packages/runfiles/runfiles.ts @@ -144,73 +144,24 @@ export class Runfiles { const repoMappings: RepoMappings = Object.create(null); const mappings = fs.readFileSync(repoMappingPath, { encoding: "utf-8" }); + // Each line of the repository mapping manifest has the form: + // canonical name of source repo,apparent name of target repo,target repo runfiles directory + // https://cs.opensource.google/bazel/bazel/+/1b073ac0a719a09c9b2d1a52680517ab22dc971e:src/main/java/com/google/devtools/build/lib/analysis/RepoMappingManifestAction.java;l=117 for (const line of mappings.split("\n")) { if (!line) continue; - try { - const parsed = this.parseBzlmodRepoMappingLine(line) || this.parseLegacyRepoMappingLine(line); - - if (parsed) { - const { sourceRepo, targetRepoApparentName, targetRepoDirectory } = parsed; - (repoMappings[sourceRepo] ??= Object.create(null))[targetRepoApparentName] = targetRepoDirectory; - } - } catch (error) { - console.warn(`Failed to parse repo mapping line: "${line}"`); - } - } - return repoMappings; - } + const [sourceRepo, targetRepoApparentName, targetRepoDirectory] = line.split(","); - private parseBzlmodRepoMappingLine(line: string): { - sourceRepo: string; - targetRepoApparentName: string; - targetRepoDirectory: string; - } | null { - const trimmedLine = line.trim(); - if (!trimmedLine || trimmedLine.startsWith('#')) { - return null; + (repoMappings[sourceRepo] ??= Object.create(null))[targetRepoApparentName] = targetRepoDirectory; } - - const parts = trimmedLine.split(','); - if (parts.length < 3) { - return null; - } - - const [sourceRepo, targetRepoApparentName, targetRepoDirectory] = parts; - if (!sourceRepo.trim() || !targetRepoApparentName.trim() || !targetRepoDirectory.trim()) { - return null; + // Ensure empty source repository mapping exists + if (!repoMappings[""]) { + repoMappings[""] = Object.create(null); + repoMappings[""]["__main__"] = "__main__"; } - - return { - sourceRepo: sourceRepo.trim(), - targetRepoApparentName: targetRepoApparentName.trim(), - targetRepoDirectory: targetRepoDirectory.trim() - }; - } - - private parseLegacyRepoMappingLine(line: string): { - sourceRepo: string; - targetRepoApparentName: string; - targetRepoDirectory: string; - } | null { - const trimmedLine = line.trim(); - if (!trimmedLine) { - return null; - } - - const parts = trimmedLine.split(','); - if (parts.length !== 3) { - return null; - } - - const [sourceRepo, targetRepoApparentName, targetRepoDirectory] = parts; - - return { - sourceRepo, - targetRepoApparentName, - targetRepoDirectory - }; + + return repoMappings; } /** Resolves the given module path. */ From 5fee67b553f4a28bd57330699742b7ba3d30eb9f Mon Sep 17 00:00:00 2001 From: Mihail Vratchanski Date: Tue, 19 Aug 2025 13:59:56 +0300 Subject: [PATCH 3/3] Improved fix --- packages/runfiles/runfiles.ts | 51 +++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/packages/runfiles/runfiles.ts b/packages/runfiles/runfiles.ts index 9797fa3a8a..ea236042e3 100644 --- a/packages/runfiles/runfiles.ts +++ b/packages/runfiles/runfiles.ts @@ -155,12 +155,6 @@ export class Runfiles { (repoMappings[sourceRepo] ??= Object.create(null))[targetRepoApparentName] = targetRepoDirectory; } - // Ensure empty source repository mapping exists - if (!repoMappings[""]) { - repoMappings[""] = Object.create(null); - repoMappings[""]["__main__"] = "__main__"; - } - return repoMappings; } @@ -183,13 +177,31 @@ export class Runfiles { // If the repository mappings were loaded ensure the source repository is valid. if (!(sourceRepo in this.repoMappings)) { - throw new Error( - `source repository "${sourceRepo}" not found in repo mappings: ${JSON.stringify( - this.repoMappings, - null, - 2, - )}`, - ); + // Try common main repository names as fallback + const mainRepoAliases = ['__main__', '_main']; + for (const alias of mainRepoAliases) { + if (alias in this.repoMappings) { + sourceRepo = alias; + break; + } + } + + // If no fallback worked, create a synthetic mapping for the main repository + if (!(sourceRepo in this.repoMappings)) { + // In non-bzlmod mode, create a synthetic mapping from empty repo to main repo + if (sourceRepo === '') { + this.repoMappings[''] = {}; + sourceRepo = ''; + } else { + throw new Error( + `source repository "${sourceRepo}" not found in repo mappings: ${JSON.stringify( + this.repoMappings, + null, + 2, + )}`, + ); + } + } } } @@ -264,7 +276,7 @@ export class Runfiles { } // Apply repo mappings to the moduleBase if it is a known repo. - if (this.repoMappings && moduleBase in this.repoMappings[sourceRepo]) { + if (this.repoMappings && this.repoMappings[sourceRepo] && moduleBase in this.repoMappings[sourceRepo]) { const mappedRepo = this.repoMappings[sourceRepo][moduleBase]; if (mappedRepo !== moduleBase) { const maybe = this._resolve(sourceRepo, mappedRepo, moduleTail); @@ -278,6 +290,17 @@ export class Runfiles { if (fs.existsSync(maybe)) { return maybe; } + + // If not found and we have repo mappings, try under main repository aliases + if (this.repoMappings && !this.repoMappings[sourceRepo]) { + const mainRepoAliases = ['__main__', '_main']; + for (const alias of mainRepoAliases) { + const fallbackPath = path.join(this.runfilesDir, alias, moduleBase, moduleTail || ''); + if (fs.existsSync(fallbackPath)) { + return fallbackPath; + } + } + } } const dirname = path.dirname(moduleBase); if (dirname == '.') {