From 9390eba52c63428e1271e8475d6967e02074b8a7 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Tue, 1 Oct 2024 15:36:51 +0200 Subject: [PATCH] Allow `+` in repo names (#2908) Bazel 8 uses `+` as the separator for segments of canonical repo names, whereas Bazel 7 uses `~` or `+` depending on the value of `--incompatible_use_plus_in_repo_names`. --------- Co-authored-by: Daniel Wagner-Hall --- crate_universe/src/utils/starlark/label.rs | 3 ++- util/label/label.rs | 23 +++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/crate_universe/src/utils/starlark/label.rs b/crate_universe/src/utils/starlark/label.rs index 30e1d23b3f..58abbcecba 100644 --- a/crate_universe/src/utils/starlark/label.rs +++ b/crate_universe/src/utils/starlark/label.rs @@ -66,7 +66,8 @@ impl FromStr for Label { fn from_str(s: &str) -> Result { static RE: OnceCell = OnceCell::new(); let re = RE.get_or_try_init(|| { - Regex::new(r"^(@@?[\w\d\-_\.~]*)?(//)?([\w\d\-_\./+]+)?(:([\+\w\d\-_\./]+))?$") + // TODO: Disallow `~` in repository names once support for Bazel 7.2 is dropped. + Regex::new(r"^(@@?[\w\d\-_\.+~]*)?(//)?([\w\d\-_\./+]+)?(:([\+\w\d\-_\./]+))?$") }); let cap = re? diff --git a/util/label/label.rs b/util/label/label.rs index d1e00a7ec3..7f832e1d3a 100644 --- a/util/label/label.rs +++ b/util/label/label.rs @@ -14,7 +14,7 @@ pub fn analyze(input: &'_ str) -> Result> { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum Repository<'s> { - /// A `@@` prefixed name that is unique within a workspace. E.g. `@@rules_rust~0.1.2~toolchains~local_rustc` + /// A `@@` prefixed name that is unique within a workspace. E.g. `@@rules_rust+0.1.2+toolchains~local_rustc` Canonical(&'s str), // stringifies to `@@self.0` where `self.0` may be empty /// A `@` (single) prefixed name. E.g. `@rules_rust`. Apparent(&'s str), @@ -187,12 +187,20 @@ fn consume_repository_name<'s>( } if !repository_name .chars() - .all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_' || c == '.' || c == '~') + // TODO: Disallow `~` in repository names once support for Bazel 7.2 is dropped. + .all(|c| { + c.is_ascii_alphanumeric() + || c == '-' + || c == '_' + || c == '.' + || c == '~' + || c == '+' + }) { return Err(LabelError(err( label, "workspace names \ - may contain only A-Z, a-z, 0-9, '-', '_', '.', and '~'.", + may contain only A-Z, a-z, 0-9, '-', '_', '.', '+', and '~'.", ))); } } @@ -334,6 +342,7 @@ mod tests { #[test] fn test_repository_name_parsing() -> Result<()> { assert_eq!(analyze("@repo//:foo")?.repo_name(), Some("repo")); + assert_eq!(analyze("@repo+name//:foo")?.repo_name(), Some("repo+name")); assert_eq!(analyze("@@repo//:foo")?.repo_name(), Some("repo")); assert_eq!(analyze("@//:foo")?.repo_name(), Some("")); assert_eq!(analyze("//:foo")?.repo_name(), None); @@ -341,6 +350,10 @@ mod tests { assert_eq!(analyze("@repo//foo/bar")?.repo_name(), Some("repo")); assert_eq!(analyze("@@repo//foo/bar")?.repo_name(), Some("repo")); + assert_eq!( + analyze("@@repo+name//foo/bar")?.repo_name(), + Some("repo+name") + ); assert_eq!(analyze("@//foo/bar")?.repo_name(), Some("")); assert_eq!(analyze("//foo/bar")?.repo_name(), None); assert_eq!( @@ -378,7 +391,7 @@ mod tests { assert_eq!( analyze("@foo:bar"), Err(LabelError( - "@foo:bar must be a legal label; workspace names may contain only A-Z, a-z, 0-9, '-', '_', '.', and '~'.".to_string() + "@foo:bar must be a legal label; workspace names may contain only A-Z, a-z, 0-9, '-', '_', '.', '+', and '~'.".to_string() )) ); @@ -398,7 +411,7 @@ mod tests { analyze("@foo#//:baz"), Err(LabelError( "@foo#//:baz must be a legal label; workspace names \ - may contain only A-Z, a-z, 0-9, '-', '_', '.', and '~'." + may contain only A-Z, a-z, 0-9, '-', '_', '.', '+', and '~'." .to_string() )) );