Skip to content

Commit e5c96be

Browse files
committed
Rejigger git repo support
1 parent afe82a1 commit e5c96be

9 files changed

Lines changed: 410 additions & 276 deletions

rs/BUILD.bazel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ bzl_library(
3838
"//rs/private:annotations",
3939
"//rs/private:cargo_credentials",
4040
"//rs/private:cfg_parser",
41-
"//rs/private:crate_git_repository",
4241
"//rs/private:crate_repository",
4342
"//rs/private:downloader",
44-
"//rs/private:git_repository",
43+
"//rs/private:git_cargo_workspace_repository",
44+
"//rs/private:git_crate_metadata_repository",
4545
"//rs/private:lint_flags",
4646
"//rs/private:registry_config_repository",
4747
"//rs/private:registry_utils",

rs/extensions.bzl

Lines changed: 103 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ load("@rs_rust_host_tools//:defs.bzl", "RS_HOST_CARGO_LABEL")
55
load("//rs/private:annotations.bzl", "annotation_for", "build_annotation_map", "well_known_annotation_snippet_paths")
66
load("//rs/private:cargo_credentials.bzl", "load_cargo_credentials")
77
load("//rs/private:cfg_parser.bzl", "cfg_matches_expr_for_cfg_attrs", "triple_to_cfg_attrs")
8-
load("//rs/private:crate_git_repository.bzl", "crate_git_repository")
98
load("//rs/private:crate_repository.bzl", "crate_repository", "local_crate_repository")
109
load("//rs/private:downloader.bzl", "download_metadata_for_git_crates", "new_downloader_state", "parse_git_url", "start_crate_registry_downloads", "start_github_downloads")
11-
load("//rs/private:git_repository.bzl", "git_repository")
10+
load("//rs/private:git_cargo_workspace_repository.bzl", "git_cargo_workspace_repository")
11+
load("//rs/private:git_crate_metadata_repository.bzl", "git_crate_metadata_repository")
1212
load("//rs/private:lint_flags.bzl", "cargo_toml_lint_flags")
1313
load("//rs/private:registry_config_repository.bzl", "registry_config_repository")
1414
load("//rs/private:registry_utils.bzl", "CRATES_IO_REGISTRY", "registry_config_repo_name")
@@ -24,8 +24,11 @@ def _spoke_repo(hub_name, name, version):
2424
s = s.replace("+", "-")
2525
return s
2626

27-
def _external_repo_for_git_source(remote, commit):
28-
return remote.replace("/", "_").replace(":", "_").replace("@", "_") + "_" + commit
27+
def _external_repo_for_git_source(hub_name, remote, commit):
28+
return hub_name + "__" + remote.replace("/", "_").replace(":", "_").replace("@", "_") + "_" + commit
29+
30+
def _git_crate_purl(name, version, remote, commit):
31+
return "pkg:cargo/%s@%s?vcs_url=git+%s@%s" % (name, version, remote, commit)
2932

3033
def _platform(triple, use_legacy_rules_rust_platforms):
3134
if use_legacy_rules_rust_platforms:
@@ -149,6 +152,28 @@ def _manifest_package_dir(manifest_path, repo_root):
149152

150153
return package_dir.removesuffix("/Cargo.toml")
151154

155+
def _git_crate_package_path(annotation, strip_prefix):
156+
workspace_dir = annotation.workspace_cargo_toml.removesuffix("Cargo.toml").removesuffix("/")
157+
crate_dir = (strip_prefix or "").removeprefix("./").removesuffix("/")
158+
159+
if workspace_dir and crate_dir:
160+
return _normalize_path(paths.normalize(paths.join(workspace_dir, crate_dir)))
161+
if workspace_dir:
162+
return _normalize_path(workspace_dir)
163+
return _normalize_path(crate_dir)
164+
165+
def _target_label(repo_name, package_path, target):
166+
if package_path:
167+
return "@%s//%s:%s" % (repo_name, package_path, target)
168+
return "@%s//:%s" % (repo_name, target)
169+
170+
def _additive_build_file_content(mctx, annotation):
171+
content = ""
172+
if annotation.additive_build_file:
173+
content += mctx.read(annotation.additive_build_file)
174+
content += annotation.additive_build_file_content
175+
return content
176+
152177
def _spec_to_dep_dict_inner(dep, spec, is_build = False):
153178
if type(spec) == "string":
154179
dep = {"name": dep}
@@ -776,6 +801,8 @@ crate.annotation(
776801
)
777802

778803
repo_name = _spoke_repo(hub_name, crate_name, version)
804+
package["target_repo_name"] = repo_name
805+
package["target_package_path"] = ""
779806

780807
if source.startswith("sparse+"):
781808
checksum = package["checksum"]
@@ -813,20 +840,18 @@ crate.annotation(
813840
elif source.startswith("git+"):
814841
remote, commit = parse_git_url(source)
815842

816-
strip_prefix = package.get("strip_prefix")
817-
workspace_cargo_toml = annotation.workspace_cargo_toml
818-
if workspace_cargo_toml != "Cargo.toml":
819-
strip_prefix = workspace_cargo_toml.removesuffix("Cargo.toml") + (strip_prefix or "")
843+
package_path = _git_crate_package_path(annotation, package.get("strip_prefix"))
844+
package["target_repo_name"] = _external_repo_for_git_source(hub_name, remote, commit)
845+
package["target_package_path"] = package_path
820846

821847
if dry_run:
822848
continue
823849

824-
crate_git_repository(
850+
git_crate_metadata_repository(
825851
name = repo_name,
826-
strip_prefix = strip_prefix,
827-
git_repo_label = "@" + _external_repo_for_git_source(remote, commit),
828-
remote = source,
829-
workspace_cargo_toml = annotation.workspace_cargo_toml,
852+
package_name = crate_name,
853+
package_version = version,
854+
purl = _git_crate_purl(crate_name, version, remote, commit),
830855
**kwargs
831856
)
832857
else:
@@ -836,35 +861,41 @@ crate.annotation(
836861

837862
mctx.report_progress("Initializing hub")
838863

864+
package_by_fq = {
865+
_fq_crate(package["name"], package["version"]): package
866+
for package in packages
867+
}
868+
839869
hub_contents = []
840870
for name, versions in versions_by_name.items():
841871
for version in versions:
842872
annotation = annotation_for(annotations, name, version)
843-
spoke_repo = _spoke_repo(hub_name, name, version)
873+
package = package_by_fq[_fq_crate(name, version)]
874+
target_repo_name = package["target_repo_name"]
875+
target_package_path = package["target_package_path"]
844876

845877
hub_contents.append("""
846878
alias(
847879
name = "{name}-{version}",
848-
actual = "@{spoke_repo}//:{name}",
849-
)""".format(name = name, version = version, spoke_repo = spoke_repo))
880+
actual = "{actual}",
881+
)""".format(name = name, version = version, actual = _target_label(target_repo_name, target_package_path, name)))
850882

851883
for binary in annotation.gen_binaries:
852884
hub_contents.append("""
853885
alias(
854886
name = "{name}-{version}__{binary}",
855-
actual = "@{spoke_repo}//:{binary}__bin",
856-
)""".format(name = name, version = version, binary = binary, spoke_repo = spoke_repo))
887+
actual = "{actual}",
888+
)""".format(name = name, version = version, binary = binary, actual = _target_label(target_repo_name, target_package_path, binary + "__bin")))
857889

858890
for alias_name, target in sorted(annotation.extra_aliased_targets.items()):
859891
hub_contents.append("""
860892
alias(
861893
name = "{alias_name}-{version}",
862-
actual = "@{spoke_repo}//:{target}",
894+
actual = "{actual}",
863895
)""".format(
864896
alias_name = alias_name,
865897
version = version,
866-
target = target,
867-
spoke_repo = spoke_repo,
898+
actual = _target_label(target_repo_name, target_package_path, target),
868899
))
869900

870901
workspace_versions = workspace_dep_versions_by_name.get(name)
@@ -1277,22 +1308,62 @@ def _crate_impl(mctx):
12771308

12781309
facts |= _generate_hub_and_spokes(mctx, cfg.name, annotations, suggested_annotation_snippet_paths, cargo_path, cfg.cargo_lock, cargo_toml_by_hub_name[cfg.name], hub_packages, cfg.platform_triples, cargo_credentials, cfg.cargo_config, cfg.validate_lockfile, cfg.debug, cfg.use_legacy_rules_rust_platforms)
12791310

1280-
# Lay down the git repos we will need; per-crate git_repository can clone from these.
1281-
git_sources = set()
1311+
# Lay down the git repos with generated per-crate BUILD overlays.
1312+
git_repos = {}
12821313
for mod in mctx.modules:
12831314
for cfg in mod.tags.from_cargo:
1315+
annotations = build_annotation_map(mod, cfg.name)
12841316
for package in packages_by_hub_name[cfg.name]:
12851317
source = package.get("source", "")
1286-
if source.startswith("git+"):
1287-
git_sources.add(source)
1288-
1289-
for git_source in git_sources:
1290-
remote, commit = parse_git_url(git_source)
1318+
if not source.startswith("git+"):
1319+
continue
12911320

1292-
git_repository(
1293-
name = _external_repo_for_git_source(remote, commit),
1294-
commit = commit,
1295-
remote = remote,
1321+
remote, commit = parse_git_url(source)
1322+
annotation = annotation_for(annotations, package["name"], package["version"])
1323+
repo_name = _external_repo_for_git_source(cfg.name, remote, commit)
1324+
git_repo = git_repos.get(repo_name)
1325+
if not git_repo:
1326+
git_repo = {
1327+
"build_files": {},
1328+
"commit": commit,
1329+
"hub_name": cfg.name,
1330+
"patch_args": [],
1331+
"patch_tool": "",
1332+
"patches": {},
1333+
"remote": remote,
1334+
"workspace_cargo_toml": annotation.workspace_cargo_toml,
1335+
}
1336+
git_repos[repo_name] = git_repo
1337+
1338+
strip_prefix = package.get("strip_prefix")
1339+
if strip_prefix == None:
1340+
strip_prefix = json.decode(facts[source + "_" + package["name"]])["strip_prefix"]
1341+
package_path = _git_crate_package_path(annotation, strip_prefix)
1342+
build_file_path = paths.join(package_path, "BUILD.bazel") if package_path else "BUILD.bazel"
1343+
git_repo["build_files"][build_file_path] = _additive_build_file_content(mctx, annotation)
1344+
1345+
if annotation.patches:
1346+
patch_args = annotation.patch_args
1347+
patch_tool = annotation.patch_tool or ""
1348+
if git_repo["patches"] and (git_repo["patch_args"] != patch_args or git_repo["patch_tool"] != patch_tool):
1349+
fail("Git crates from %s use incompatible patch settings" % source)
1350+
1351+
git_repo["patch_args"] = patch_args
1352+
git_repo["patch_tool"] = patch_tool
1353+
for patch_file in annotation.patches:
1354+
git_repo["patches"][str(patch_file)] = patch_file
1355+
1356+
for repo_name, git_repo in git_repos.items():
1357+
git_cargo_workspace_repository(
1358+
name = repo_name,
1359+
build_files = git_repo["build_files"],
1360+
commit = git_repo["commit"],
1361+
hub_name = git_repo["hub_name"],
1362+
patch_args = git_repo["patch_args"],
1363+
patch_tool = git_repo["patch_tool"],
1364+
patches = git_repo["patches"].values(),
1365+
remote = git_repo["remote"],
1366+
workspace_cargo_toml = git_repo["workspace_cargo_toml"],
12961367
)
12971368

12981369
kwargs = dict(

rs/private/BUILD.bazel

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,11 @@ bzl_library(
3030
)
3131

3232
bzl_library(
33-
name = "crate_git_repository",
34-
srcs = ["crate_git_repository.bzl"],
33+
name = "git_crate_metadata_repository",
34+
srcs = ["git_crate_metadata_repository.bzl"],
3535
visibility = ["//rs:__subpackages__"],
3636
deps = [
3737
":repository_utils",
38-
":symlink_utils",
39-
":toml2json",
40-
"@bazel_tools//tools/build_defs/repo:git_worker.bzl",
41-
"@bazel_tools//tools/build_defs/repo:utils.bzl",
4238
],
4339
)
4440

@@ -100,10 +96,15 @@ bzl_library(
10096
)
10197

10298
bzl_library(
103-
name = "git_repository",
104-
srcs = ["git_repository.bzl"],
99+
name = "git_cargo_workspace_repository",
100+
srcs = ["git_cargo_workspace_repository.bzl"],
105101
visibility = ["//rs:__subpackages__"],
106-
deps = ["@bazel_tools//tools/build_defs/repo:git_worker.bzl"],
102+
deps = [
103+
":repository_utils",
104+
":toml2json",
105+
"@bazel_tools//tools/build_defs/repo:git_worker.bzl",
106+
"@bazel_tools//tools/build_defs/repo:utils.bzl",
107+
],
107108
)
108109

109110
bzl_library(

rs/private/crate_git_repository.bzl

Lines changed: 0 additions & 125 deletions
This file was deleted.

0 commit comments

Comments
 (0)