Skip to content

Commit 1df16ae

Browse files
Max Huang-HobbsMax Huang-Hobbs
authored andcommitted
Test cargo-provided variables in build-scripts
- Tests availability of cargo-provided environment variables in build scripts (cargo_toml_env_vars). - Tests multiline strings in generated env files
1 parent ae69e5f commit 1df16ae

6 files changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
load("//cargo:defs.bzl", "cargo_build_script", "cargo_toml_env_vars")
2+
load("//rust:defs.bzl", "rust_library", "rust_test")
3+
4+
# Test that cargo_toml_env_vars works with build_script_env_files to provide
5+
# CARGO_PKG_* variables to build scripts at runtime. This is the fix for
6+
# crates like rav1e whose build scripts (via the `built` crate) read
7+
# CARGO_PKG_AUTHORS at runtime with std::env::var().
8+
9+
cargo_toml_env_vars(
10+
name = "cargo_toml_env_vars",
11+
src = "Cargo.toml",
12+
)
13+
14+
cargo_build_script(
15+
name = "cargo_build_script",
16+
srcs = ["build.rs"],
17+
build_script_env_files = [":cargo_toml_env_vars"],
18+
edition = "2021",
19+
)
20+
21+
rust_library(
22+
name = "test_lib",
23+
srcs = ["test_lib.rs"],
24+
edition = "2021",
25+
deps = [":cargo_build_script"],
26+
)
27+
28+
rust_test(
29+
name = "consume_build_script",
30+
crate = ":test_lib",
31+
size = "small",
32+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "test_cargo_toml_env"
3+
version = "1.2.3"
4+
authors = ["Test Author <test@example.com>", "Another Author"]
5+
description = """
6+
This is a multiline description
7+
that spans multiple lines.
8+
"""
9+
edition = "2021"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//! Build script that reads CARGO_PKG_* env vars at runtime.
2+
//! This tests that cargo_toml_env_vars + build_script_env_files correctly
3+
//! provides these variables to build scripts, which is needed for crates
4+
//! like rav1e that use the `built` crate.
5+
6+
fn main() {
7+
// Read env vars that should be set from cargo_toml_env_vars via build_script_env_files
8+
let authors = std::env::var("CARGO_PKG_AUTHORS")
9+
.expect("CARGO_PKG_AUTHORS should be set from Cargo.toml");
10+
let version = std::env::var("CARGO_PKG_VERSION")
11+
.expect("CARGO_PKG_VERSION should be set from Cargo.toml");
12+
let name = std::env::var("CARGO_PKG_NAME")
13+
.expect("CARGO_PKG_NAME should be set from Cargo.toml");
14+
let description = std::env::var("CARGO_PKG_DESCRIPTION")
15+
.expect("CARGO_PKG_DESCRIPTION should be set from Cargo.toml");
16+
17+
// Pass them to rustc so the test can verify them
18+
println!("cargo:rustc-env=TEST_AUTHORS={}", authors);
19+
println!("cargo:rustc-env=TEST_VERSION={}", version);
20+
println!("cargo:rustc-env=TEST_NAME={}", name);
21+
// Escape newlines for cargo:rustc-env
22+
println!("cargo:rustc-env=TEST_DESCRIPTION={}", description.replace('\n', "\\n"));
23+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//! Tests that CARGO_PKG_* env vars from Cargo.toml are available to build.rs
2+
//! at runtime via build_script_env_files.
3+
4+
#[test]
5+
fn check_authors_from_cargo_toml() {
6+
// Authors should be colon-separated as Cargo does
7+
let authors = env!("TEST_AUTHORS");
8+
assert!(
9+
authors.contains("Test Author"),
10+
"Expected 'Test Author' in authors, got: {}",
11+
authors
12+
);
13+
assert!(
14+
authors.contains("Another Author"),
15+
"Expected 'Another Author' in authors, got: {}",
16+
authors
17+
);
18+
}
19+
20+
#[test]
21+
fn check_version_from_cargo_toml() {
22+
assert_eq!("1.2.3", env!("TEST_VERSION"));
23+
}
24+
25+
#[test]
26+
fn check_name_from_cargo_toml() {
27+
assert_eq!("test_cargo_toml_env", env!("TEST_NAME"));
28+
}
29+
30+
#[test]
31+
fn check_description_from_cargo_toml() {
32+
let desc = env!("TEST_DESCRIPTION");
33+
// Description should contain the multiline content (with escaped newlines)
34+
assert!(
35+
desc.contains("multiline description"),
36+
"Expected 'multiline description' in description, got: {}",
37+
desc
38+
);
39+
}

cargo/tests/cargo_build_script/build_script_env_files/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ rust_library(
2828
rust_test(
2929
name = "consume_build_script",
3030
crate = ":test_lib",
31+
size = "small",
3132
)

crate_universe/src/rendering.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,68 @@ mod test {
13411341
assert!(build_file_content.contains("name = \"_bs\""));
13421342
}
13431343

1344+
#[test]
1345+
fn render_cargo_build_script_with_env_files() {
1346+
let mut context = Context::default();
1347+
let crate_id = CrateId::new("mock_crate".to_owned(), VERSION_ZERO_ONE_ZERO);
1348+
1349+
let attrs = BuildScriptAttributes {
1350+
build_script_env_files: Select::from_value(BTreeSet::from([
1351+
"env_file.txt".to_owned(),
1352+
])),
1353+
..BuildScriptAttributes::default()
1354+
};
1355+
1356+
context.crates.insert(
1357+
crate_id.clone(),
1358+
CrateContext {
1359+
name: crate_id.name,
1360+
version: crate_id.version,
1361+
package_url: None,
1362+
repository: None,
1363+
targets: BTreeSet::from([Rule::BuildScript(TargetAttributes {
1364+
crate_name: "build_script_build".to_owned(),
1365+
crate_root: Some("build.rs".to_owned()),
1366+
..TargetAttributes::default()
1367+
})]),
1368+
library_target_name: None,
1369+
common_attrs: CommonAttributes::default(),
1370+
build_script_attrs: Some(attrs),
1371+
license: None,
1372+
license_ids: BTreeSet::default(),
1373+
license_file: None,
1374+
additive_build_file_content: None,
1375+
disable_pipelining: false,
1376+
extra_aliased_targets: BTreeMap::default(),
1377+
alias_rule: None,
1378+
override_targets: BTreeMap::default(),
1379+
},
1380+
);
1381+
1382+
let renderer = Renderer::new(mock_render_config(None), mock_supported_platform_triples());
1383+
let output = renderer.render(&context, None).unwrap();
1384+
1385+
let build_file_content = output
1386+
.get(&PathBuf::from("BUILD.mock_crate-0.1.0.bazel"))
1387+
.unwrap();
1388+
1389+
assert!(
1390+
build_file_content.contains("cargo_build_script("),
1391+
"Expected cargo_build_script in:\n{}",
1392+
build_file_content
1393+
);
1394+
assert!(
1395+
build_file_content.contains("build_script_env_files = ["),
1396+
"Expected build_script_env_files in:\n{}",
1397+
build_file_content
1398+
);
1399+
assert!(
1400+
build_file_content.contains("\"env_file.txt\""),
1401+
"Expected env_file.txt in build_script_env_files:\n{}",
1402+
build_file_content
1403+
);
1404+
}
1405+
13441406
#[test]
13451407
fn render_proc_macro() {
13461408
let mut context = Context::default();

0 commit comments

Comments
 (0)