|
29 | 29 | import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileGlobals.ModuleExtensionUsageBuilder.ModuleExtensionProxy; |
30 | 30 | import com.google.devtools.build.lib.bazel.bzlmod.Version.ParseException; |
31 | 31 | import com.google.devtools.build.lib.cmdline.Label; |
| 32 | +import com.google.devtools.build.lib.cmdline.LabelSyntaxException; |
| 33 | +import com.google.devtools.build.lib.cmdline.PackageIdentifier; |
| 34 | +import com.google.devtools.build.lib.cmdline.RepositoryMapping; |
32 | 35 | import com.google.devtools.build.lib.cmdline.RepositoryName; |
33 | 36 | import com.google.devtools.build.lib.events.EventHandler; |
34 | 37 | import com.google.devtools.build.lib.packages.StarlarkExportable; |
| 38 | +import com.google.devtools.build.lib.vfs.PathFragment; |
35 | 39 | import java.util.ArrayList; |
36 | 40 | import java.util.HashMap; |
37 | 41 | import java.util.LinkedHashMap; |
@@ -480,17 +484,31 @@ public ModuleExtensionProxy useExtension( |
480 | 484 | } |
481 | 485 |
|
482 | 486 | private String normalizeLabelString(String rawExtensionBzlFile) { |
483 | | - // Normalize the label by adding the current module's repo_name if the label doesn't specify a |
484 | | - // repository name. This is necessary as ModuleExtensionUsages are grouped by the string value |
485 | | - // of this label, but later mapped to their Label representation. If multiple strings map to the |
486 | | - // same Label, this would result in a crash. |
| 487 | + // Normalize the label by parsing and stringifying it with a repo mapping that preserves the |
| 488 | + // apparent repository name, except that a reference to the main repository via the empty |
| 489 | + // repo name is translated to using the module repo name. This is necessary as |
| 490 | + // ModuleExtensionUsages are grouped by the string value of this label, but later mapped to |
| 491 | + // their Label representation. If multiple strings map to the same Label, this would result in a |
| 492 | + // crash. |
487 | 493 | // ownName can't change anymore as calling module() after this results in an error. |
488 | 494 | String ownName = module.getRepoName().orElse(module.getName()); |
489 | | - if (module.getKey().equals(ModuleKey.ROOT) && rawExtensionBzlFile.startsWith("@//")) { |
490 | | - return "@" + ownName + rawExtensionBzlFile.substring(1); |
491 | | - } else if (rawExtensionBzlFile.startsWith("//")) { |
492 | | - return "@" + ownName + rawExtensionBzlFile; |
493 | | - } else { |
| 495 | + RepositoryName ownRepoName = RepositoryName.createUnvalidated(ownName); |
| 496 | + try { |
| 497 | + ImmutableMap<String, RepositoryName> repoMapping = ImmutableMap.of(); |
| 498 | + if (module.getKey().equals(ModuleKey.ROOT)) { |
| 499 | + repoMapping = ImmutableMap.of("", ownRepoName); |
| 500 | + } |
| 501 | + Label label = |
| 502 | + Label.parseWithPackageContext( |
| 503 | + rawExtensionBzlFile, |
| 504 | + Label.PackageContext.of( |
| 505 | + PackageIdentifier.create(ownRepoName, PathFragment.EMPTY_FRAGMENT), |
| 506 | + RepositoryMapping.createAllowingFallback(repoMapping))); |
| 507 | + // Skip over the leading "@" of the unambiguous form. |
| 508 | + return label.getUnambiguousCanonicalForm().substring(1); |
| 509 | + } catch (LabelSyntaxException ignored) { |
| 510 | + // Preserve backwards compatibility by not failing eagerly, rather keep the invalid label and |
| 511 | + // let the extension fail when evaluated. |
494 | 512 | return rawExtensionBzlFile; |
495 | 513 | } |
496 | 514 | } |
|
0 commit comments