Skip to content

Commit 8c63cf5

Browse files
committed
Crate Universe: crate.spec() supports path
This is inspired by #3464
1 parent 6d532fd commit 8c63cf5

File tree

12 files changed

+147
-39
lines changed

12 files changed

+147
-39
lines changed

crate_universe/extensions.bzl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ def _generate_hub_and_spokes(
645645
config_path = config_file,
646646
output_dir = tag_path.get_child("splicing-output"),
647647
debug_workspace_dir = tag_path.get_child("splicing-workspace"),
648+
nonhermetic_root_bazel_workspace_dir = nonhermetic_root_bazel_workspace_dir,
648649
repository_name = cfg.name,
649650
)
650651

@@ -1269,7 +1270,7 @@ _spec = tag_class(
12691270
doc = "A list of features to use for the crate.",
12701271
),
12711272
"git": attr.string(
1272-
doc = "The Git url to use for the crate. Cannot be used with `version`.",
1273+
doc = "The Git url to use for the crate. Cannot be used with `version` or `path`.",
12731274
),
12741275
"lib": attr.bool(
12751276
doc = "If using `artifact = 'bin'`, additionally setting `lib = True` declares a dependency on both the package's library and binary, as opposed to just the binary.",
@@ -1278,6 +1279,9 @@ _spec = tag_class(
12781279
doc = "The explicit name of the package.",
12791280
mandatory = True,
12801281
),
1282+
"path": attr.string(
1283+
doc = "The local path of the remote crate. Cannot be used with `version` or `git`.",
1284+
),
12811285
"repositories": attr.string_list(
12821286
doc = "A list of repository names specified from `crate.from_cargo(name=...)` that this spec is applied to. Defaults to all repositories.",
12831287
default = [],
@@ -1289,7 +1293,7 @@ _spec = tag_class(
12891293
doc = "The git tag of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. Specifying `rev` is recommended for fully-reproducible builds.",
12901294
),
12911295
"version": attr.string(
1292-
doc = "The exact version of the crate. Cannot be used with `git`.",
1296+
doc = "The exact version of the crate. Cannot be used with `git` or `path`.",
12931297
),
12941298
},
12951299
)

