Repository: cargo-lambda/cargo-lambda (language: python)

Issue:
cargo lambda build --bin zipping all lambdas in project
I am in a mono-repo with a bunch of different bins and when I run the command to build with a single bin specified, and with the --verbose command I see that the majority of the time is spend on "checking function binary" of lots of binaries that I am not looking to build. 

Was wondering if this was expected behavior and there is a flag I'm missing or this is a bug and the code should be modified to not check the function binaries if a specific bin is specified? In the meanwhile during development I just comment out all of the other bins for faster development iterations. 


Discussion / hints:
Logs of what it looks like:
```
DEBUG run: checking function binary binary="/local/home/drydench/Workspace/ReplicatorWorkflow/src/ReplicatorRustLambdas/build/private/cargo-target/x86_64-unknown-linux-gnu/debug/features" exists=true
DEBUG run: checking function binary binary="/local/home/drydench/Workspace/ReplicatorWorkflow/src/ReplicatorRustLambdas/build/private/cargo-target/x86_64-unknown-linux-gnu/debug/validateInputs" exists=true

```

I have around 10 binaries so it ends up taking longer for this step than the rest of the workflow and when I comment out the binaries in the Cargo.toml the build to deploy to aws workflow speeds up 5x.
Feel free to propose any improvements to that code in a pull request.

Fix patch:
diff --git a/crates/cargo-lambda-build/src/lib.rs b/crates/cargo-lambda-build/src/lib.rs
index 6c85f560..4d84875a 100644
--- a/crates/cargo-lambda-build/src/lib.rs
+++ b/crates/cargo-lambda-build/src/lib.rs
@@ -10,6 +10,7 @@ use cargo_options::Build as CargoBuild;
 use clap::{Args, ValueHint};
 use miette::{IntoDiagnostic, Report, Result, WrapErr};
 use std::{
+    collections::HashSet,
     fs::create_dir_all,
     path::{Path, PathBuf},
     str::FromStr,
@@ -153,13 +154,20 @@ impl Build {
         let binaries = binary_targets_from_metadata(&metadata, build_examples);
         debug!(binaries = ?binaries, "found new target binaries to build");
 
-        if !self.build.bin.is_empty() {
+        let binaries = if !self.build.bin.is_empty() {
+            let mut final_binaries = HashSet::with_capacity(binaries.len());
+
             for name in &self.build.bin {
                 if !binaries.contains(name) {
                     return Err(BuildError::FunctionBinaryMissing(name.into()).into());
                 }
+                final_binaries.insert(name.into());
             }
-        }
+
+            final_binaries
+        } else {
+            binaries
+        };
 
         if compiler_option.is_local_cargo() {
             // This check only makes sense when the build host is local.


Test patch:
diff --git a/crates/cargo-lambda-cli/tests/cargo_lambda.rs b/crates/cargo-lambda-cli/tests/cargo_lambda.rs
index 6da17259..adc73e20 100644
--- a/crates/cargo-lambda-cli/tests/cargo_lambda.rs
+++ b/crates/cargo-lambda-cli/tests/cargo_lambda.rs
@@ -468,3 +468,61 @@ members = ["crates/{}", "crates/{}"]
             .success();
     }
 }
+
+#[test]
+fn test_build_zip_workspace() {
+    let _guard = init_root();
+    let workspace = project().build();
+    let crates = workspace.root().join("crates");
+    crates.mkdir_p();
+
+    let lp_1 = cargo_lambda_new_in_root("p1", &crates);
+    lp_1.new_cmd()
+        .arg("--no-interactive")
+        .arg(&lp_1.name)
+        .assert()
+        .success();
+
+    let lp_2 = cargo_lambda_new_in_root("p2", &crates);
+    lp_2.new_cmd()
+        .arg("--no-interactive")
+        .arg(&lp_2.name)
+        .assert()
+        .success();
+
+    let mut manifest = File::create(workspace.root().join("Cargo.toml"))
+        .expect("failed to create Cargo.toml file");
+    let content = format!(
+        r#"[workspace]
+resolver = "2"
+members = ["crates/{}", "crates/{}"]
+"#,
+        &lp_1.name, &lp_2.name
+    );
+    manifest
+        .write_all(content.as_bytes())
+        .expect("failed to create manifest content");
+    manifest.flush().unwrap();
+
+    // Build all binaries first. The second build should zip only one of them.
+    cargo_lambda_build(workspace.root()).assert().success();
+    let lp_1_bin = workspace
+        .lambda_dir()
+        .join(&lp_1.name)
+        .join("bootstrap.zip");
+    assert!(!lp_1_bin.exists(), "{:?} exist", lp_1_bin);
+    let lp_2_bin = workspace
+        .lambda_dir()
+        .join(&lp_2.name)
+        .join("bootstrap.zip");
+    assert!(!lp_2_bin.exists(), "{:?} exist", lp_2_bin);
+
+    cargo_lambda_build(workspace.root())
+        .args(["--bin", &lp_1.name, "--output-format", "zip"])
+        .assert()
+        .success();
+
+    assert!(lp_1_bin.exists(), "{:?} doesn't exist", lp_1_bin);
+    // The second zip file should not be created because we're using `--bin`.
+    assert!(!lp_2_bin.exists(), "{:?} exist", lp_2_bin);
+}