Skip to content

Commit 57ab984

Browse files
feat(cli): add beforeBundleCommand, closes #4879 (#4893)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent 4c24d10 commit 57ab984

File tree

4 files changed

+83
-43
lines changed

4 files changed

+83
-43
lines changed

.changes/before-bundle-command.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri-utils": minor
3+
"cli.rs": minor
4+
"cli.js": minor
5+
---
6+
7+
Allow adding `build > beforeBundleCommand` in tauri.conf.json to run a shell command before the bundling phase.

core/tauri-utils/src/config.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,11 +2396,11 @@ pub enum BeforeDevCommand {
23962396
},
23972397
}
23982398

2399-
/// Describes the shell command to run before `tauri build`.
2399+
/// Describes a shell command to be executed when a CLI hook is triggered.
24002400
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
24012401
#[cfg_attr(feature = "schema", derive(JsonSchema))]
24022402
#[serde(rename_all = "camelCase", untagged)]
2403-
pub enum BeforeBuildCommand {
2403+
pub enum HookCommand {
24042404
/// Run the given script with the default options.
24052405
Script(String),
24062406
/// Run the given script with custom options.
@@ -2451,7 +2451,12 @@ pub struct BuildConfig {
24512451
///
24522452
/// The TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.
24532453
#[serde(alias = "before-build-command")]
2454-
pub before_build_command: Option<BeforeBuildCommand>,
2454+
pub before_build_command: Option<HookCommand>,
2455+
/// A shell command to run before the bundling phase in `tauri build` kicks in.
2456+
///
2457+
/// The TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.
2458+
#[serde(alias = "before-build-command")]
2459+
pub before_bundle_command: Option<HookCommand>,
24552460
/// Features passed to `cargo` commands.
24562461
pub features: Option<Vec<String>>,
24572462
/// Whether we should inject the Tauri API on `window.__TAURI__` or not.
@@ -2467,6 +2472,7 @@ impl Default for BuildConfig {
24672472
dist_dir: default_dist_dir(),
24682473
before_dev_command: None,
24692474
before_build_command: None,
2475+
before_bundle_command: None,
24702476
features: None,
24712477
with_global_tauri: false,
24722478
}
@@ -2679,6 +2685,7 @@ fn default_build() -> BuildConfig {
26792685
dist_dir: default_dist_dir(),
26802686
before_dev_command: None,
26812687
before_build_command: None,
2688+
before_bundle_command: None,
26822689
features: None,
26832690
with_global_tauri: false,
26842691
}
@@ -3146,6 +3153,7 @@ mod build {
31463153
let runner = quote!(None);
31473154
let before_dev_command = quote!(None);
31483155
let before_build_command = quote!(None);
3156+
let before_bundle_command = quote!(None);
31493157
let features = quote!(None);
31503158

31513159
literal_struct!(
@@ -3157,6 +3165,7 @@ mod build {
31573165
with_global_tauri,
31583166
before_dev_command,
31593167
before_build_command,
3168+
before_bundle_command,
31603169
features
31613170
);
31623171
}
@@ -3557,6 +3566,7 @@ mod test {
35573566
dist_dir: AppUrl::Url(WindowUrl::App("../dist".into())),
35583567
before_dev_command: None,
35593568
before_build_command: None,
3569+
before_bundle_command: None,
35603570
features: None,
35613571
with_global_tauri: false,
35623572
};

tooling/cli/schema.json

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,7 +2462,18 @@
24622462
"description": "A shell command to run before `tauri build` kicks in.\n\nThe TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.",
24632463
"anyOf": [
24642464
{
2465-
"$ref": "#/definitions/BeforeBuildCommand"
2465+
"$ref": "#/definitions/HookCommand"
2466+
},
2467+
{
2468+
"type": "null"
2469+
}
2470+
]
2471+
},
2472+
"beforeBundleCommand": {
2473+
"description": "A shell command to run before the bundling phase in `tauri build` kicks in.\n\nThe TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.",
2474+
"anyOf": [
2475+
{
2476+
"$ref": "#/definitions/HookCommand"
24662477
},
24672478
{
24682479
"type": "null"
@@ -2541,8 +2552,8 @@
25412552
}
25422553
]
25432554
},
2544-
"BeforeBuildCommand": {
2545-
"description": "Describes the shell command to run before `tauri build`.",
2555+
"HookCommand": {
2556+
"description": "Describes a shell command to be executed when a CLI hook is triggered.",
25462557
"anyOf": [
25472558
{
25482559
"description": "Run the given script with the default options.",

tooling/cli/src/build.rs

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ use crate::{
66
helpers::{
77
app_paths::{app_dir, tauri_dir},
88
command_env,
9-
config::{
10-
get as get_config, AppUrl, BeforeBuildCommand, WindowUrl, MERGE_CONFIG_EXTENSION_NAME,
11-
},
9+
config::{get as get_config, AppUrl, HookCommand, WindowUrl, MERGE_CONFIG_EXTENSION_NAME},
1210
updater_signature::{read_key_from_file, secret_key as updater_secret_key, sign_file},
1311
},
1412
interface::{AppInterface, AppSettings, Interface},
@@ -115,40 +113,7 @@ pub fn command(mut options: Options) -> Result<()> {
115113
}
116114

117115
if let Some(before_build) = config_.build.before_build_command.clone() {
118-
let (script, script_cwd) = match before_build {
119-
BeforeBuildCommand::Script(s) if s.is_empty() => (None, None),
120-
BeforeBuildCommand::Script(s) => (Some(s), None),
121-
BeforeBuildCommand::ScriptWithOptions { script, cwd } => (Some(script), cwd.map(Into::into)),
122-
};
123-
let cwd = script_cwd.unwrap_or_else(|| app_dir().clone());
124-
if let Some(before_build) = script {
125-
info!(action = "Running"; "beforeBuildCommand `{}`", before_build);
126-
#[cfg(target_os = "windows")]
127-
let status = Command::new("cmd")
128-
.arg("/S")
129-
.arg("/C")
130-
.arg(&before_build)
131-
.current_dir(cwd)
132-
.envs(command_env(options.debug))
133-
.piped()
134-
.with_context(|| format!("failed to run `{}` with `cmd /C`", before_build))?;
135-
#[cfg(not(target_os = "windows"))]
136-
let status = Command::new("sh")
137-
.arg("-c")
138-
.arg(&before_build)
139-
.current_dir(cwd)
140-
.envs(command_env(options.debug))
141-
.piped()
142-
.with_context(|| format!("failed to run `{}` with `sh -c`", before_build))?;
143-
144-
if !status.success() {
145-
bail!(
146-
"beforeBuildCommand `{}` failed with exit code {}",
147-
before_build,
148-
status.code().unwrap_or_default()
149-
);
150-
}
151-
}
116+
run_hook("beforeBuildCommand", before_build, options.debug)?;
152117
}
153118

154119
if let AppUrl::Url(WindowUrl::App(web_asset_path)) = &config_.build.dist_dir {
@@ -238,6 +203,13 @@ pub fn command(mut options: Options) -> Result<()> {
238203
}
239204
}
240205

206+
// if we have a package to bundle, let's run the `before_bundle_command`.
207+
if package_types.as_ref().map_or(true, |p| !p.is_empty()) {
208+
if let Some(before_bundle) = config_.build.before_bundle_command.clone() {
209+
run_hook("beforeBundleCommand", before_bundle, options.debug)?;
210+
}
211+
}
212+
241213
let settings = app_settings
242214
.get_bundler_settings(&options.into(), config_, out_dir, package_types)
243215
.with_context(|| "failed to build bundler settings")?;
@@ -337,6 +309,46 @@ pub fn command(mut options: Options) -> Result<()> {
337309
Ok(())
338310
}
339311

312+
fn run_hook(name: &str, hook: HookCommand, debug: bool) -> Result<()> {
313+
let (script, script_cwd) = match hook {
314+
HookCommand::Script(s) if s.is_empty() => (None, None),
315+
HookCommand::Script(s) => (Some(s), None),
316+
HookCommand::ScriptWithOptions { script, cwd } => (Some(script), cwd.map(Into::into)),
317+
};
318+
let cwd = script_cwd.unwrap_or_else(|| app_dir().clone());
319+
if let Some(script) = script {
320+
info!(action = "Running"; "{} `{}`", name, script);
321+
#[cfg(target_os = "windows")]
322+
let status = Command::new("cmd")
323+
.arg("/S")
324+
.arg("/C")
325+
.arg(&script)
326+
.current_dir(cwd)
327+
.envs(command_env(debug))
328+
.piped()
329+
.with_context(|| format!("failed to run `{}` with `cmd /C`", script))?;
330+
#[cfg(not(target_os = "windows"))]
331+
let status = Command::new("sh")
332+
.arg("-c")
333+
.arg(&script)
334+
.current_dir(cwd)
335+
.envs(command_env(debug))
336+
.piped()
337+
.with_context(|| format!("failed to run `{}` with `sh -c`", script))?;
338+
339+
if !status.success() {
340+
bail!(
341+
"{} `{}` failed with exit code {}",
342+
name,
343+
script,
344+
status.code().unwrap_or_default()
345+
);
346+
}
347+
}
348+
349+
Ok(())
350+
}
351+
340352
fn print_signed_updater_archive(output_paths: &[PathBuf]) -> crate::Result<()> {
341353
let pluralised = if output_paths.len() == 1 {
342354
"updater archive"

0 commit comments

Comments
 (0)