crate_universe/private/crate.bzl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ def _spec(
2727
git = None,
2828
branch = None,
2929
tag = None,
30-
rev = None):
30+
rev = None,
31+
path = None):
3132
"""A constructor for a crate dependency.
3233
3334
See [specifying dependencies][sd] in the Cargo book for more details.
@@ -36,15 +37,16 @@ def _spec(
3637
3738
Args:
3839
package (str, optional): The explicit name of the package (used when attempting to alias a crate).
39-
version (str, optional): The exact version of the crate. Cannot be used with `git`.
40+
version (str, optional): The exact version of the crate. Cannot be used with `git` or `path`.
4041
artifact (str, optional): Set to "bin" to pull in a binary crate as an artifact dependency. Requires a nightly Cargo.
4142
lib (bool, optional): If using `artifact = "bin"`, additionally setting `lib = True` declares a dependency on both the package's library and binary, as opposed to just the binary.
4243
default_features (bool, optional): Maps to the `default-features` flag.
4344
features (list, optional): A list of features to use for the crate
44-
git (str, optional): The Git url to use for the crate. Cannot be used with `version`.
45+
git (str, optional): The Git url to use for the crate. Cannot be used with `version` or `path`.
4546
branch (str, optional): The git branch of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. Specifying `rev` is recommended for fully-reproducible builds.
4647
tag (str, optional): The git tag of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. Specifying `rev` is recommended for fully-reproducible builds.
4748
rev (str, optional): The git revision of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified.
49+
path (str, optional): The local path of the remote crate. Cannot be used with `version` or `git`.
4850
4951
Returns:
5052
string: A json encoded string of all inputs
@@ -59,6 +61,7 @@ def _spec(
5961
"git": git,
6062
"lib": lib,
6163
"package": package,
64+
"path": path,
6265
"rev": rev,
6366
"tag": tag,
6467
"version": version,

crate_universe/private/crates_repository.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def _crates_repository_impl(repository_ctx):
9191
splicing_manifest = splicing_manifest,
9292
config_path = config_path,
9393
output_dir = repository_ctx.path("splicing-output"),
94+
nonhermetic_root_bazel_workspace_dir = nonhermetic_root_bazel_workspace_dir,
9495
repository_name = repository_ctx.name,
9596
)
9697

crate_universe/private/splicing_utils.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ def splice_workspace_manifest(
123123
config_path,
124124
output_dir,
125125
repository_name,
126+
nonhermetic_root_bazel_workspace_dir,
126127
debug_workspace_dir = None):
127128
"""Splice together a Cargo workspace from various other manifests and package definitions
128129
@@ -134,6 +135,7 @@ def splice_workspace_manifest(
134135
config_path (path): The path to the config file (containing `cargo_bazel::config::Config`.)
135136
output_dir (path): THe location in which to write splicing outputs.
136137
repository_name (str): Name of the repository being generated.
138+
nonhermetic_root_bazel_workspace_dir (path): The path to the current workspace root
137139
debug_workspace_dir (path): The location in which to save splicing outputs for future review.
138140
139141
Returns:
@@ -151,6 +153,8 @@ def splice_workspace_manifest(
151153
config_path,
152154
"--repository-name",
153155
repository_name,
156+
"--nonhermetic-root-bazel-workspace-dir",
157+
nonhermetic_root_bazel_workspace_dir,
154158
]
155159

156160
if cargo_lockfile:

crate_universe/src/cli/splice.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ pub struct SpliceOptions {
6464
/// The name of the repository being generated.
6565
#[clap(long)]
6666
pub repository_name: String,
67+
68+
/// The path to the Bazel root workspace (i.e. the directory containing the WORKSPACE.bazel file or similar).
69+
/// BE CAREFUL with this value. We never want to include it in a lockfile hash (to keep lockfiles portable),
70+
/// which means you also should not use it anywhere that _should_ be guarded by a lockfile hash.
71+
/// You basically never want to use this value.
72+
#[clap(long)]
73+
pub nonhermetic_root_bazel_workspace_dir: Utf8PathBuf,
6774
}
6875

6976
/// Combine a set of disjoint manifests into a single workspace.
@@ -73,12 +80,12 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
7380
.context("Failed to parse splicing manifest")?;
7481

7582
// Determine the splicing workspace
76-
let temp_dir;
83+
// let temp_dir;
7784
let splicing_dir = match &opt.workspace_dir {
7885
Some(dir) => dir.clone(),
7986
None => {
80-
temp_dir = tempfile::tempdir().context("Failed to generate temporary directory")?;
81-
Utf8PathBuf::from_path_buf(temp_dir.as_ref().to_path_buf())
87+
let temp_dir = tempfile::tempdir().context("Failed to generate temporary directory")?;
88+
Utf8PathBuf::from_path_buf(temp_dir.into_path())
8289
.unwrap_or_else(|path| panic!("Temporary directory wasn't valid UTF-8: {:?}", path))
8390
}
8491
};
@@ -91,7 +98,7 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
9198

9299
// Splice together the manifest
93100
let manifest_path = prepared_splicer
94-
.splice(&splicing_dir)
101+
.splice(&splicing_dir, &opt.nonhermetic_root_bazel_workspace_dir)
95102
.with_context(|| format!("Failed to splice workspace {}", opt.repository_name))?;
96103

97104
// Generate a lockfile

crate_universe/src/cli/vendor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
217217

218218
// Splice together the manifest
219219
let manifest_path = splicer
220-
.splice_workspace()
220+
.splice_workspace(&opt.nonhermetic_root_bazel_workspace_dir)
221221
.context("Failed to splice workspace")?;
222222

223223
// Gather a cargo lockfile

0 commit comments

Comments
 (0)