diff --git a/Cargo.toml b/Cargo.toml index 6c0414f9..602ac88e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kit" -version = "0.2.0" +version = "0.2.1" edition = "2021" [build-dependencies] diff --git a/src/build/mod.rs b/src/build/mod.rs index 364baf4e..b3c94fa0 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -169,7 +169,10 @@ async fn compile_python_wasm_process(process_dir: &Path, python: &str) -> anyhow } #[instrument(level = "trace", err, skip_all)] -async fn compile_rust_wasm_process(process_dir: &Path) -> anyhow::Result<()> { +async fn compile_rust_wasm_process( + process_dir: &Path, + features: &str, +) -> anyhow::Result<()> { info!("Compiling Rust Kinode process in {:?}...", process_dir); // Paths @@ -218,18 +221,23 @@ async fn compile_rust_wasm_process(process_dir: &Path) -> anyhow::Result<()> { File::create(bindings_dir.join("world"))?; // Build the module using Cargo + let mut args = vec![ + "+nightly", + "build", + "--release", + "--no-default-features", + "--target", + "wasm32-wasi", + "--target-dir", + "target", + ]; + if !features.is_empty() { + args.push("--features"); + args.push(&features); + } run_command( Command::new("cargo") - .args(&[ - "+nightly", - "build", - "--release", - "--no-default-features", - "--target", - "wasm32-wasi", - "--target-dir", - "target", - ]) + .args(&args) .current_dir(process_dir), )?; @@ -341,14 +349,19 @@ async fn compile_package_and_ui( package_dir: &Path, valid_node: Option, skip_deps_check: bool, + features: &str, ) -> anyhow::Result<()> { compile_and_copy_ui(package_dir, valid_node).await?; - compile_package(package_dir, skip_deps_check).await?; + compile_package(package_dir, skip_deps_check, features).await?; Ok(()) } #[instrument(level = "trace", err, skip_all)] -async fn compile_package(package_dir: &Path, skip_deps_check: bool) -> anyhow::Result<()> { +async fn compile_package( + package_dir: &Path, + skip_deps_check: bool, + features: &str, +) -> anyhow::Result<()> { for entry in package_dir.read_dir()? { let entry = entry?; let path = entry.path(); @@ -358,7 +371,7 @@ async fn compile_package(package_dir: &Path, skip_deps_check: bool) -> anyhow::R let deps = check_rust_deps()?; get_deps(deps)?; } - compile_rust_wasm_process(&path).await?; + compile_rust_wasm_process(&path, features).await?; } else if path.join(PYTHON_SRC_PATH).exists() { let python = check_py_deps()?; compile_python_wasm_process(&path, &python).await?; @@ -382,6 +395,7 @@ pub async fn execute( no_ui: bool, ui_only: bool, skip_deps_check: bool, + features: &str, ) -> anyhow::Result<()> { if !package_dir.join("pkg").exists() { return Err(anyhow::anyhow!( @@ -397,11 +411,11 @@ pub async fn execute( "kit build: can't build UI: no ui directory exists" )); } else { - compile_package(package_dir, skip_deps_check).await + compile_package(package_dir, skip_deps_check, features).await } } else { if no_ui { - return compile_package(package_dir, skip_deps_check).await; + return compile_package(package_dir, skip_deps_check, features).await; } let deps = check_js_deps()?; @@ -411,7 +425,12 @@ pub async fn execute( if ui_only { compile_and_copy_ui(package_dir, valid_node).await } else { - compile_package_and_ui(package_dir, valid_node, skip_deps_check).await + compile_package_and_ui( + package_dir, + valid_node, + skip_deps_check, + features, + ).await } } } diff --git a/src/build_start_package/mod.rs b/src/build_start_package/mod.rs index 8a441a86..d52ac55a 100644 --- a/src/build_start_package/mod.rs +++ b/src/build_start_package/mod.rs @@ -12,8 +12,9 @@ pub async fn execute( ui_only: bool, url: &str, skip_deps_check: bool, + features: &str, ) -> anyhow::Result<()> { - build::execute(package_dir, no_ui, ui_only, skip_deps_check).await?; + build::execute(package_dir, no_ui, ui_only, skip_deps_check, features).await?; start_package::execute(package_dir, url).await?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index ad38b285..b8dc5b6c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -154,8 +154,12 @@ async fn execute( let no_ui = build_matches.get_one::("NO_UI").unwrap(); let ui_only = build_matches.get_one::("UI_ONLY").unwrap(); let skip_deps_check = build_matches.get_one::("SKIP_DEPS_CHECK").unwrap(); + let features = match build_matches.get_one::("FEATURES") { + Some(f) => f.clone(), + None => "".into(), + }; - build::execute(&package_dir, *no_ui, *ui_only, *skip_deps_check).await + build::execute(&package_dir, *no_ui, *ui_only, *skip_deps_check, &features).await }, Some(("build-start-package", build_start_matches)) => { @@ -170,6 +174,10 @@ async fn execute( }, }; let skip_deps_check = build_start_matches.get_one::("SKIP_DEPS_CHECK").unwrap(); + let features = match build_start_matches.get_one::("FEATURES") { + Some(f) => f.clone(), + None => "".into(), + }; build_start_package::execute( &package_dir, @@ -177,6 +185,7 @@ async fn execute( *ui_only, &url, *skip_deps_check, + &features, ).await }, Some(("dev-ui", dev_ui_matches)) => { @@ -438,6 +447,12 @@ async fn make_app(current_dir: &std::ffi::OsString) -> anyhow::Result { .help("If set, do not check for dependencies") .required(false) ) + .arg(Arg::new("FEATURES") + .action(ArgAction::Set) + .long("features") + .help("Pass these comma-delimited feature flags to Rust cargo builds") + .required(false) + ) ) .subcommand(Command::new("build-start-package") .about("Build and start a Kinode package") @@ -481,6 +496,12 @@ async fn make_app(current_dir: &std::ffi::OsString) -> anyhow::Result { .help("If set, do not check for dependencies") .required(false) ) + .arg(Arg::new("FEATURES") + .action(ArgAction::Set) + .long("features") + .help("Pass these comma-delimited feature flags to Rust cargo builds") + .required(false) + ) ) .subcommand(Command::new("dev-ui") .about("Start the web UI development server with hot reloading (same as `cd ui && npm i && npm start`)") diff --git a/src/run_tests/mod.rs b/src/run_tests/mod.rs index 7232b51c..c1d889bb 100644 --- a/src/run_tests/mod.rs +++ b/src/run_tests/mod.rs @@ -288,10 +288,10 @@ async fn run_tests( #[instrument(level = "trace", err, skip_all)] async fn handle_test(detached: bool, runtime_path: &Path, test: Test) -> anyhow::Result<()> { for setup_package_path in &test.setup_package_paths { - build::execute(&setup_package_path, false, false, false).await?; + build::execute(&setup_package_path, false, false, false, "").await?; } for TestPackage { ref path, .. } in &test.test_packages { - build::execute(path, false, false, false).await?; + build::execute(path, false, false, false, "").await?; } // Initialize variables for master node and nodes list