From 247edbc5dbbf091bed6eebc17d054bf7a65a8305 Mon Sep 17 00:00:00 2001 From: Brian Carlsen Date: Thu, 12 Sep 2024 17:13:54 -0600 Subject: [PATCH] Added OS-specific overrides for hooks. --- Cargo.lock | 2 +- Cargo.toml | 2 +- Trunk.toml | 8 +++++ site/content/assets.md | 4 +++ src/config/models/hook.rs | 61 +++++++++++++++++++++++++++++++++++++++ src/hooks.rs | 8 ++--- 6 files changed, 79 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13f57e14..f3151a0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3598,7 +3598,7 @@ dependencies = [ [[package]] name = "trunk" -version = "0.20.3" +version = "0.20.4" dependencies = [ "ansi_term", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index fb1a1448..7a3f25d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trunk" -version = "0.20.3" +version = "0.20.4" edition = "2021" description = "Build, bundle & ship your Rust WASM application to the web." license = "MIT/Apache-2.0" diff --git a/Trunk.toml b/Trunk.toml index 300dae55..7ade5977 100644 --- a/Trunk.toml +++ b/Trunk.toml @@ -126,6 +126,14 @@ stage = "build" command = "sh" command_arguments = ["-c", "echo Staging directory: $TRUNK_STAGING_DIR"] +[hooks.windows] +# This shows how to create OS-specific overrides for hooks. +# This will override the hook directly above it. +# For overrides, only the `command` and `command_arguments` keys must be specified. +# Valid values are `windows`, `macos`, and `linux`. +command = "cmd" +command_arguments = ["/c", "echo Staging directory: %TRUNK_STAGING_DIR%"] + [[hooks]] # This hook example shows how command_arguments defaults to an empty list when absent. It also uses # the post_build stage, meaning it executes after the rest of the build is complete, just before diff --git a/site/content/assets.md b/site/content/assets.md index 20a7b28a..7d87ce82 100644 --- a/site/content/assets.md +++ b/site/content/assets.md @@ -183,6 +183,10 @@ All hooks are executed using the same `stdin` and `stdout` as trunk. The executa - `TRUNK_DIST_DIR`: the full path of the Trunk dist directory. - `TRUNK_PUBLIC_URL`: the configured public URL for Trunk. +## OS-specific overrides + +Often times you will want to perform the same build step on different OSes, requiring different commands. A typical example of this is using the `sh` command on Linux, but `cmd` on Windows. To accomodate this, you can optionally create OS-specific overrides for each hook. To do this, specify the default hook, then directly below it create a `[hooks.]` entry where `` can be one of `windows`, `macos`, or `linux`. Within this entry you must specify only the `command` and `command_argumnets` keys. You may provide multiple overrides for each hook. i.e. One for `windows`, one for `macos`, and one for `linux`. + # Auto-Reload As of `v0.14.0`, Trunk now ships with the ability to automatically reload your web app as the Trunk build pipeline completes. diff --git a/src/config/models/hook.rs b/src/config/models/hook.rs index 872a15f4..89f8ec40 100644 --- a/src/config/models/hook.rs +++ b/src/config/models/hook.rs @@ -7,6 +7,67 @@ use serde::Deserialize; pub struct ConfigOptsHook { /// The stage in the build process to execute this hook. pub stage: PipelineStage, + /// The command to run for this hook. + command: String, + /// Any arguments to pass to the command. + #[serde(default)] + command_arguments: Vec, + /// Overrides + #[serde(default, flatten)] + overrides: ConfigOptsHookOverrride, +} + +impl ConfigOptsHook { + pub fn command(&self) -> &String { + if cfg!(target_os = "windows") { + if let Some(cfg) = self.overrides.windows.as_ref() { + return &cfg.command; + } + } else if cfg!(target_os = "macos") { + if let Some(cfg) = self.overrides.macos.as_ref() { + return &cfg.command; + } + } else if cfg!(target_os = "linux") { + if let Some(cfg) = self.overrides.linux.as_ref() { + return &cfg.command; + } + } + + &self.command + } + + pub fn command_arguments(&self) -> &Vec { + if cfg!(target_os = "windows") { + if let Some(cfg) = self.overrides.windows.as_ref() { + return &cfg.command_arguments; + } + } else if cfg!(target_os = "macos") { + if let Some(cfg) = self.overrides.macos.as_ref() { + return &cfg.command_arguments; + } + } else if cfg!(target_os = "linux") { + if let Some(cfg) = self.overrides.linux.as_ref() { + return &cfg.command_arguments; + } + } + + &self.command_arguments + } +} + +/// Config options for build system hooks. +#[derive(Clone, Debug, Deserialize, Default)] +#[serde(rename_all = "snake_case")] +pub struct ConfigOptsHookOverrride { + pub windows: Option, + pub macos: Option, + pub linux: Option, +} + +/// OS-specific overrides. +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "snake_case")] +pub struct ConfigOptsHookOs { /// The command to run for this hook. pub command: String, /// Any arguments to pass to the command. diff --git a/src/hooks.rs b/src/hooks.rs index f5850fa5..94147b06 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -19,9 +19,9 @@ pub fn spawn_hooks(cfg: Arc, stage: PipelineStage) -> HookHandles { .iter() .filter(|hook_cfg| hook_cfg.stage == stage) .map(|hook_cfg| { - let mut command = Command::new(&hook_cfg.command); + let mut command = Command::new(hook_cfg.command()); command - .args(&hook_cfg.command_arguments) + .args(hook_cfg.command_arguments()) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .env("TRUNK_PROFILE", if cfg.release { "release" } else { "debug" }) @@ -31,9 +31,9 @@ pub fn spawn_hooks(cfg: Arc, stage: PipelineStage) -> HookHandles { .env("TRUNK_DIST_DIR", &cfg.final_dist) .env("TRUNK_PUBLIC_URL", &cfg.public_url); - tracing::info!(command_arguments = ?hook_cfg.command_arguments, "spawned hook {}", hook_cfg.command); + tracing::info!(command_arguments = ?hook_cfg.command_arguments(), "spawned hook {}", hook_cfg.command()); - let command_name = hook_cfg.command.clone(); + let command_name = hook_cfg.command().clone(); tracing::info!(?stage, command = %command_name, "spawning hook"); tokio::spawn(async move { let status = command