From f7bfa707d906ed92ded2917f3afd650e3620278e Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sat, 15 Feb 2025 14:11:45 +0100 Subject: [PATCH] add workspace --- examples/workplace/Cargo.lock | 9 ++- examples/workplace/Cargo.toml | 2 +- .../workplace/not-default-example/Cargo.toml | 15 ++++ .../workplace/not-default-example/index.html | 13 ++++ .../workplace/not-default-example/src/main.rs | 15 ++++ examples/workplace/simple-example/index.html | 2 +- src/config/models/mod.rs | 72 ++++++++++++------- src/config/models/source/workspace.rs | 21 +++++- src/main.rs | 29 ++++++-- 9 files changed, 143 insertions(+), 35 deletions(-) create mode 100644 examples/workplace/not-default-example/Cargo.toml create mode 100644 examples/workplace/not-default-example/index.html create mode 100644 examples/workplace/not-default-example/src/main.rs diff --git a/examples/workplace/Cargo.lock b/examples/workplace/Cargo.lock index b212b37d..4b3ecb99 100644 --- a/examples/workplace/Cargo.lock +++ b/examples/workplace/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "bumpalo" @@ -29,6 +29,13 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "not-default-example" +version = "0.1.0" +dependencies = [ + "web-sys", +] + [[package]] name = "once_cell" version = "1.19.0" diff --git a/examples/workplace/Cargo.toml b/examples/workplace/Cargo.toml index 2931b724..5d72d8b4 100644 --- a/examples/workplace/Cargo.toml +++ b/examples/workplace/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["simple-example"] +members = ["simple-example", "not-default-example"] default-members = ["simple-example"] [workspace.package] diff --git a/examples/workplace/not-default-example/Cargo.toml b/examples/workplace/not-default-example/Cargo.toml new file mode 100644 index 00000000..9f759699 --- /dev/null +++ b/examples/workplace/not-default-example/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "not-default-example" +version = "0.1.0" +authors = ["Jens Reimann "] +edition = "2021" + +[dependencies] +web-sys = { version = "0.3", features = [ + "console", + "Document", + "HtmlElement", + "Node", + "Text", + "Window", +] } diff --git a/examples/workplace/not-default-example/index.html b/examples/workplace/not-default-example/index.html new file mode 100644 index 00000000..b167c487 --- /dev/null +++ b/examples/workplace/not-default-example/index.html @@ -0,0 +1,13 @@ + + + + + + Trunk | No-Rust + + + + +

Trunk without WASM in workspace (not default target)

+ + diff --git a/examples/workplace/not-default-example/src/main.rs b/examples/workplace/not-default-example/src/main.rs new file mode 100644 index 00000000..014f8deb --- /dev/null +++ b/examples/workplace/not-default-example/src/main.rs @@ -0,0 +1,15 @@ +use web_sys::window; + +fn start_app() { + let document = window() + .and_then(|win| win.document()) + .expect("Could not access document"); + let body = document.body().expect("Could not access document.body"); + let text_node = document.create_text_node("Hello, world from Vanilla Rust!"); + body.append_child(text_node.as_ref()) + .expect("Failed to append text"); +} + +fn main() { + start_app(); +} diff --git a/examples/workplace/simple-example/index.html b/examples/workplace/simple-example/index.html index 58724fc4..67840ab2 100644 --- a/examples/workplace/simple-example/index.html +++ b/examples/workplace/simple-example/index.html @@ -8,6 +8,6 @@ -

Trunk without WASM

+

Trunk without WASM in workspace

