diff --git a/Cargo.lock b/Cargo.lock index 5f61caf57..5dc25077c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3552,6 +3552,7 @@ dependencies = [ "pubsys", "pubsys-setup", "serde", + "serde_json", "sha2", "tar", "tempfile", diff --git a/tests/projects/project1/Release.toml b/tests/projects/project1/Release.toml deleted file mode 100644 index 5820a7290..000000000 --- a/tests/projects/project1/Release.toml +++ /dev/null @@ -1 +0,0 @@ -version = "0.0.1" diff --git a/tests/projects/project1/variants/Cargo.lock b/tests/projects/project1/variants/Cargo.lock index 9291e5672..54165822b 100644 --- a/tests/projects/project1/variants/Cargo.lock +++ b/tests/projects/project1/variants/Cargo.lock @@ -2,14 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aws-test-1" -version = "0.1.0" -dependencies = [ - "hello-agent", - "hello-go", -] - [[package]] name = "hello-agent" version = "0.1.0" diff --git a/twoliter/Cargo.toml b/twoliter/Cargo.toml index ff1e85cd3..db7a8c81a 100644 --- a/twoliter/Cargo.toml +++ b/twoliter/Cargo.toml @@ -19,6 +19,7 @@ hex = "0.4" log = "0.4" non-empty-string = { version = "0.2", features = [ "serde" ] } serde = { version = "1", features = ["derive"] } +serde_json = "1" sha2 = "0.10" tar = "0.4" tempfile = "3" diff --git a/twoliter/embedded/Makefile.toml b/twoliter/embedded/Makefile.toml index 87b2c554a..d71d9d49f 100644 --- a/twoliter/embedded/Makefile.toml +++ b/twoliter/embedded/Makefile.toml @@ -22,7 +22,7 @@ BUILDSYS_VERSION_BUILD = { script = ["git describe --always --dirty --exclude '* # later in this section. You have to edit the path here in Makefile.toml to # use a different Release.toml. BUILDSYS_RELEASE_CONFIG_PATH = "${BUILDSYS_ROOT_DIR}/Release.toml" -BUILDSYS_VERSION_IMAGE = { script = ["awk -F '[ =\"]+' '$1 == \"version\" {print $2}' ${BUILDSYS_RELEASE_CONFIG_PATH}"] } + # This can be overridden with -e to build a different variant from the variants/ directory BUILDSYS_VARIANT = { script = ['echo "${BUILDSYS_VARIANT:-aws-k8s-1.24}"'] } # Product name used for file and directory naming @@ -137,6 +137,8 @@ TESTSYS_LOG_LEVEL = "info" # Certain variables are defined here to allow us to override a component value # on the command line. +BUILDSYS_VERSION_IMAGE = { script = ["awk -F '[ =\"]+' '$1 == \"version\" {print $2}' ${BUILDSYS_RELEASE_CONFIG_PATH}"], condition = { env_not_set = ["BUILDSYS_VERSION_IMAGE"]}} + # Depends on ${BUILDSYS_JOBS}. CARGO_MAKE_CARGO_LIMIT_JOBS = "--jobs ${BUILDSYS_JOBS}" CARGO_MAKE_CARGO_ARGS = "--offline --locked" diff --git a/twoliter/src/cmd/build.rs b/twoliter/src/cmd/build.rs index 36e78b430..bc967cb9e 100644 --- a/twoliter/src/cmd/build.rs +++ b/twoliter/src/cmd/build.rs @@ -2,6 +2,7 @@ use crate::cargo_make::CargoMake; use crate::docker::DockerContainer; use crate::project; use crate::tools::{install_tools, tools_tempdir}; +use crate::variant::variant_version; use anyhow::{Context, Result}; use clap::Parser; use log::debug; @@ -50,6 +51,8 @@ impl BuildVariant { .context("Unable to create a tempdir for Twoliter's build")?; let packages_dir = build_temp_dir.path().join("sdk_rpms"); fs::create_dir_all(&packages_dir)?; + let variant_version = + variant_version(&project.project_dir().join("variants"), &self.variant).await?; let sdk_container = DockerContainer::new( format!("sdk-{}", token), @@ -107,6 +110,7 @@ impl BuildVariant { .env("BUILDSYS_ARCH", &self.arch) .env("BUILDSYS_VARIANT", &self.variant) .env("BUILDSYS_SBKEYS_DIR", sbkeys_dir.display().to_string()) + .env("BUILDSYS_VERSION_IMAGE", variant_version) .makefile(makefile_path) .project_dir(project.project_dir()) .exec("build") diff --git a/twoliter/src/cmd/new.rs b/twoliter/src/cmd/new.rs new file mode 100644 index 000000000..e69de29bb diff --git a/twoliter/src/common.rs b/twoliter/src/common.rs index 9378614ee..32bfb9a9a 100644 --- a/twoliter/src/common.rs +++ b/twoliter/src/common.rs @@ -9,15 +9,16 @@ pub(crate) async fn exec_log(cmd: &mut Command) -> Result<()> { log::max_level(), LevelFilter::Off | LevelFilter::Error | LevelFilter::Warn ); - exec(cmd, quiet).await + exec(cmd, quiet).await?; + Ok(()) } /// Run a `tokio::process::Command` and return a `Result` letting us know whether or not it worked. /// `quiet` determines whether or not the command output will be piped to `stdout/stderr`. When -/// `quiet=true`, no output will be shown. -pub(crate) async fn exec(cmd: &mut Command, quiet: bool) -> Result<()> { +/// `quiet=true`, no output will be shown and will be returned instead. +pub(crate) async fn exec(cmd: &mut Command, quiet: bool) -> Result { debug!("Running: {:?}", cmd); - if quiet { + Ok(if quiet { // For quiet levels of logging we capture stdout and stderr let output = cmd .output() @@ -30,6 +31,8 @@ pub(crate) async fn exec(cmd: &mut Command, quiet: bool) -> Result<()> { String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr) ); + + String::from_utf8(output.stdout).context("Unable to convert command output to `String`")? } else { // For less quiet log levels we stream to stdout and stderr. let status = cmd @@ -42,6 +45,7 @@ pub(crate) async fn exec(cmd: &mut Command, quiet: bool) -> Result<()> { "Command was unsuccessful, exit code {}", status.code().unwrap_or(1), ); - } - Ok(()) + + "".to_string() + }) } diff --git a/twoliter/src/docker/container.rs b/twoliter/src/docker/container.rs index 7ccec0961..b16e51344 100644 --- a/twoliter/src/docker/container.rs +++ b/twoliter/src/docker/container.rs @@ -51,7 +51,8 @@ impl DockerContainer { let mut args = vec!["cp".to_string()]; args.push(format!("{}:{}", self.name, src.as_ref().display())); args.push(dest.as_ref().display().to_string()); - exec(Command::new("docker").args(args), true).await + exec(Command::new("docker").args(args), true).await?; + Ok(()) } } diff --git a/twoliter/src/main.rs b/twoliter/src/main.rs index 9a3ea4be6..37d544bbc 100644 --- a/twoliter/src/main.rs +++ b/twoliter/src/main.rs @@ -8,6 +8,7 @@ mod common; mod docker; mod project; mod tools; +mod variant; /// Test code that should only be compiled when running tests. #[cfg(test)] diff --git a/twoliter/src/test/data/variants/test-variant/Cargo.lock b/twoliter/src/test/data/variants/test-variant/Cargo.lock new file mode 100644 index 000000000..36277dfcd --- /dev/null +++ b/twoliter/src/test/data/variants/test-variant/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "test-variant" +version = "0.1.0" diff --git a/twoliter/src/test/data/variants/test-variant/Cargo.toml b/twoliter/src/test/data/variants/test-variant/Cargo.toml new file mode 100644 index 000000000..f9bc2cd35 --- /dev/null +++ b/twoliter/src/test/data/variants/test-variant/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "test-variant" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[workspace] diff --git a/twoliter/src/test/data/variants/test-variant/src/main.rs b/twoliter/src/test/data/variants/test-variant/src/main.rs new file mode 100644 index 000000000..e7a11a969 --- /dev/null +++ b/twoliter/src/test/data/variants/test-variant/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/twoliter/src/test/mod.rs b/twoliter/src/test/mod.rs index bead937ef..b49ad0970 100644 --- a/twoliter/src/test/mod.rs +++ b/twoliter/src/test/mod.rs @@ -5,6 +5,7 @@ be compiled for `cfg(test)`, which is accomplished at its declaration in `main.r !*/ mod cargo_make; +mod variant_version; use std::path::PathBuf; /// Return the canonical path to the directory where we store test data. diff --git a/twoliter/src/test/variant_version.rs b/twoliter/src/test/variant_version.rs new file mode 100644 index 000000000..0027a77fd --- /dev/null +++ b/twoliter/src/test/variant_version.rs @@ -0,0 +1,11 @@ +use crate::{test::data_dir, variant::variant_version}; + +#[tokio::test] +async fn test_variant_version() { + assert_eq!( + variant_version(&data_dir().join("variants"), "test-variant") + .await + .unwrap(), + "0.1.0" + ); +} diff --git a/twoliter/src/variant.rs b/twoliter/src/variant.rs new file mode 100644 index 000000000..195b68d17 --- /dev/null +++ b/twoliter/src/variant.rs @@ -0,0 +1,46 @@ +use crate::common::exec; +use anyhow::{Context, Result}; +use serde_json::Value; +use std::path::Path; +use tokio::process::Command; + +pub(crate) async fn variant_version(variants_dir: &Path, variant: S) -> Result +where + S: AsRef, +{ + serde_json::from_str::( + &exec( + Command::new("cargo").args([ + "metadata", + "--manifest-path", + &variants_dir + .join(variant.as_ref()) + .join("Cargo.toml") + .display() + .to_string(), + "--no-deps", + "--format-version", + "1", + ]), + true, + ) + .await?, + )? + .as_object() + .context("Unexpected output format from `cargo metadata`")? + .get("packages") + .and_then(Value::as_array) + .context("`packages` is not an array")? + .iter() + .find(|value| { + value + .as_object() + .map(|object| object.get("name") == Some(&Value::String(variant.as_ref().into()))) + .unwrap_or_default() + }) + .and_then(Value::as_object) + .and_then(|object| object.get("version")) + .and_then(Value::as_str) + .map(str::to_string) + .context("Unable to get variant version from Cargo.toml metadata") +}