Skip to content

Commit

Permalink
Add patching example
Browse files Browse the repository at this point in the history
  • Loading branch information
P1n3appl3 committed Dec 9, 2024
1 parent b5185cd commit a4c8762
Show file tree
Hide file tree
Showing 26 changed files with 1,178 additions and 4 deletions.
1 change: 0 additions & 1 deletion crate_universe/private/crates_vendor.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ def _crates_vendor_impl(ctx):
environ = {
"CARGO": _runfiles_path(toolchain.cargo, is_windows),
"RUSTC": _runfiles_path(toolchain.rustc, is_windows),
# "RUST_BACKTRACE": 1,
}

args = ["vendor"]
Expand Down
1 change: 0 additions & 1 deletion crate_universe/src/metadata/metadata_annotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ impl LockfileAnnotation {
workspace_metadata: &WorkspaceMetadata,
) -> Result<SourceAnnotation> {
let pkg = &metadata[&node.id];
println!("{} : {}", pkg.name, pkg.id.repr);

// Locate the matching lock package for the current crate
let lock_pkg = match cargo_meta_pkg_to_locked_pkg(pkg, &lockfile.packages) {
Expand Down
1 change: 1 addition & 0 deletions examples/crate_universe/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ bazel commands:
bazel run //vendor_external:crates_vendor
bazel run //vendor_local_manifests:crates_vendor
bazel run //vendor_local_pkgs:crates_vendor
bazel run //vendor_local_patching:vendor
bazel run //vendor_remote_manifests:crates_vendor
bazel run //vendor_remote_pkgs:crates_vendor
```
Expand Down
3 changes: 3 additions & 0 deletions examples/crate_universe/vendor_local_patching/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignore everything but the `BUILD` files within the vendored directories
vendor/*/*
!vendor/*/BUILD.bazel
31 changes: 31 additions & 0 deletions examples/crate_universe/vendor_local_patching/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
load("@rules_rust//crate_universe:defs.bzl", "crates_vendor")
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test")

crates_vendor(
name = "vendor",
cargo_lockfile = ":Cargo.lock",
manifests = [":Cargo.toml"],
mode = "local",
vendor_path = "vendor",
# No wasi support
supported_platform_triples = [
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-pc-windows-msvc",
"x86_64-unknown-fuchsia",
"aarch64-unknown-fuchsia",
],
)

rust_binary(
name = "bin",
srcs = ["src/main.rs"],
edition = "2021",
deps = ["//vendor_local_patching/vendor:rand"],
)

rust_test(
name = "test",
crate = ":bin",
)
70 changes: 70 additions & 0 deletions examples/crate_universe/vendor_local_patching/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions examples/crate_universe/vendor_local_patching/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "my_third_party"
version = "0.1.0"

[dependencies]
rand = "0.8.5"

[patch.crates-io]
# We need to make sure that forked_getrandom/BUILD.bazel exposes the correct
# filegroups so that the generated BUILD file in the vendor dir can point to them.
getrandom = { path = "forked_getrandom" }

# Since we know this crate is never used, we don't have to bother creating a BUILD
# file for our empty stub crate we're using to patch it out
wasi = { path = "empty_wasi" }
19 changes: 19 additions & 0 deletions examples/crate_universe/vendor_local_patching/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Local vendoring with patches

This demonstrates patching out crates when using the "local" vendor mode. The
example crate just depends on `rand`, and we patch out two of the transitive deps:

- `getrandom` is forked. In `forked_getrandom/BUILD.bazel` the necessary
filegroups are exposed so that the generated BUILD file at
`vendor/getrandom-0.2.8/BUILD.bazel` can use them.
- `wasi` is "empty-patched" because it's not actually used in the build. When
using local vendoring, `crate_universe` runs `cargo vendor` which isn't aware
of which target-triples you're using. The `wasi` crate is only used by `rand`
when you're actually targeting `wasi` (which we're not), so we
patch it out with a stub crate to avoid downloading and vendoring the source
of the that crate. This can be helpful to avoid vendoring large crates or
ones with conflicting licenses that aren't used in your build graph.

The result of our `getrandom` patch is that the binary is always given the
same value for seeding its RNG. Therefore we can test that `rand::random`
returns the same value to check that the patching behavior is working correctly.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[package]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
filegroup(
name = "crate_root",
srcs = ["src/lib.rs"],
visibility = ["//vendor_local_patching/vendor:__subpackages__"],
)

filegroup(
name = "srcs",
srcs = glob(["**/*.rs"]),
visibility = ["//vendor_local_patching/vendor:__subpackages__"],
)

filegroup(
name = "compile_data",
srcs = glob(["**/*"]),
visibility = ["//vendor_local_patching/vendor:__subpackages__"],
)

filegroup(
name = "build_script_crate_root",
srcs = ["build.rs"],
visibility = ["//vendor_local_patching/vendor:__subpackages__"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
edition = "2018"
name = "getrandom"
version = "0.2.15"
authors = ["The Rand Project Developers"]
exclude = [".*"]
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A small cross-platform library for retrieving random data from system source"
documentation = "https://docs.rs/getrandom"
readme = "README.md"
categories = ["os", "no-std"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-random/getrandom"

[lib]
name = "getrandom"
path = "src/lib.rs"

[dependencies.cfg-if]
version = "1"

[dependencies.compiler_builtins]
version = "0.1"
optional = true

[dependencies.core]
version = "1.0"
optional = true
package = "rustc-std-workspace-core"

[features]
std = []
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-env=RANDOM_NUMBER=4");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::{fmt, num::NonZeroU32};

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct Error(NonZeroU32);
impl std::error::Error for Error {}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Error({})", self.0.get())
}
}

pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
if dest.is_empty() {
return Ok(());
}
let num = env!("RANDOM_NUMBER").parse().unwrap();
for n in dest {
*n = num; // chosen by fair dice roll.
// guaranteed to be random.
}
Ok(())
}
11 changes: 11 additions & 0 deletions examples/crate_universe/vendor_local_patching/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn main() {
println!("\"random\" number: {}", rand::random::<f32>());
}

#[cfg(test)]
mod tests {
#[test]
fn not_actually_random() {
assert_eq!(rand::random::<u32>(), 34253218);
}
}
37 changes: 37 additions & 0 deletions examples/crate_universe/vendor_local_patching/vendor/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//vendor_local_patching:vendor
###############################################################################

package(default_visibility = ["//visibility:public"])

exports_files(
[
"cargo-bazel.json",
"defs.bzl",
] + glob(
include = ["*.bazel"],
allow_empty = True,
),
)

filegroup(
name = "srcs",
srcs = glob(
include = [
"*.bazel",
"*.bzl",
],
allow_empty = True,
),
)

# Workspace Member Dependencies
alias(
name = "rand",
actual = "//vendor_local_patching/vendor/rand-0.8.5:rand",
tags = ["manual"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""Alias that transitions its target to `compilation_mode=opt`. Use `transition_alias="opt"` to enable."""

load("@rules_cc//cc:defs.bzl", "CcInfo")
load("@rules_rust//rust:rust_common.bzl", "COMMON_PROVIDERS")

def _transition_alias_impl(ctx):
# `ctx.attr.actual` is a list of 1 item due to the transition
providers = [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]
if CcInfo in ctx.attr.actual[0]:
providers.append(ctx.attr.actual[0][CcInfo])
return providers

def _change_compilation_mode(compilation_mode):
def _change_compilation_mode_impl(_settings, _attr):
return {
"//command_line_option:compilation_mode": compilation_mode,
}

return transition(
implementation = _change_compilation_mode_impl,
inputs = [],
outputs = [
"//command_line_option:compilation_mode",
],
)

def _transition_alias_rule(compilation_mode):
return rule(
implementation = _transition_alias_impl,
provides = COMMON_PROVIDERS,
attrs = {
"actual": attr.label(
mandatory = True,
doc = "`rust_library()` target to transition to `compilation_mode=opt`.",
providers = COMMON_PROVIDERS,
cfg = _change_compilation_mode(compilation_mode),
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
doc = "Transitions a Rust library crate to the `compilation_mode=opt`.",
)

transition_alias_dbg = _transition_alias_rule("dbg")
transition_alias_fastbuild = _transition_alias_rule("fastbuild")
transition_alias_opt = _transition_alias_rule("opt")
Loading

0 comments on commit a4c8762

Please sign in to comment.