bazelbuild / bazelbuild/rules_rust

Get list of manifests to use with crates_repository

Open
#2,724 1 comment 0 reactions 0 assignees View on GitHub
needs-triage
Dominant language
Starlark
Stars
843
Forks
651
Avg merge
2d 18h
Merged PRs (30d)
15

Description

I have a project with a Cargo workspace with 100+ members, meaning it's not practical to list every single manifest manually when calling `crates_repository`. Maybe I'm going the wrong way about it, but I'm wondering how to get a list of all manifests to give `crates_repository`, much like `all_crate_deps` does for dependencies.

Right now I'm using this hacky (& brittle) repository rule that reads the top-level `Cargo.toml` and exports a list of labels:

```starlark
"""
A repository rule that creates a repo exporting the list of all Cargo manifests
(excluding the top-level one) as MANIFESTS
"""

def _impl(repository_ctx):
# Assume a Cargo.toml in the root
contents = repository_ctx.read(repository_ctx.attr.manifest)

repository_ctx.report_progress("Fetching manifests")
# Read the Cargo.toml's `members`; does this by reading
# all lines between 'members = [' and the closing ']'
[_, contents] = contents.split("members = [\n")
[contents,_] = contents.split("]",1)
packages = contents.splitlines()

# turn the manifest path into a Bazel label
def package_to_label(package):
[_, rest] = package.split("\"", 1)
[rest, _] = rest.split("\"", 1)
return "\"//" + rest + ":Cargo.toml\","

labels = [package_to_label(p) for p in packages]
manifests = "".join(labels)
repository_ctx.file("BUILD.bazel", content = "\n", executable = False)
repository_ctx.file("defs.bzl", "MANIFESTS = [ {manifests} ]\n".format(manifests = manifests), executable = False)

_manifests = repository_rule(
implementation = _impl,
attrs = {
"manifest": attr.label(mandatory = True),
},
)

def manifests_repository(name, manifest):
_manifests(name = name, manifest = manifest)
```

and in the `WORKSPACE`:

```starlark
load("//bazel/manifests:defs.bzl", "manifests_repository")

manifests_repository(name = "manifests")
```

and in the `BUILD.bazel` file with `crates_repository`:

```starlark
load("@manifests//:defs.bzl", "MANIFESTS")

crates_repository(
...
manifests = ["//:Cargo.toml"] + MANIFESTS
)
````

Is there a better/recommended way of doing this?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.