diff --git a/src/config/models/mod.rs b/src/config/models/mod.rs index d5b02924..fb43efa5 100644 --- a/src/config/models/mod.rs +++ b/src/config/models/mod.rs @@ -30,7 +30,7 @@ use anyhow::{bail, Context, Result}; use schemars::JsonSchema; use serde::Deserialize; use source::{workspace, Source}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use tracing::log; /// Common configuration model functionality @@ -114,16 +114,53 @@ impl ConfigModel for Configuration { } } -pub async fn load_workspace_config(path: &PathBuf) -> Result> { - let cargo_toml = path.clone().join("Cargo.toml"); +pub async fn load_workspace_config( + current_path: &Path, + workspace_name: Option, +) -> Result> { + let cargo_toml = current_path.join("Cargo.toml"); if cargo_toml.exists() { - if let Ok(workspace) = workspace::workspace_from_manifest(cargo_toml).await { - if let Some(workspace) = workspace.get_default_workspace() { - // get the parent directory of the workspace - let workspace = workspace - .parent() - .context("unable to get parent directory of workspace")?; - return Ok(Some(workspace.to_path_buf())); + if let Ok(workspace) = workspace::workspace_from_manifest(&cargo_toml).await { + match workspace_name { + Some(name) => { + if let Some(workspace) = workspace.get_workspace_by_name(&name) { + // get the parent directory of the workspace + let workspace = match workspace.parent() { + Some(parent) => parent, + None => { + return Err(anyhow::format_err!( + "unable to get parent directory of workspace '{}'", + workspace.display() + )); + } + }; + return Ok(Some(workspace.to_path_buf())); + } + return Err(anyhow::format_err!( + "workspace '{}' not found in {}", + name, + cargo_toml.display() + )); + } + None => { + if let Some(workspace) = workspace.get_default_workspace() { + // get the parent directory of the workspace + let workspace = match workspace.parent() { + Some(parent) => parent, + None => { + return Err(anyhow::format_err!( + "unable to get parent directory of workspace '{}'", + workspace.display() + )); + } + }; + return Ok(Some(workspace.to_path_buf())); + } + return Err(anyhow::format_err!( + "default workspace not found in {}", + cargo_toml.display() + )); + } } } } @@ -152,25 +189,12 @@ pub async fn load(path: Option) -> Result<(Configuration, PathBuf)> { Ok((Source::File(path).load().await?, cwd)) } // if we have a directory, try finding a file and load it - Some(path) if path.is_dir() => { - let cwd = if let Some(new_cwd) = load_workspace_config(&path).await? { - new_cwd - } else { - path.clone() - }; - - Ok((Source::find(&path)?.load().await?, cwd)) - } + Some(path) if path.is_dir() => Ok((Source::find(&path)?.load().await?, path)), // if we have something else, we can't deal with it Some(path) => bail!("{} is neither a file nor a directory", path.display()), // if we have nothing, try to find a file in the current directory and load it None => { let cwd = std::env::current_dir().context("unable to get current directory")?; - let cwd = if let Some(new_cwd) = load_workspace_config(&cwd).await? { - new_cwd - } else { - cwd - }; Ok((Source::find(&cwd)?.load().await?, cwd)) } } diff --git a/src/config/models/source/workspace.rs b/src/config/models/source/workspace.rs index e6044463..01e048e5 100644 --- a/src/config/models/source/workspace.rs +++ b/src/config/models/source/workspace.rs @@ -17,11 +17,11 @@ impl WorkspaceConfig { .await .context("error awaiting spawned cargo metadata task")? .context("error getting cargo metadata")?; - return Ok(Self { metadata }); + Ok(Self { metadata }) } pub fn get_default_workspace(self) -> Option { - if let Some(default_members) = self.metadata.workspace_default_members.get(0) { + if let Some(default_members) = self.metadata.workspace_default_members.first() { if let Some(found) = self .metadata .packages @@ -33,6 +33,23 @@ impl WorkspaceConfig { } None } + + pub fn get_workspace_by_name(self, name: &str) -> Option { + // we search for the package in the workspace packages list + if let Some(one_package) = self.metadata.packages.iter().find(|m| m.name == name) { + // we check if the package is present in the workspace members list + if self + .metadata + .workspace_members + .into_iter() + .any(|p| p == one_package.id) + { + // we return the manifest path of the package + return Some(one_package.manifest_path.clone().into()); + } + } + None + } } /// Load the trunk configuration from the cargo manifest diff --git a/src/main.rs b/src/main.rs index 9a179396..649434b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ mod ws; use anyhow::{Context, Result}; use clap::{ArgAction, Parser, Subcommand, ValueEnum}; use common::STARTING; +use config::models::load_workspace_config; use std::io::IsTerminal; use std::path::PathBuf; use std::process::ExitCode; @@ -144,6 +145,9 @@ struct Trunk { /// Support for `NO_COLOR` environment variable #[arg(long, env = "NO_COLOR", global(true))] pub no_color: bool, + + #[arg(long = "workspace", env = "TRUNK_CRATE_WORKSPACE")] + pub crate_workspace: Option, } impl Trunk { @@ -174,13 +178,26 @@ impl Trunk { pub async fn run(self) -> Result<()> { version::update_check(self.skip_version_check | self.offline.unwrap_or_default()); + let cwd = std::env::current_dir().context("unable to get current directory")?; + let workspace_config = load_workspace_config(&cwd, self.crate_workspace).await?; + + let config_path = if let Some(config_path_from_workspace) = workspace_config { + tracing::info!( + "Loading config from {}", + config_path_from_workspace.display() + ); + Some(config_path_from_workspace) + } else { + self.config + }; + match self.action { - TrunkSubcommands::Build(inner) => inner.run(self.config).await, - TrunkSubcommands::Clean(inner) => inner.run(self.config).await, - TrunkSubcommands::Serve(inner) => inner.run(self.config).await, - TrunkSubcommands::Watch(inner) => inner.run(self.config).await, - TrunkSubcommands::Config(inner) => inner.run(self.config).await, - TrunkSubcommands::Tools(inner) => inner.run(self.config).await, + TrunkSubcommands::Build(inner) => inner.run(config_path).await, + TrunkSubcommands::Clean(inner) => inner.run(config_path).await, + TrunkSubcommands::Serve(inner) => inner.run(config_path).await, + TrunkSubcommands::Watch(inner) => inner.run(config_path).await, + TrunkSubcommands::Config(inner) => inner.run(config_path).await, + TrunkSubcommands::Tools(inner) => inner.run(config_path).await, } } }