From 06fd2569ec47f8a1f90d06814d53ca5897327e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 18 Sep 2024 14:17:59 +0300 Subject: [PATCH 01/23] chore: add `--env` argument to cargo near build/deploy commands --- Cargo.lock | 19 ++++++++--- Cargo.toml | 3 ++ .../src/types/near/build/input/mod.rs | 4 +++ cargo-near/Cargo.toml | 1 - cargo-near/src/commands/build_command/mod.rs | 32 +++++++++++++++++++ 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9fcd38f3..46442085 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -461,7 +461,6 @@ dependencies = [ "indicatif", "inquire", "interactive-clap", - "interactive-clap-derive", "linked-hash-map", "names", "near-cli-rs", @@ -1942,10 +1941,9 @@ dependencies = [ [[package]] name = "interactive-clap" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1e6acfe2ceaaa893a54c57d445a820d3b0fa4c6187b67b3f69fd07473c726e" +source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#04dd1267e78b31d2d950a4ff137855d7c2f76af0" dependencies = [ - "interactive-clap-derive", + "interactive-clap-derive 0.3.0 (git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr)", "strum", "strum_macros", ] @@ -1962,6 +1960,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "interactive-clap-derive" +version = "0.3.0" +source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#04dd1267e78b31d2d950a4ff137855d7c2f76af0" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ipnet" version = "2.10.0" @@ -2491,7 +2500,7 @@ dependencies = [ "indicatif", "inquire", "interactive-clap", - "interactive-clap-derive", + "interactive-clap-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "keyring", "linked-hash-map", "near-abi", diff --git a/Cargo.toml b/Cargo.toml index e4fbd613..80fe33f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,3 +51,6 @@ aarch64-unknown-linux-gnu = "ubuntu-arm64-22.04-4core" [workspace.metadata.dist.dependencies.apt] libudev-dev = { version = "*", targets = ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu"] } + +[patch.crates-io] +interactive-clap = { git = 'https://github.com/dj8yfo/interactive-clap.git', branch = 'multiple_vec_attr' } diff --git a/cargo-near-build/src/types/near/build/input/mod.rs b/cargo-near-build/src/types/near/build/input/mod.rs index 023e6788..41ce8d30 100644 --- a/cargo-near-build/src/types/near/build/input/mod.rs +++ b/cargo-near-build/src/types/near/build/input/mod.rs @@ -16,6 +16,7 @@ pub enum BuildContext { /// [std::default::Default] implementation is derived: /// - `false` for `bool`-s, /// - `None` - for `Option`-s +/// - empty vector - for `Vec` /// - delegates to [impl Default for CliDescription](struct.CliDescription.html#impl-Default-for-CliDescription) #[derive(Debug, Default, Clone)] pub struct Opts { @@ -43,6 +44,9 @@ pub struct Opts { /// description of cli command, where [BuildOpts](crate::BuildOpts) are being used from, either real /// or emulated pub cli_description: CliDescription, + /// additional environment key-value pairs, that should be passed to underlying + /// build commands + pub env: Vec<(String, String)>, } /// used as field in [BuildOpts](crate::BuildOpts) diff --git a/cargo-near/Cargo.toml b/cargo-near/Cargo.toml index 2fb82ff3..ad0b9002 100644 --- a/cargo-near/Cargo.toml +++ b/cargo-near/Cargo.toml @@ -39,7 +39,6 @@ names = { version = "0.14.0", default-features = false } derive_more = "0.99.9" shell-words = "1.0.0" interactive-clap = "0.3" -interactive-clap-derive = "0.3" near-cli-rs = { version = "0.15.0", default-features = false } reqwest = "0.12.5" indicatif = "0.17.8" diff --git a/cargo-near/src/commands/build_command/mod.rs b/cargo-near/src/commands/build_command/mod.rs index c6bfdc23..18970ddf 100644 --- a/cargo-near/src/commands/build_command/mod.rs +++ b/cargo-near/src/commands/build_command/mod.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use cargo_near_build::{env_keys, BuildArtifact, BuildContext, BuildOpts}; #[derive(Debug, Default, Clone, interactive_clap::InteractiveClap)] @@ -43,10 +45,23 @@ pub struct BuildCommand { #[interactive_clap(value_enum)] #[interactive_clap(skip_interactive_input)] pub color: Option, + /// env overrides in the form of `"KEY=VALUE"` strings + #[interactive_clap(long_vec_multiple_opt)] + pub env: Vec, } impl BuildCommand { + fn validate_env_opt(&self) -> color_eyre::eyre::Result<()> { + for pair in self.env.iter() { + pair.split_once('=').ok_or(color_eyre::eyre::eyre!( + "invalid \"key=value\" environment argument (must contain '='): {}", + pair + ))?; + } + Ok(()) + } pub fn run(self, context: BuildContext) -> color_eyre::eyre::Result { + self.validate_env_opt()?; if self.no_docker() { if let BuildContext::Deploy { skip_git_remote_check: true, @@ -83,10 +98,25 @@ impl From for BuildCommand { out_dir: value.out_dir, manifest_path: value.manifest_path, color: value.color, + env: value.env, } } } +fn get_env_key_vals(input: Vec) -> Vec<(String, String)> { + let iterator = input.iter().flat_map(|pair_string| { + pair_string + .split_once('=') + .map(|(env_key, value)| (env_key.to_string(), value.to_string())) + }); + + let dedup_map: HashMap = HashMap::from_iter(iterator); + + let result = dedup_map.into_iter().collect(); + tracing::trace!("passed additional environment pairs: {:#?}", result); + result +} + impl From for BuildOpts { fn from(value: BuildCommand) -> Self { Self { @@ -101,6 +131,7 @@ impl From for BuildOpts { manifest_path: value.manifest_path.map(Into::into), color: value.color.map(Into::into), cli_description: Default::default(), + env: get_env_key_vals(value.env), } } } @@ -124,6 +155,7 @@ impl BuildCommandlContext { features: scope.features.clone(), no_default_features: scope.no_default_features, color: scope.color.clone(), + env: scope.env.clone(), }; args.run(BuildContext::Build)?; Ok(Self) From e9e88e2d87ce317cf95216ac07b11e1fef8d3ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 18 Sep 2024 16:17:03 +0300 Subject: [PATCH 02/23] chore: update `interactive-clap` revision in Cargo.lock (patched from git version) --- Cargo.lock | 58 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46442085..0110b5f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arbitrary" @@ -157,9 +157,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -405,9 +405,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bytesize" @@ -480,9 +480,7 @@ dependencies = [ [[package]] name = "cargo-near-build" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "110e4e3b4dc5187c77581a49866018db00c1f4b1b108762aea203e1f35b14445" +version = "0.1.1" dependencies = [ "bs58 0.5.1", "camino", @@ -490,21 +488,31 @@ dependencies = [ "colored", "dunce", "eyre", + "git2", "hex", + "home", "libloading", - "log", "near-abi", + "nix", + "pathdiff", "rustc_version", "schemars", + "serde", "serde_json", "sha2 0.10.8", "symbolic-debuginfo", + "tempfile", + "tracing", + "unix_path", + "url", "zstd 0.13.2", ] [[package]] name = "cargo-near-build" version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd00f13698319e43d9af5b1afc7045131342f3097dd78320a09bb6303bbf2d06" dependencies = [ "bs58 0.5.1", "camino", @@ -512,23 +520,15 @@ dependencies = [ "colored", "dunce", "eyre", - "git2", "hex", - "home", "libloading", "near-abi", - "nix", - "pathdiff", "rustc_version", "schemars", - "serde", "serde_json", "sha2 0.10.8", "symbolic-debuginfo", - "tempfile", "tracing", - "unix_path", - "url", "zstd 0.13.2", ] @@ -606,9 +606,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.18" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "jobserver", "libc", @@ -1802,9 +1802,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1941,7 +1941,7 @@ dependencies = [ [[package]] name = "interactive-clap" version = "0.3.0" -source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#04dd1267e78b31d2d950a4ff137855d7c2f76af0" +source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#e0a04e2ffa903012baa467dbb6c67d0e4476498a" dependencies = [ "interactive-clap-derive 0.3.0 (git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr)", "strum", @@ -1963,7 +1963,7 @@ dependencies = [ [[package]] name = "interactive-clap-derive" version = "0.3.0" -source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#04dd1267e78b31d2d950a4ff137855d7c2f76af0" +source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#e0a04e2ffa903012baa467dbb6c67d0e4476498a" dependencies = [ "proc-macro-error", "proc-macro2", @@ -2842,7 +2842,7 @@ dependencies = [ "async-trait", "base64 0.22.1", "bs58 0.5.1", - "cargo-near-build 0.1.0", + "cargo-near-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono", "fs2", "json-patch", @@ -4611,9 +4611,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap 2.5.0", "serde", @@ -4806,9 +4806,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" From 8a323729d4841a1988ad35a6188858a3ea523737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 18 Sep 2024 16:54:39 +0300 Subject: [PATCH 03/23] chore: add `env` argument to `cargo_near_build::near::abi::generate` function --- cargo-near-build/src/near/abi/generate/mod.rs | 16 +++++++++---- cargo-near-build/src/near/abi/mod.rs | 1 + cargo-near-build/src/near/build/mod.rs | 24 ++++++++++++------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/cargo-near-build/src/near/abi/generate/mod.rs b/cargo-near-build/src/near/abi/generate/mod.rs index 921f4c08..7d588384 100644 --- a/cargo-near-build/src/near/abi/generate/mod.rs +++ b/cargo-near-build/src/near/abi/generate/mod.rs @@ -16,6 +16,7 @@ pub fn procedure( generate_docs: bool, hide_warnings: bool, cargo_feature_args: &[&str], + env: Vec<(&str, &str)>, color: ColorPreference, ) -> eyre::Result { let root_node = crate_metadata @@ -68,15 +69,20 @@ pub fn procedure( pretty_print::step("Generating ABI"); - let dylib_artifact = cargo_native::compile::run::( - &crate_metadata.manifest_path, - cargo_args.as_slice(), - vec![ + let compile_env = { + let mut compile_env = vec![ ("CARGO_PROFILE_DEV_OPT_LEVEL", "0"), ("CARGO_PROFILE_DEV_DEBUG", "0"), ("CARGO_PROFILE_DEV_LTO", "off"), (env_keys::BUILD_RS_ABI_STEP_HINT, "true"), - ], + ]; + compile_env.extend_from_slice(&env); + compile_env + }; + let dylib_artifact = cargo_native::compile::run::( + &crate_metadata.manifest_path, + cargo_args.as_slice(), + compile_env, hide_warnings, color, )?; diff --git a/cargo-near-build/src/near/abi/mod.rs b/cargo-near-build/src/near/abi/mod.rs index 59557926..337bafd2 100644 --- a/cargo-near-build/src/near/abi/mod.rs +++ b/cargo-near-build/src/near/abi/mod.rs @@ -38,6 +38,7 @@ pub fn build(args: abi_types::Opts) -> eyre::Result<()> { !args.no_doc, false, &[], + vec![], color, )?; let abi_types::Result { path } = write_to_file( diff --git a/cargo-near-build/src/near/build/mod.rs b/cargo-near-build/src/near/build/mod.rs index 3b5b8dd9..a2c49d76 100644 --- a/cargo-near-build/src/near/build/mod.rs +++ b/cargo-near-build/src/near/build/mod.rs @@ -76,14 +76,22 @@ pub fn run(args: Opts) -> eyre::Result { let (builder_version, builder_version_mismatch) = VersionMismatch::get_coerced_builder_version()?; if !args.no_abi { - let mut contract_abi = abi::generate::procedure( - &crate_metadata, - args.no_locked, - !args.no_doc, - true, - &cargo_feature_args, - color.clone(), - )?; + let mut contract_abi = { + let env = args + .env + .iter() + .map(|(key, value)| (key.as_ref(), value.as_ref())) + .collect::>(); + abi::generate::procedure( + &crate_metadata, + args.no_locked, + !args.no_doc, + true, + &cargo_feature_args, + env, + color.clone(), + )? + }; let embedding_binary = args.cli_description.cli_name_abi; contract_abi.metadata.build = Some(BuildInfo { From bb8e24b60f75a1077ed4bd600d165b60fb27e778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 18 Sep 2024 20:43:11 +0300 Subject: [PATCH 04/23] chore: update `interactive-clap` from crates.io --- Cargo.lock | 24 +++++++----------------- Cargo.toml | 3 --- cargo-near/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0110b5f4..b2ddfff0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1940,30 +1940,20 @@ dependencies = [ [[package]] name = "interactive-clap" -version = "0.3.0" -source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#e0a04e2ffa903012baa467dbb6c67d0e4476498a" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0f7ba4a74027eb091780d5f44c60ab8d7d7bcb0770af33ef024d4e7d1c8cf3" dependencies = [ - "interactive-clap-derive 0.3.0 (git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr)", + "interactive-clap-derive", "strum", "strum_macros", ] [[package]] name = "interactive-clap-derive" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab1ce8e6ef82771b125341b0a6bd5eb45888b01235aa61125ecc72cc22be4738" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "interactive-clap-derive" -version = "0.3.0" -source = "git+https://github.com/dj8yfo/interactive-clap.git?branch=multiple_vec_attr#e0a04e2ffa903012baa467dbb6c67d0e4476498a" +checksum = "bdced66b21ea0b5ce63c96e34ebfdadf05cf74594a5659d2bdd5d2c8cf586fa0" dependencies = [ "proc-macro-error", "proc-macro2", @@ -2500,7 +2490,7 @@ dependencies = [ "indicatif", "inquire", "interactive-clap", - "interactive-clap-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "interactive-clap-derive", "keyring", "linked-hash-map", "near-abi", diff --git a/Cargo.toml b/Cargo.toml index 80fe33f6..e4fbd613 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,3 @@ aarch64-unknown-linux-gnu = "ubuntu-arm64-22.04-4core" [workspace.metadata.dist.dependencies.apt] libudev-dev = { version = "*", targets = ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu"] } - -[patch.crates-io] -interactive-clap = { git = 'https://github.com/dj8yfo/interactive-clap.git', branch = 'multiple_vec_attr' } diff --git a/cargo-near/Cargo.toml b/cargo-near/Cargo.toml index ad0b9002..fdddbf2b 100644 --- a/cargo-near/Cargo.toml +++ b/cargo-near/Cargo.toml @@ -38,7 +38,7 @@ linked-hash-map = { version = "0.5", features = ["serde_impl"] } names = { version = "0.14.0", default-features = false } derive_more = "0.99.9" shell-words = "1.0.0" -interactive-clap = "0.3" +interactive-clap = "0.3.1" near-cli-rs = { version = "0.15.0", default-features = false } reqwest = "0.12.5" indicatif = "0.17.8" From 404981a050c05ddc8fc21bb0058e92e28d8d07f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 18 Sep 2024 20:54:24 +0300 Subject: [PATCH 05/23] feat: use external `env` field in `cargo_near_build::near::build::run` function --- cargo-near-build/src/cargo_native/compile.rs | 2 +- cargo-near-build/src/near/build/mod.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cargo-near-build/src/cargo_native/compile.rs b/cargo-near-build/src/cargo_native/compile.rs index 66d21771..c5f8f67f 100644 --- a/cargo-near-build/src/cargo_native/compile.rs +++ b/cargo-near-build/src/cargo_native/compile.rs @@ -134,7 +134,7 @@ where ColorPreference::Never => cmd.args(["--color", "never"]), }; - tracing::info!("Invoking cargo: {:?}", cmd); + tracing::info!("Invoking cargo: {:#?}", cmd); let mut child = cmd // capture the stdout to return from this function as bytes diff --git a/cargo-near-build/src/near/build/mod.rs b/cargo-near-build/src/near/build/mod.rs index a2c49d76..017a32c1 100644 --- a/cargo-near-build/src/near/build/mod.rs +++ b/cargo-near-build/src/near/build/mod.rs @@ -50,7 +50,15 @@ pub fn run(args: Opts) -> eyre::Result { let out_dir = crate_metadata.resolve_output_dir(args.out_dir.map(Into::into))?; - let mut build_env = vec![("RUSTFLAGS", "-C link-arg=-s")]; + let mut build_env = { + let mut build_env = vec![("RUSTFLAGS", "-C link-arg=-s")]; + build_env.extend( + args.env + .iter() + .map(|(key, value)| (key.as_ref(), value.as_ref())), + ); + build_env + }; let mut cargo_args = vec!["--target", COMPILATION_TARGET]; let cargo_feature_args = { let mut feat_args = vec![]; From 5b67da9832ac183f16e1b0078d06e6de1aa4d1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 18 Sep 2024 21:36:36 +0300 Subject: [PATCH 06/23] chore: add `env` flags to command export in `build::input::Opts::get_cli_build_command` in lib run variant --- .../src/types/near/build/input/mod.rs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/cargo-near-build/src/types/near/build/input/mod.rs b/cargo-near-build/src/types/near/build/input/mod.rs index 41ce8d30..0e5aa469 100644 --- a/cargo-near-build/src/types/near/build/input/mod.rs +++ b/cargo-near-build/src/types/near/build/input/mod.rs @@ -111,6 +111,16 @@ impl Opts { color = color_arg.to_string(); cargo_args.extend(&["--color", &color]); } + + let equal_pairs: Vec = self + .env + .iter() + .map(|(key, value)| [key.as_str(), value.as_str()].join("=")) + .collect(); + equal_pairs.iter().for_each(|equal_pair| { + cargo_args.extend(&["--env", &equal_pair]); + }); + cargo_args .into_iter() .map(|el| el.to_string()) @@ -167,3 +177,30 @@ impl ColorPreference { } } } + +#[cfg(test)] +mod tests { + + #[test] + fn test_opts_get_cli_build_command_for_env_vals() { + let opts = super::Opts { + env: vec![ + ("KEY".into(), "VALUE".into()), + ( + "GOOGLE_QUERY".into(), + "https://www.google.com/search?q=google+translate&sca_esv=3c150c50f502bc5d" + .into(), + ), + ], + ..Default::default() + }; + + assert_eq!(opts.get_cli_build_command(), ["cargo".to_string(), + "near".to_string(), + "build".to_string(), + "--env".to_string(), + "KEY=VALUE".to_string(), + "--env".to_string(), + "GOOGLE_QUERY=https://www.google.com/search?q=google+translate&sca_esv=3c150c50f502bc5d".to_string()]); + } +} From 982bcc7ac7d090dcce1e7ab3d8b90af201e2ee56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 18 Sep 2024 23:33:55 +0300 Subject: [PATCH 07/23] feat: add support of `--env` flag in docker build without cmd in manifest --- Cargo.lock | 1 + cargo-near-build/Cargo.toml | 3 +- .../src/near/docker_build/subprocess_step.rs | 11 +- .../types/near/build/input/docker_context.rs | 201 +++++++++++------- .../src/types/near/build/input/mod.rs | 2 +- 5 files changed, 140 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2ddfff0..dd416113 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -500,6 +500,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.8", + "shell-words", "symbolic-debuginfo", "tempfile", "tracing", diff --git a/cargo-near-build/Cargo.toml b/cargo-near-build/Cargo.toml index 75eb1936..e7f17bba 100644 --- a/cargo-near-build/Cargo.toml +++ b/cargo-near-build/Cargo.toml @@ -30,6 +30,7 @@ home = { version = "0.5.9", optional = true } pathdiff = { version = "0.2.1", features = ["camino"], optional = true } unix_path = { version = "1.0.1", optional = true } tempfile = { version = "3.10.1", optional = true } +shell-words = { version = "1.0.0", optional = true} [target.'cfg(target_os = "linux")'.dependencies] nix = { version = "0.29.0", features = ["user", "process"], optional = true } @@ -48,6 +49,6 @@ abi_build = [] docker = [ "dep:url", "dep:serde", "dep:git2", "dep:home", "dep:pathdiff", "dep:unix_path", - "dep:tempfile", "dep:nix" + "dep:tempfile", "dep:nix", "dep:shell-words" ] diff --git a/cargo-near-build/src/near/docker_build/subprocess_step.rs b/cargo-near-build/src/near/docker_build/subprocess_step.rs index 7ccda8df..4482aeab 100644 --- a/cargo-near-build/src/near/docker_build/subprocess_step.rs +++ b/cargo-near-build/src/near/docker_build/subprocess_step.rs @@ -46,8 +46,13 @@ pub fn run( let env = env_vars::EnvVars::new(&docker_build_meta, cloned_repo)?; let env_args = env.docker_args(); - let cargo_cmd = opts - .get_cli_build_command_in_docker(docker_build_meta.container_build_command.clone())?; + let cargo_cmd = { + let cargo_cmd = opts.get_cli_build_command_in_docker( + docker_build_meta.container_build_command.clone(), + )?; + tracing::debug!("cli_build_command_in_docker {:#?}", cargo_cmd); + shell_words::join(cargo_cmd) + }; println!("{} {}", "build command in container:".green(), cargo_cmd); let docker_args = { @@ -75,7 +80,7 @@ pub fn run( docker_args.extend(vec![&docker_image, "/bin/bash", "-c"]); docker_args.push(&cargo_cmd); - tracing::debug!("docker command : {:?}", docker_args); + tracing::debug!("docker command : {:#?}", docker_args); docker_args }; diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index 0f93fce1..91f00975 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -14,100 +14,155 @@ impl super::Opts { Ok(contract_path) } - const BUILD_COMMAND_CLI_CONFIG_ERR: &'static str = "cannot be used, when `container_build_command` is configured from `[package.metadata.near.reproducible_build]` in Cargo.toml"; + const BUILD_COMMAND_CLI_CONFIG_ERR: &'static str = "flag cannot be used, when `container_build_command` is configured from `[package.metadata.near.reproducible_build]` in Cargo.toml"; pub fn get_cli_build_command_in_docker( &self, manifest_command: Option>, - ) -> eyre::Result { - if let Some(manifest_command) = manifest_command { - // NOTE: `--no-locked` is allowed for docker builds - // if self.no_locked { - // no-op - // } - if self.no_release { - return Err(eyre::eyre!(format!( - "`{}` {}", - "--no-release", - Self::BUILD_COMMAND_CLI_CONFIG_ERR - ))); - } - if self.no_abi { - return Err(eyre::eyre!(format!( - "`{}` {}", - "--no-abi", - Self::BUILD_COMMAND_CLI_CONFIG_ERR - ))); - } - if self.no_embed_abi { - return Err(eyre::eyre!(format!( - "`{}` {}", - "--no-embed-abi", - Self::BUILD_COMMAND_CLI_CONFIG_ERR - ))); - } - if self.no_doc { - return Err(eyre::eyre!(format!( - "`{}` {}", - "--no-doc", - Self::BUILD_COMMAND_CLI_CONFIG_ERR - ))); - } - if self.features.is_some() { - return Err(eyre::eyre!(format!( - "`{}` {}", - "--features", - Self::BUILD_COMMAND_CLI_CONFIG_ERR - ))); - } - if self.no_default_features { - return Err(eyre::eyre!(format!( - "`{}` {}", - "--no-default-features", - Self::BUILD_COMMAND_CLI_CONFIG_ERR - ))); + ) -> eyre::Result> { + manifest_command.map_or_else( + || { + println!( + "{}", + "configuring `container_build_command` from cli args, passed to current command".cyan() + ); + Ok(self.passthrough_some_opts_into_docker_cmd()) + }, + |manifest_command| { + + self.check_conflicts_with_manifest_command()?; + Ok(manifest_command) } - return Ok(manifest_command.join(" ")); - } - println!( - "{}", - "configuring `container_build_command` from cli args, passed to current command".cyan() - ); - let mut cli_args = vec![]; + ) + } + + fn passthrough_some_opts_into_docker_cmd(&self) -> Vec { + let mut cli_args: Vec = vec![]; // NOTE: not passing through `no_locked` to cmd in container, // an invisible Cargo.lock was generated by implicit `cargo metadata` anyway // if self.no_locked { // no-op // } + + cli_args.extend(self.no_release.then_some("--no-release".into())); + cli_args.extend(self.no_abi.then_some("--no-abi".into())); + cli_args.extend(self.no_embed_abi.then_some("--no-embed-abi".into())); + cli_args.extend(self.no_doc.then_some("--no-doc".into())); + + cli_args.extend( + self.features + .clone() + .into_iter() + .flat_map(|features| ["--features".into(), features]), + ); + cli_args.extend( + self.no_default_features + .then_some("--no-default-features".into()), + ); + cli_args.extend( + self.color + .clone() + .into_iter() + .flat_map(|color| ["--color".into(), color.to_string()]), + ); + cli_args.extend(self.env.clone().into_iter().flat_map(|(key, value)| { + let equal_pair = [key, value].join("="); + ["--env".to_string(), equal_pair] + })); + + let mut cli_command_prefix = self.cli_description.cli_command_prefix.clone(); + cli_command_prefix.extend(cli_args); + cli_command_prefix + } + fn check_conflicts_with_manifest_command(&self) -> eyre::Result<()> { + // NOTE: `--no-locked` is allowed for docker builds + // if self.no_locked { + // no-op + // } if self.no_release { - cli_args.push("--no-release"); + return Err(eyre::eyre!(format!( + "`{}` {}", + "--no-release", + Self::BUILD_COMMAND_CLI_CONFIG_ERR + ))); } if self.no_abi { - cli_args.push("--no-abi"); + return Err(eyre::eyre!(format!( + "`{}` {}", + "--no-abi", + Self::BUILD_COMMAND_CLI_CONFIG_ERR + ))); } if self.no_embed_abi { - cli_args.push("--no-embed-abi"); + return Err(eyre::eyre!(format!( + "`{}` {}", + "--no-embed-abi", + Self::BUILD_COMMAND_CLI_CONFIG_ERR + ))); } if self.no_doc { - cli_args.push("--no-doc"); + return Err(eyre::eyre!(format!( + "`{}` {}", + "--no-doc", + Self::BUILD_COMMAND_CLI_CONFIG_ERR + ))); } - if let Some(ref features) = self.features { - cli_args.extend(&["--features", features]); + if self.features.is_some() { + return Err(eyre::eyre!(format!( + "`{}` {}", + "--features", + Self::BUILD_COMMAND_CLI_CONFIG_ERR + ))); } if self.no_default_features { - cli_args.push("--no-default-features"); + return Err(eyre::eyre!(format!( + "`{}` {}", + "--no-default-features", + Self::BUILD_COMMAND_CLI_CONFIG_ERR + ))); } - - let color; - if let Some(ref color_arg) = self.color { - color = color_arg.to_string(); - cli_args.extend(&["--color", &color]); + if !self.env.is_empty() { + return Err(eyre::eyre!(format!( + "`{}` {}", + "--env", + Self::BUILD_COMMAND_CLI_CONFIG_ERR + ))); } - let cli_command_prefix = self.cli_description.cli_command_prefix.clone(); - let mut cli_command_prefix: Vec<&str> = - cli_command_prefix.iter().map(|ele| ele.as_str()).collect(); - cli_command_prefix.extend(&cli_args); - let cli_command = cli_command_prefix.join(" "); - Ok(cli_command) + Ok(()) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_passthrough_some_opts_into_docker_cmd() { + let opts = crate::BuildOpts { + no_release: true, + no_abi: true, + no_embed_abi: true, + no_doc: true, + features: Some("cool_feature".into()), + no_default_features: true, + color: Some(crate::ColorPreference::Always), + ..Default::default() + }; + + assert_eq!( + opts.passthrough_some_opts_into_docker_cmd(), + vec![ + "cargo".to_string(), + "near".to_string(), + "build".to_string(), + "--no-release".to_string(), + "--no-abi".to_string(), + "--no-embed-abi".to_string(), + "--no-doc".to_string(), + "--features".to_string(), + "cool_feature".to_string(), + "--no-default-features".to_string(), + "--color".to_string(), + "always".to_string() + ], + ); } } diff --git a/cargo-near-build/src/types/near/build/input/mod.rs b/cargo-near-build/src/types/near/build/input/mod.rs index 0e5aa469..b895625e 100644 --- a/cargo-near-build/src/types/near/build/input/mod.rs +++ b/cargo-near-build/src/types/near/build/input/mod.rs @@ -118,7 +118,7 @@ impl Opts { .map(|(key, value)| [key.as_str(), value.as_str()].join("=")) .collect(); equal_pairs.iter().for_each(|equal_pair| { - cargo_args.extend(&["--env", &equal_pair]); + cargo_args.extend(&["--env", equal_pair]); }); cargo_args From 15a11c9484b26f02e2d774826c54bf199567681f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Thu, 19 Sep 2024 16:35:51 +0300 Subject: [PATCH 08/23] chore: split `metadata::ReproducibleBuild::validate` --- .../src/types/near/docker_build/metadata.rs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/cargo-near-build/src/types/near/docker_build/metadata.rs b/cargo-near-build/src/types/near/docker_build/metadata.rs index 140b595f..d1df766a 100644 --- a/cargo-near-build/src/types/near/docker_build/metadata.rs +++ b/cargo-near-build/src/types/near/docker_build/metadata.rs @@ -53,7 +53,7 @@ impl std::fmt::Display for ReproducibleBuild { } impl ReproducibleBuild { - fn validate(&self) -> eyre::Result<()> { + fn validate_image(&self) -> eyre::Result<()> { if self .image .chars() @@ -66,6 +66,9 @@ impl ReproducibleBuild { "`image`: string contains invalid characters", )); } + Ok(()) + } + fn validate_image_digest(&self) -> eyre::Result<()> { if self .image_digest .chars() @@ -78,6 +81,10 @@ impl ReproducibleBuild { "`image_digest`: string contains invalid characters", )); } + Ok(()) + } + fn validate_container_build_command(&self) -> eyre::Result<()> { + let is_cargo_near = { let build_command = self.container_build_command.clone().unwrap_or_default(); Some("cargo") == build_command.first().map(AsRef::as_ref) @@ -103,6 +110,10 @@ impl ReproducibleBuild { )); } } + Ok(()) + } + + fn validate_if_unknown_keys_present(&self) -> eyre::Result<()> { if !self.unknown_keys.is_empty() { let keys = self .unknown_keys @@ -114,6 +125,10 @@ impl ReproducibleBuild { keys.join(",") )); } + Ok(()) + } + + fn validate_repository(&self) -> eyre::Result<()> { match self.repository { Some(ref repository) => { if repository.scheme() != "https" { @@ -135,6 +150,15 @@ impl ReproducibleBuild { } Ok(()) } + + fn validate(&self) -> eyre::Result<()> { + self.validate_image()?; + self.validate_image_digest()?; + self.validate_container_build_command()?; + self.validate_if_unknown_keys_present()?; + self.validate_repository()?; + Ok(()) + } pub fn parse(cargo_metadata: &CrateMetadata) -> eyre::Result { let build_meta_value = cargo_metadata .root_package From f1b31985106f866df840f572b3503d440ec0f7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Thu, 19 Sep 2024 16:57:24 +0300 Subject: [PATCH 09/23] chore: add optional `passed_env` to toml manifest metadata for reproducible builds --- .../src/types/near/docker_build/metadata.rs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cargo-near-build/src/types/near/docker_build/metadata.rs b/cargo-near-build/src/types/near/docker_build/metadata.rs index d1df766a..073d6e64 100644 --- a/cargo-near-build/src/types/near/docker_build/metadata.rs +++ b/cargo-near-build/src/types/near/docker_build/metadata.rs @@ -11,6 +11,7 @@ use crate::types::cargo::metadata::CrateMetadata; pub struct ReproducibleBuild { image: String, image_digest: String, + pub passed_env: Option>, pub container_build_command: Option>, /// a clonable git remote url, /// currently, only ones, starting with `https://`, are supported; @@ -29,6 +30,16 @@ impl std::fmt::Display for ReproducibleBuild { writeln!(f, " {}: {}", "image", self.image)?; writeln!(f, " {}: {}", "image digest", self.image_digest)?; + if let Some(ref passed_env) = self.passed_env { + writeln!(f, " {}: {:?}", "passed environment variables", passed_env)?; + } else { + writeln!( + f, + " {}: {}", + "passed environment variables", + "ABSENT".green() + )?; + } if let Some(ref cmd) = self.container_build_command { writeln!(f, " {}: {:?}", "container build command", cmd)?; } else { @@ -84,7 +95,6 @@ impl ReproducibleBuild { Ok(()) } fn validate_container_build_command(&self) -> eyre::Result<()> { - let is_cargo_near = { let build_command = self.container_build_command.clone().unwrap_or_default(); Some("cargo") == build_command.first().map(AsRef::as_ref) @@ -157,6 +167,14 @@ impl ReproducibleBuild { self.validate_container_build_command()?; self.validate_if_unknown_keys_present()?; self.validate_repository()?; + + if self.passed_env.is_some() && self.container_build_command.is_none() { + return Err(eyre::eyre!( + "{}: \n{}", + "Malformed `[package.metadata.near.reproducible_build]` in Cargo.toml", + "using optional `passed_env` field requires that `container_build_command` is set too", + )); + } Ok(()) } pub fn parse(cargo_metadata: &CrateMetadata) -> eyre::Result { From 687502fe9464725ac05563136666bc05f3739462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Thu, 19 Sep 2024 22:26:01 +0300 Subject: [PATCH 10/23] feat: add arguments from `passed_env` in toml to cmd in docker --- .../src/near/docker_build/subprocess_step.rs | 2 ++ .../types/near/build/input/docker_context.rs | 28 ++++++++++++++++++- .../src/types/near/docker_build/metadata.rs | 6 +++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cargo-near-build/src/near/docker_build/subprocess_step.rs b/cargo-near-build/src/near/docker_build/subprocess_step.rs index 4482aeab..95d82ee5 100644 --- a/cargo-near-build/src/near/docker_build/subprocess_step.rs +++ b/cargo-near-build/src/near/docker_build/subprocess_step.rs @@ -49,11 +49,13 @@ pub fn run( let cargo_cmd = { let cargo_cmd = opts.get_cli_build_command_in_docker( docker_build_meta.container_build_command.clone(), + docker_build_meta.passed_env.clone(), )?; tracing::debug!("cli_build_command_in_docker {:#?}", cargo_cmd); shell_words::join(cargo_cmd) }; println!("{} {}", "build command in container:".green(), cargo_cmd); + println!(); let docker_args = { let mut docker_args = vec![ diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index 91f00975..97815874 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -19,6 +19,7 @@ impl super::Opts { pub fn get_cli_build_command_in_docker( &self, manifest_command: Option>, + passed_env: Option>, ) -> eyre::Result> { manifest_command.map_or_else( || { @@ -28,7 +29,32 @@ impl super::Opts { ); Ok(self.passthrough_some_opts_into_docker_cmd()) }, - |manifest_command| { + |mut manifest_command| { + let suffix_env = passed_env.into_iter().flatten().filter(|env_key| { + std::env::var(env_key).is_ok() + }).flat_map(|env_key| { + println!( + "{}{}{}", + "detected environment build parameter, which has been set: `".cyan(), + env_key.yellow(), + "`".cyan(), + ); + let value = std::env::var(&env_key).unwrap(); + let pair = [env_key, value].join("="); + ["--env".to_string(), pair] + }).collect::>(); + + if !suffix_env.is_empty() { + println!("{}{}{}", + "(listed in `".cyan(), + "passed_env".yellow(), + "` from `[package.metadata.near.reproducible_build]` in Cargo.toml)".cyan(), + ); + println!(); + } + + + manifest_command.extend(suffix_env); self.check_conflicts_with_manifest_command()?; Ok(manifest_command) diff --git a/cargo-near-build/src/types/near/docker_build/metadata.rs b/cargo-near-build/src/types/near/docker_build/metadata.rs index 073d6e64..03b32740 100644 --- a/cargo-near-build/src/types/near/docker_build/metadata.rs +++ b/cargo-near-build/src/types/near/docker_build/metadata.rs @@ -31,7 +31,11 @@ impl std::fmt::Display for ReproducibleBuild { writeln!(f, " {}: {}", "image", self.image)?; writeln!(f, " {}: {}", "image digest", self.image_digest)?; if let Some(ref passed_env) = self.passed_env { - writeln!(f, " {}: {:?}", "passed environment variables", passed_env)?; + writeln!( + f, + " {}: {:?}", + "passed environment variables", passed_env + )?; } else { writeln!( f, From 97670a8d13690f55c29aa8d669ae22f194ce2223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Thu, 19 Sep 2024 22:38:31 +0300 Subject: [PATCH 11/23] chore: update `near new` template with added `passed_env` manifest field --- .../new/new-project-template/Cargo.toml.template | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cargo-near/src/commands/new/new-project-template/Cargo.toml.template b/cargo-near/src/commands/new/new-project-template/Cargo.toml.template index 3d61f702..91331cd4 100644 --- a/cargo-near/src/commands/new/new-project-template/Cargo.toml.template +++ b/cargo-near/src/commands/new/new-project-template/Cargo.toml.template @@ -15,9 +15,14 @@ crate-type = ["cdylib", "rlib"] # in https://github.com/near/NEPs/blob/master/neps/nep-0330.md [package.metadata.near.reproducible_build] # docker image, descriptor of build environment -image = "sourcescan/cargo-near:0.8.2-rust-1.81.0" +# TODO: replace with git-image tag after publish +image = "sourcescan/cargo-near:git-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-1.81.0" # tag after colon above serves only descriptive purpose; image is identified by digest -image_digest = "sha256:3b5e6efa1d0cef710009f9cc20c845d316187cc170455edc5ba7fdf471c19655" +image_digest = "sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +# list of environment variables names, whose values, if set, will be used as external build parameters +# in a reproducible manner +# supported by `git-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-1.81.0` image or later images +passed_env = [] # build command inside of docker container # if docker image from default gallery is used https://hub.docker.com/r/sourcescan/cargo-near/tags, # the command may be any combination of flags of `cargo-near`, From d31c5a4021c8c9a353accfa3254169b0c7b2fbfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Fri, 20 Sep 2024 13:32:48 +0300 Subject: [PATCH 12/23] chore: add space for visual prowess --- cargo-near-build/src/types/near/build/input/docker_context.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index 97815874..6d1c1e59 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -27,6 +27,7 @@ impl super::Opts { "{}", "configuring `container_build_command` from cli args, passed to current command".cyan() ); + println!(); Ok(self.passthrough_some_opts_into_docker_cmd()) }, |mut manifest_command| { From 3693ba5670f51fb75b021ab8d0d66e26cde3f409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Fri, 20 Sep 2024 16:54:16 +0300 Subject: [PATCH 13/23] chore: move `check_flag_confilicts_with_manifest_command` to start of its block when manifest_command is set --- cargo-near-build/src/types/near/build/input/docker_context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index 6d1c1e59..472e04f5 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -31,6 +31,7 @@ impl super::Opts { Ok(self.passthrough_some_opts_into_docker_cmd()) }, |mut manifest_command| { + self.check_flag_conflicts_with_manifest_command()?; let suffix_env = passed_env.into_iter().flatten().filter(|env_key| { std::env::var(env_key).is_ok() }).flat_map(|env_key| { @@ -57,7 +58,6 @@ impl super::Opts { manifest_command.extend(suffix_env); - self.check_conflicts_with_manifest_command()?; Ok(manifest_command) } ) @@ -101,7 +101,7 @@ impl super::Opts { cli_command_prefix.extend(cli_args); cli_command_prefix } - fn check_conflicts_with_manifest_command(&self) -> eyre::Result<()> { + fn check_flag_conflicts_with_manifest_command(&self) -> eyre::Result<()> { // NOTE: `--no-locked` is allowed for docker builds // if self.no_locked { // no-op From 779467bba31f357272493b4a8f57df9a5170c775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Fri, 20 Sep 2024 17:00:11 +0300 Subject: [PATCH 14/23] chore: better error msg for `--env` flag conflict with `container_build_command` --- .../src/types/near/build/input/docker_context.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index 472e04f5..41a5839d 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -150,9 +150,10 @@ impl super::Opts { } if !self.env.is_empty() { return Err(eyre::eyre!(format!( - "`{}` {}", + "`{}` {}\n{}", "--env", - Self::BUILD_COMMAND_CLI_CONFIG_ERR + Self::BUILD_COMMAND_CLI_CONFIG_ERR, + "You can specify environment vars in `passed_env` list in `[package.metadata.near.reproducible_build]` instead" ))); } Ok(()) From 99c3be15af939c61bff63f833e6ba82b1af7c0ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Mon, 23 Sep 2024 14:38:50 +0300 Subject: [PATCH 15/23] chore: revert `cargo near new` template --- .../new/new-project-template/Cargo.toml.template | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cargo-near/src/commands/new/new-project-template/Cargo.toml.template b/cargo-near/src/commands/new/new-project-template/Cargo.toml.template index 91331cd4..3d61f702 100644 --- a/cargo-near/src/commands/new/new-project-template/Cargo.toml.template +++ b/cargo-near/src/commands/new/new-project-template/Cargo.toml.template @@ -15,14 +15,9 @@ crate-type = ["cdylib", "rlib"] # in https://github.com/near/NEPs/blob/master/neps/nep-0330.md [package.metadata.near.reproducible_build] # docker image, descriptor of build environment -# TODO: replace with git-image tag after publish -image = "sourcescan/cargo-near:git-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-1.81.0" +image = "sourcescan/cargo-near:0.8.2-rust-1.81.0" # tag after colon above serves only descriptive purpose; image is identified by digest -image_digest = "sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -# list of environment variables names, whose values, if set, will be used as external build parameters -# in a reproducible manner -# supported by `git-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-1.81.0` image or later images -passed_env = [] +image_digest = "sha256:3b5e6efa1d0cef710009f9cc20c845d316187cc170455edc5ba7fdf471c19655" # build command inside of docker container # if docker image from default gallery is used https://hub.docker.com/r/sourcescan/cargo-near/tags, # the command may be any combination of flags of `cargo-near`, From db47ac4bd5601fbecb7a3862d90660ba61ca9277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Mon, 23 Sep 2024 14:57:09 +0300 Subject: [PATCH 16/23] review: fix nit https://github.com/near/cargo-near/pull/226#discussion_r1770895121 --- cargo-near-build/src/near/abi/generate/mod.rs | 2 +- cargo-near-build/src/near/abi/mod.rs | 2 +- cargo-near-build/src/near/build/mod.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cargo-near-build/src/near/abi/generate/mod.rs b/cargo-near-build/src/near/abi/generate/mod.rs index 7d588384..81a12b1b 100644 --- a/cargo-near-build/src/near/abi/generate/mod.rs +++ b/cargo-near-build/src/near/abi/generate/mod.rs @@ -16,7 +16,7 @@ pub fn procedure( generate_docs: bool, hide_warnings: bool, cargo_feature_args: &[&str], - env: Vec<(&str, &str)>, + env: &[(&str, &str)], color: ColorPreference, ) -> eyre::Result { let root_node = crate_metadata diff --git a/cargo-near-build/src/near/abi/mod.rs b/cargo-near-build/src/near/abi/mod.rs index 337bafd2..0898a298 100644 --- a/cargo-near-build/src/near/abi/mod.rs +++ b/cargo-near-build/src/near/abi/mod.rs @@ -38,7 +38,7 @@ pub fn build(args: abi_types::Opts) -> eyre::Result<()> { !args.no_doc, false, &[], - vec![], + &[], color, )?; let abi_types::Result { path } = write_to_file( diff --git a/cargo-near-build/src/near/build/mod.rs b/cargo-near-build/src/near/build/mod.rs index 017a32c1..54a5b8c5 100644 --- a/cargo-near-build/src/near/build/mod.rs +++ b/cargo-near-build/src/near/build/mod.rs @@ -96,7 +96,7 @@ pub fn run(args: Opts) -> eyre::Result { !args.no_doc, true, &cargo_feature_args, - env, + &env, color.clone(), )? }; From 1f3f024dd3758303ea9b8ae44c9c96b960192a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Mon, 23 Sep 2024 15:15:02 +0300 Subject: [PATCH 17/23] review: fix nit https://github.com/near/cargo-near/pull/226#discussion_r1770897233 --- cargo-near-build/src/near/abi/generate/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cargo-near-build/src/near/abi/generate/mod.rs b/cargo-near-build/src/near/abi/generate/mod.rs index 81a12b1b..f2cda718 100644 --- a/cargo-near-build/src/near/abi/generate/mod.rs +++ b/cargo-near-build/src/near/abi/generate/mod.rs @@ -70,14 +70,13 @@ pub fn procedure( pretty_print::step("Generating ABI"); let compile_env = { - let mut compile_env = vec![ + let compile_env = vec![ ("CARGO_PROFILE_DEV_OPT_LEVEL", "0"), ("CARGO_PROFILE_DEV_DEBUG", "0"), ("CARGO_PROFILE_DEV_LTO", "off"), (env_keys::BUILD_RS_ABI_STEP_HINT, "true"), ]; - compile_env.extend_from_slice(&env); - compile_env + [&compile_env, env].concat() }; let dylib_artifact = cargo_native::compile::run::( &crate_metadata.manifest_path, From 1bbf544fdc33ef7c9811586c8b7b56eb85a6f4ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Mon, 23 Sep 2024 15:32:02 +0300 Subject: [PATCH 18/23] review: partially fix nit https://github.com/near/cargo-near/pull/226#discussion_r1770898758 --- cargo-near-build/src/near/build/mod.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/cargo-near-build/src/near/build/mod.rs b/cargo-near-build/src/near/build/mod.rs index 54a5b8c5..702d6db5 100644 --- a/cargo-near-build/src/near/build/mod.rs +++ b/cargo-near-build/src/near/build/mod.rs @@ -50,15 +50,12 @@ pub fn run(args: Opts) -> eyre::Result { let out_dir = crate_metadata.resolve_output_dir(args.out_dir.map(Into::into))?; - let mut build_env = { - let mut build_env = vec![("RUSTFLAGS", "-C link-arg=-s")]; - build_env.extend( - args.env - .iter() - .map(|(key, value)| (key.as_ref(), value.as_ref())), - ); - build_env - }; + let mut build_env = vec![("RUSTFLAGS", "-C link-arg=-s")]; + build_env.extend( + args.env + .iter() + .map(|(key, value)| (key.as_ref(), value.as_ref())), + ); let mut cargo_args = vec!["--target", COMPILATION_TARGET]; let cargo_feature_args = { let mut feat_args = vec![]; From e131c989381e2981810f89670bbc0082a3f4b437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Mon, 23 Sep 2024 15:57:58 +0300 Subject: [PATCH 19/23] review: somewhat fix nit https://github.com/near/cargo-near/pull/226#discussion_r1770902812 --- .../src/near/docker_build/subprocess_step.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cargo-near-build/src/near/docker_build/subprocess_step.rs b/cargo-near-build/src/near/docker_build/subprocess_step.rs index 95d82ee5..4b05385d 100644 --- a/cargo-near-build/src/near/docker_build/subprocess_step.rs +++ b/cargo-near-build/src/near/docker_build/subprocess_step.rs @@ -46,7 +46,7 @@ pub fn run( let env = env_vars::EnvVars::new(&docker_build_meta, cloned_repo)?; let env_args = env.docker_args(); - let cargo_cmd = { + let shell_escaped_cargo_cmd = { let cargo_cmd = opts.get_cli_build_command_in_docker( docker_build_meta.container_build_command.clone(), docker_build_meta.passed_env.clone(), @@ -54,7 +54,11 @@ pub fn run( tracing::debug!("cli_build_command_in_docker {:#?}", cargo_cmd); shell_words::join(cargo_cmd) }; - println!("{} {}", "build command in container:".green(), cargo_cmd); + println!( + "{} {}", + "build command in container:".green(), + shell_escaped_cargo_cmd + ); println!(); let docker_args = { @@ -81,7 +85,7 @@ pub fn run( docker_args.extend(vec![&docker_image, "/bin/bash", "-c"]); - docker_args.push(&cargo_cmd); + docker_args.push(&shell_escaped_cargo_cmd); tracing::debug!("docker command : {:#?}", docker_args); docker_args }; From e6a3be9e940dc8fb7aab07a7607b7973d4be11ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Tue, 24 Sep 2024 14:22:21 +0300 Subject: [PATCH 20/23] review: fix nit https://github.com/near/cargo-near/pull/226#discussion_r1770905350 --- .../types/near/build/input/docker_context.rs | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index 41a5839d..ac4991fb 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -21,46 +21,55 @@ impl super::Opts { manifest_command: Option>, passed_env: Option>, ) -> eyre::Result> { - manifest_command.map_or_else( - || { + if let Some(manifest_command) = manifest_command { + self.append_env_suffix(manifest_command, passed_env) + } else { + println!( + "{}", + "configuring `container_build_command` from cli args, passed to current command" + .cyan() + ); + println!(); + Ok(self.passthrough_some_opts_into_docker_cmd()) + } + } + + fn append_env_suffix( + &self, + mut manifest_command: Vec, + passed_env: Option>, + ) -> eyre::Result> { + self.check_flag_conflicts_with_manifest_command()?; + let suffix_env = passed_env + .into_iter() + .flatten() + .filter(|env_key| std::env::var(env_key).is_ok()) + .flat_map(|env_key| { println!( - "{}", - "configuring `container_build_command` from cli args, passed to current command".cyan() + "{}{}{}", + "detected environment build parameter, which has been set: `".cyan(), + env_key.yellow(), + "`".cyan(), ); - println!(); - Ok(self.passthrough_some_opts_into_docker_cmd()) - }, - |mut manifest_command| { - self.check_flag_conflicts_with_manifest_command()?; - let suffix_env = passed_env.into_iter().flatten().filter(|env_key| { - std::env::var(env_key).is_ok() - }).flat_map(|env_key| { - println!( - "{}{}{}", - "detected environment build parameter, which has been set: `".cyan(), - env_key.yellow(), - "`".cyan(), - ); - let value = std::env::var(&env_key).unwrap(); - let pair = [env_key, value].join("="); - ["--env".to_string(), pair] - }).collect::>(); - - if !suffix_env.is_empty() { - println!("{}{}{}", - "(listed in `".cyan(), - "passed_env".yellow(), - "` from `[package.metadata.near.reproducible_build]` in Cargo.toml)".cyan(), - ); - println!(); - } + let value = std::env::var(&env_key).unwrap(); + let pair = [env_key, value].join("="); + ["--env".to_string(), pair] + }) + .collect::>(); + if !suffix_env.is_empty() { + println!( + "{}{}{}", + "(listed in `".cyan(), + "passed_env".yellow(), + "` from `[package.metadata.near.reproducible_build]` in Cargo.toml)".cyan(), + ); + println!(); + } - manifest_command.extend(suffix_env); + manifest_command.extend(suffix_env); - Ok(manifest_command) - } - ) + Ok(manifest_command) } fn passthrough_some_opts_into_docker_cmd(&self) -> Vec { From 631367e30bc38f5fb3b12cf782824404ac17e445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Tue, 24 Sep 2024 14:31:36 +0300 Subject: [PATCH 21/23] review: fix nit https://github.com/near/cargo-near/pull/226#discussion_r1771132625 --- .../types/near/build/input/docker_context.rs | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index ac4991fb..b3bdc368 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -40,35 +40,36 @@ impl super::Opts { passed_env: Option>, ) -> eyre::Result> { self.check_flag_conflicts_with_manifest_command()?; - let suffix_env = passed_env - .into_iter() - .flatten() - .filter(|env_key| std::env::var(env_key).is_ok()) - .flat_map(|env_key| { + if let Some(passed_env) = passed_env { + let suffix_env = passed_env + .into_iter() + .filter(|env_key| std::env::var(env_key).is_ok()) + .flat_map(|env_key| { + println!( + "{}{}{}", + "detected environment build parameter, which has been set: `".cyan(), + env_key.yellow(), + "`".cyan(), + ); + let value = std::env::var(&env_key).unwrap(); + let pair = [env_key, value].join("="); + ["--env".to_string(), pair] + }) + .collect::>(); + + if !suffix_env.is_empty() { println!( "{}{}{}", - "detected environment build parameter, which has been set: `".cyan(), - env_key.yellow(), - "`".cyan(), + "(listed in `".cyan(), + "passed_env".yellow(), + "` from `[package.metadata.near.reproducible_build]` in Cargo.toml)".cyan(), ); - let value = std::env::var(&env_key).unwrap(); - let pair = [env_key, value].join("="); - ["--env".to_string(), pair] - }) - .collect::>(); + println!(); + } - if !suffix_env.is_empty() { - println!( - "{}{}{}", - "(listed in `".cyan(), - "passed_env".yellow(), - "` from `[package.metadata.near.reproducible_build]` in Cargo.toml)".cyan(), - ); - println!(); + manifest_command.extend(suffix_env); } - manifest_command.extend(suffix_env); - Ok(manifest_command) } From 62e21ae93008f832d981aa845b224bedc56beb72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Tue, 24 Sep 2024 14:49:55 +0300 Subject: [PATCH 22/23] review: fix nit https://github.com/near/cargo-near/pull/226#discussion_r1771135821 --- .../types/near/build/input/docker_context.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/cargo-near-build/src/types/near/build/input/docker_context.rs b/cargo-near-build/src/types/near/build/input/docker_context.rs index b3bdc368..c74e2bdc 100644 --- a/cargo-near-build/src/types/near/build/input/docker_context.rs +++ b/cargo-near-build/src/types/near/build/input/docker_context.rs @@ -86,22 +86,16 @@ impl super::Opts { cli_args.extend(self.no_embed_abi.then_some("--no-embed-abi".into())); cli_args.extend(self.no_doc.then_some("--no-doc".into())); - cli_args.extend( - self.features - .clone() - .into_iter() - .flat_map(|features| ["--features".into(), features]), - ); + if let Some(ref features) = self.features { + cli_args.extend(["--features".into(), features.clone()]); + } cli_args.extend( self.no_default_features .then_some("--no-default-features".into()), ); - cli_args.extend( - self.color - .clone() - .into_iter() - .flat_map(|color| ["--color".into(), color.to_string()]), - ); + if let Some(ref color) = self.color { + cli_args.extend(["--color".into(), color.to_string()]); + } cli_args.extend(self.env.clone().into_iter().flat_map(|(key, value)| { let equal_pair = [key, value].join("="); ["--env".to_string(), equal_pair] From 8f6dd73da062ff561897bc5c1c6174d4ab00144e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Tue, 24 Sep 2024 14:54:00 +0300 Subject: [PATCH 23/23] review: fix nit https://github.com/near/cargo-near/pull/226#discussion_r1771139255 --- cargo-near-build/src/types/near/build/input/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cargo-near-build/src/types/near/build/input/mod.rs b/cargo-near-build/src/types/near/build/input/mod.rs index b895625e..e5d4bd81 100644 --- a/cargo-near-build/src/types/near/build/input/mod.rs +++ b/cargo-near-build/src/types/near/build/input/mod.rs @@ -117,9 +117,9 @@ impl Opts { .iter() .map(|(key, value)| [key.as_str(), value.as_str()].join("=")) .collect(); - equal_pairs.iter().for_each(|equal_pair| { + for equal_pair in equal_pairs.iter() { cargo_args.extend(&["--env", equal_pair]); - }); + } cargo_args .into_iter()