diff --git a/Cargo.lock b/Cargo.lock index 0d3254d..1079320 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -113,6 +113,7 @@ dependencies = [ "snapbox", "tempfile", "toml", + "xdg", ] [[package]] @@ -636,3 +637,9 @@ checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] + +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" diff --git a/Cargo.toml b/Cargo.toml index b2ffd2e..64c9396 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ once_cell = "1.20" regex = "1.11" tempfile = "3.14" toml = "0.8" +xdg = "2.5" [dev-dependencies] assert_cmd = "2.0" diff --git a/README.md b/README.md index 227d0a8..504c8c6 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ Note that the below environment variables are read **when a build script is link BUILD_WRAP_ALLOW=1 cargo build -vv ``` + If a package must always be built with this strategy, put the package's name in [`$HOME/.config/build-wrap/allow.txt`] (see below). + - `BUILD_WRAP_CMD`: Command used to execute a build script. Linux default: - With comments: @@ -90,6 +92,17 @@ Note that the below environment variables are read **when a build script is link (deny network*) ;; Deny network access ``` +## `$HOME/.config/build-wrap/allow.txt` + +If a file at `$HOME/.config/build-wrap/allow.txt` exists, `build-wrap` treats each line as the name of a package. Such packages are built as though `BUILD_WRAP_ALLOW` were set to `1`. + +For example, [`svm-rs-builds`] downloads information about Solc releases when it is built. So if you build [`svm-rs`] frequently, you might do the following: + +```sh +mkdir -p "$HOME/.config/build-wrap" +echo 'svm-rs-builds' > "$HOME/.config/build-wrap/allow.txt" +``` + ## Environment variables that `build-wrap` treats as set Note that we say "treats as set" because these are considered only when [`BUILD_WRAP_CMD` is expanded]. @@ -134,9 +147,12 @@ The "wrapped" version of the build script does the following when invoked: [How `build-wrap` works]: #how-build-wrap-works [Ubuntu Community Wiki]: https://help.ubuntu.com/community/AppArmor [Ubuntu Server]: https://documentation.ubuntu.com/server/how-to/security/apparmor/ +[`$HOME/.config/build-wrap/allow.txt`]: #homeconfigbuild-wrapallowtxt [`BUILD_WRAP_CMD` is expanded]: #how-build_wrap_cmd-is-expanded [`cc-rs`]: https://github.com/rust-lang/cc-rs [`sandbox-exec`]: https://keith.github.io/xcode-man-pages/sandbox-exec.1.html +[`svm-rs-builds`]: https://github.com/alloy-rs/svm-rs/tree/master/crates/svm-builds +[`svm-rs`]: https://github.com/alloy-rs/svm-rs [affect Bubblewrap]: https://github.com/containers/bubblewrap/issues/505#issuecomment-2093203129 [as it would `BUILD_WRAP_CMD`]: #how-build_wrap_cmd-is-expanded [changed with version 24.04]: https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces diff --git a/src/util/common.rs b/src/util/common.rs index 0492bbe..b8a35bd 100644 --- a/src/util/common.rs +++ b/src/util/common.rs @@ -4,7 +4,7 @@ use anyhow::{anyhow, bail, ensure, Context, Result}; use once_cell::sync::Lazy; use std::{ env, - fs::canonicalize, + fs::{canonicalize, read_to_string}, io::Write, os::unix::ffi::OsStrExt, path::Path, @@ -84,7 +84,7 @@ fn exec_sibling(sibling_path_as_str: &str) -> Result<()> { // They will cause the wrapped build script to be rerun, however. let expanded_args = split_and_expand(sibling_path)?; - let allow_enabled = enabled("BUILD_WRAP_ALLOW"); + let allow_enabled = enabled("BUILD_WRAP_ALLOW") || package_name_allowed(); let mut command = Command::new(&expanded_args[0]); command.args(&expanded_args[1..]); @@ -275,6 +275,22 @@ fn enabled(name: &str) -> bool { env::var(name).is_ok_and(|value| value != "0") } +static ALLOWED_PACKAGE_NAMES: Lazy> = Lazy::new(|| { + let base_directories = xdg::BaseDirectories::new().unwrap(); + let Some(allowed) = base_directories.find_config_file("build-wrap/allow.txt") else { + return Vec::new(); + }; + let contents = read_to_string(allowed).unwrap(); + contents.lines().map(ToOwned::to_owned).collect() +}); + +fn package_name_allowed() -> bool { + let Ok(package_name) = env::var("CARGO_PKG_NAME") else { + return false; + }; + ALLOWED_PACKAGE_NAMES.contains(&package_name) +} + #[cfg(test)] pub use test::assert_readme_contains_code_block; diff --git a/src/wrapper.rs b/src/wrapper.rs index bffdcc6..baf5bd5 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -44,6 +44,7 @@ publish = false anyhow = "1.0" once_cell = "1.19" tempfile = "3.10" +xdg = "2.5" "#; /// A wrapper build script's src/main.rs consists of the following: