Skip to content

Commit 5f1911c

Browse files
bicarlsenctron
authored andcommitted
feat: Added OS-specific hook overrides.
1 parent 0d0cbd3 commit 5f1911c

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

Trunk.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ stage = "build"
138138
command = "sh"
139139
command_arguments = ["-c", "echo Staging directory: $TRUNK_STAGING_DIR"]
140140

141+
[hooks.windows]
142+
# This shows how to create OS-specific overrides for hooks.
143+
# This will override the hook directly above it.
144+
# For overrides, only the `command` and `command_arguments` keys must be specified.
145+
# Valid values are `windows`, `macos`, and `linux`.
146+
command = "cmd"
147+
command_arguments = ["/c", "echo Staging directory: %TRUNK_STAGING_DIR%"]
148+
141149
[[hooks]]
142150
# This hook example shows how command_arguments defaults to an empty list when absent. It also uses
143151
# the post_build stage, meaning it executes after the rest of the build is complete, just before

site/content/assets.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ All hooks are executed using the same `stdin` and `stdout` as trunk. The executa
183183
- `TRUNK_DIST_DIR`: the full path of the Trunk dist directory.
184184
- `TRUNK_PUBLIC_URL`: the configured public URL for Trunk.
185185

186+
## OS-specific overrides
187+
188+
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.<os>]` entry where `<os>` 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`.
189+
186190
# Auto-Reload
187191

188192
As of `v0.14.0`, Trunk now ships with the ability to automatically reload your web app as the Trunk build pipeline completes.

src/config/models/hook.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,70 @@ pub struct Hook {
1010
/// The stage in the build process to execute this hook.
1111
pub stage: PipelineStage,
1212
/// The command to run for this hook.
13-
pub command: String,
13+
command: String,
1414
/// Any arguments to pass to the command.
1515
#[serde(default, skip_serializing_if = "Vec::is_empty")]
16+
command_arguments: Vec<String>,
17+
/// Overrides
18+
#[serde(default, flatten)]
19+
overrides: HookOverrides,
20+
}
21+
22+
impl Hook {
23+
pub fn command(&self) -> &String {
24+
if cfg!(target_os = "windows") {
25+
if let Some(cfg) = self.overrides.windows.as_ref() {
26+
return &cfg.command;
27+
}
28+
} else if cfg!(target_os = "macos") {
29+
if let Some(cfg) = self.overrides.macos.as_ref() {
30+
return &cfg.command;
31+
}
32+
} else if cfg!(target_os = "linux") {
33+
if let Some(cfg) = self.overrides.linux.as_ref() {
34+
return &cfg.command;
35+
}
36+
}
37+
38+
&self.command
39+
}
40+
41+
pub fn command_arguments(&self) -> &Vec<String> {
42+
if cfg!(target_os = "windows") {
43+
if let Some(cfg) = self.overrides.windows.as_ref() {
44+
return &cfg.command_arguments;
45+
}
46+
} else if cfg!(target_os = "macos") {
47+
if let Some(cfg) = self.overrides.macos.as_ref() {
48+
return &cfg.command_arguments;
49+
}
50+
} else if cfg!(target_os = "linux") {
51+
if let Some(cfg) = self.overrides.linux.as_ref() {
52+
return &cfg.command_arguments;
53+
}
54+
}
55+
56+
&self.command_arguments
57+
}
58+
}
59+
60+
/// Hook override config.
61+
#[derive(Clone, Debug, Deserialize, Default)]
62+
#[serde(rename_all = "snake_case")]
63+
pub struct HookOverrides {
64+
pub windows: Option<HookOverride>,
65+
pub macos: Option<HookOverride>,
66+
pub linux: Option<HookOverride>,
67+
}
68+
69+
/// OS-specific overrides.
70+
#[derive(Clone, Debug, Deserialize)]
71+
#[serde(rename_all = "snake_case")]
72+
pub struct HookOverride {
73+
/// The command to run for this hook.
74+
pub command: String,
75+
/// Any arguments to pass to the command.
76+
#[serde(default)]
1677
pub command_arguments: Vec<String>,
1778
}
1879

@@ -40,6 +101,7 @@ mod test {
40101
stage: PipelineStage::PreBuild,
41102
command: "foo".to_string(),
42103
command_arguments: vec![],
104+
overrides: HookOverrides::default(),
43105
}]),
44106
})
45107
.expect("must serialize");

src/hooks.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ pub fn spawn_hooks(cfg: Arc<RtcBuild>, stage: PipelineStage) -> HookHandles {
1414
.iter()
1515
.filter(|hook_cfg| hook_cfg.stage == stage)
1616
.map(|hook_cfg| {
17-
let mut command = Command::new(&hook_cfg.command);
17+
let mut command = Command::new(hook_cfg.command());
1818
command
1919
.current_dir(&cfg.core.working_directory)
20-
.args(&hook_cfg.command_arguments)
20+
.args(hook_cfg.command_arguments())
2121
.stdout(Stdio::inherit())
2222
.stderr(Stdio::inherit())
2323
.env("TRUNK_PROFILE", if cfg.release { "release" } else { "debug" })
@@ -27,9 +27,9 @@ pub fn spawn_hooks(cfg: Arc<RtcBuild>, stage: PipelineStage) -> HookHandles {
2727
.env("TRUNK_DIST_DIR", &cfg.final_dist)
2828
.env("TRUNK_PUBLIC_URL", &cfg.public_url);
2929

30-
tracing::info!(command_arguments = ?hook_cfg.command_arguments, "spawned hook {}", hook_cfg.command);
30+
tracing::info!(command_arguments = ?hook_cfg.command_arguments(), "spawned hook {}", hook_cfg.command());
3131

32-
let command_name = hook_cfg.command.clone();
32+
let command_name = hook_cfg.command().clone();
3333
tracing::info!(?stage, command = %command_name, "spawning hook");
3434
tokio::spawn(async move {
3535
let status = command

0 commit comments

Comments
 (0)