From 4a2471c22dfd46d7d42bf65d000cdcca08926c47 Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Wed, 15 Oct 2025 18:06:54 -0400 Subject: [PATCH] support building --example and --bin Signed-off-by: Jason Hall --- README.md | 12 ++++++++++++ src/builder/mod.rs | 32 ++++++++++++++++++++++++++++---- tests/testdata/build_example.txt | 26 ++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 tests/testdata/build_example.txt diff --git a/README.md b/README.md index 6a2fd17..aac3171 100644 --- a/README.md +++ b/README.md @@ -135,9 +135,21 @@ krust build ### Build with custom cargo arguments ```bash +# Build with features krust build -- --features=prod + +# Build an example binary +krust build -- --example http_server + +# Build a specific binary target +krust build -- --bin my-app + +# Combine multiple flags +krust build -- --example server --features=tls ``` +When building examples or specific binaries, krust automatically detects the correct binary name and path from the cargo arguments. + ## Supported Platforms - `linux/amd64` (x86_64-unknown-linux-musl) diff --git a/src/builder/mod.rs b/src/builder/mod.rs index a7c097c..5297e22 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -142,10 +142,12 @@ impl RustBuilder { } let binary_name = self.get_binary_name()?; - let binary_path = target_dir - .join(&self.target) - .join("release") - .join(&binary_name); + let binary_subdir = self.get_binary_subdir(); + let mut binary_path = target_dir.join(&self.target).join("release"); + if let Some(subdir) = binary_subdir { + binary_path = binary_path.join(subdir); + } + binary_path = binary_path.join(&binary_name); // Sometimes cargo build completes but the binary isn't immediately visible // due to filesystem sync issues. Give it a moment. @@ -169,6 +171,18 @@ impl RustBuilder { } fn get_binary_name(&self) -> Result { + // Check if --example or --bin was specified + let mut i = 0; + while i < self.cargo_args.len() { + if (self.cargo_args[i] == "--example" || self.cargo_args[i] == "--bin") + && i + 1 < self.cargo_args.len() + { + return Ok(self.cargo_args[i + 1].clone()); + } + i += 1; + } + + // Fall back to package name let cargo_toml_path = self.project_path.join("Cargo.toml"); let content = std::fs::read_to_string(&cargo_toml_path).context("Failed to read Cargo.toml")?; @@ -184,6 +198,16 @@ impl RustBuilder { Ok(name.to_string()) } + + fn get_binary_subdir(&self) -> Option<&str> { + // Check if --example was specified (examples go in "examples/" subdir) + for (i, arg) in self.cargo_args.iter().enumerate() { + if arg == "--example" && i + 1 < self.cargo_args.len() { + return Some("examples"); + } + } + None + } } pub fn get_rust_target_triple(platform: &str) -> Result { diff --git a/tests/testdata/build_example.txt b/tests/testdata/build_example.txt new file mode 100644 index 0000000..8c0179e --- /dev/null +++ b/tests/testdata/build_example.txt @@ -0,0 +1,26 @@ +# Test building examples with --example flag + +-- Cargo.toml -- +[package] +name = "test-app" +version = "0.1.0" +edition = "2021" + +[dependencies] +-- src/main.rs -- +fn main() { + println!("Hello from main!"); +} + +-- examples/example_server.rs -- +fn main() { + println!("Hello from example!"); +} + +# Build the example binary +[linux] env KRUST_REPO=ttl.sh/test exec ./krust build --no-push --platform linux/amd64 . -- --example example_server +[darwin] env KRUST_REPO=ttl.sh/test exec ./krust build --no-push --platform linux/amd64 . -- --example example_server +stderr 'Building Rust project' +stderr 'Successfully built binary' +stderr 'examples/example_server' +stderr 'Successfully built image'