|
2 | 2 | // SPDX-License-Identifier: Apache-2.0 |
3 | 3 | // SPDX-License-Identifier: MIT |
4 | 4 |
|
5 | | -use crate::helpers::{ |
6 | | - app_paths::{app_dir, tauri_dir}, |
7 | | - command_env, |
8 | | - config::{get as get_config, AppUrl, WindowUrl}, |
9 | | - manifest::rewrite_manifest, |
10 | | - updater_signature::sign_file_from_env_variables, |
| 5 | +use crate::{ |
| 6 | + helpers::{ |
| 7 | + app_paths::{app_dir, tauri_dir}, |
| 8 | + command_env, |
| 9 | + config::{get as get_config, AppUrl, WindowUrl}, |
| 10 | + manifest::rewrite_manifest, |
| 11 | + updater_signature::sign_file_from_env_variables, |
| 12 | + }, |
| 13 | + interface::{AppInterface, AppSettings, Interface}, |
| 14 | + CommandExt, Result, |
11 | 15 | }; |
12 | | -use crate::{CommandExt, Result}; |
13 | 16 | use anyhow::{bail, Context}; |
14 | 17 | use clap::Parser; |
15 | | -#[cfg(target_os = "linux")] |
16 | | -use heck::ToKebabCase; |
17 | 18 | use log::warn; |
18 | 19 | use log::{error, info}; |
19 | | -use std::{env::set_current_dir, fs::rename, path::PathBuf, process::Command}; |
| 20 | +use std::{env::set_current_dir, path::PathBuf, process::Command}; |
20 | 21 | use tauri_bundler::bundle::{bundle_project, PackageType}; |
21 | 22 |
|
22 | | -#[derive(Debug, Parser)] |
| 23 | +#[derive(Debug, Clone, Parser)] |
23 | 24 | #[clap(about = "Tauri build")] |
24 | 25 | pub struct Options { |
25 | 26 | /// Binary to use to build the application, defaults to `cargo` |
26 | 27 | #[clap(short, long)] |
27 | | - runner: Option<String>, |
| 28 | + pub runner: Option<String>, |
28 | 29 | /// Builds with the debug flag |
29 | 30 | #[clap(short, long)] |
30 | | - debug: bool, |
| 31 | + pub debug: bool, |
31 | 32 | /// Target triple to build against. |
32 | 33 | /// |
33 | 34 | /// It must be one of the values outputted by `$rustc --print target-list` or `universal-apple-darwin` for an universal macOS application. |
34 | 35 | /// |
35 | 36 | /// Note that compiling an universal macOS application requires both `aarch64-apple-darwin` and `x86_64-apple-darwin` targets to be installed. |
36 | 37 | #[clap(short, long)] |
37 | | - target: Option<String>, |
| 38 | + pub target: Option<String>, |
38 | 39 | /// Space or comma separated list of features to activate |
39 | 40 | #[clap(short, long, multiple_occurrences(true), multiple_values(true))] |
40 | | - features: Option<Vec<String>>, |
| 41 | + pub features: Option<Vec<String>>, |
41 | 42 | /// Space or comma separated list of bundles to package. |
42 | 43 | /// |
43 | 44 | /// Each bundle must be one of `deb`, `appimage`, `msi`, `app` or `dmg` on MacOS and `updater` on all platforms. |
| 45 | + /// If `none` is specified, the bundler will be skipped. |
44 | 46 | /// |
45 | 47 | /// Note that the `updater` bundle is not automatically added so you must specify it if the updater is enabled. |
46 | 48 | #[clap(short, long, multiple_occurrences(true), multiple_values(true))] |
47 | | - bundles: Option<Vec<String>>, |
| 49 | + pub bundles: Option<Vec<String>>, |
48 | 50 | /// JSON string or path to JSON file to merge with tauri.conf.json |
49 | 51 | #[clap(short, long)] |
50 | | - config: Option<String>, |
| 52 | + pub config: Option<String>, |
51 | 53 | /// Command line arguments passed to the runner |
52 | | - args: Vec<String>, |
| 54 | + pub args: Vec<String>, |
53 | 55 | } |
54 | 56 |
|
55 | | -pub fn command(options: Options) -> Result<()> { |
| 57 | +pub fn command(mut options: Options) -> Result<()> { |
56 | 58 | let merge_config = if let Some(config) = &options.config { |
57 | 59 | Some(if config.starts_with('{') { |
58 | 60 | config.to_string() |
@@ -150,116 +152,30 @@ pub fn command(options: Options) -> Result<()> { |
150 | 152 | } |
151 | 153 | } |
152 | 154 |
|
153 | | - let runner_from_config = config_.build.runner.clone(); |
154 | | - let runner = options |
155 | | - .runner |
156 | | - .or(runner_from_config) |
157 | | - .unwrap_or_else(|| "cargo".to_string()); |
158 | | - |
159 | | - let mut features = config_.build.features.clone().unwrap_or_default(); |
160 | | - if let Some(list) = options.features { |
161 | | - features.extend(list); |
162 | | - } |
163 | | - |
164 | | - let mut args = Vec::new(); |
165 | | - if !options.args.is_empty() { |
166 | | - args.extend(options.args); |
167 | | - } |
168 | | - |
169 | | - if !features.is_empty() { |
170 | | - args.push("--features".into()); |
171 | | - args.push(features.join(",")); |
172 | | - } |
173 | | - |
174 | | - if !options.debug { |
175 | | - args.push("--release".into()); |
176 | | - } |
177 | | - |
178 | | - let app_settings = crate::interface::rust::AppSettings::new(config_)?; |
179 | | - |
180 | | - let out_dir = app_settings |
181 | | - .get_out_dir(options.target.clone(), options.debug) |
182 | | - .with_context(|| "failed to get project out directory")?; |
183 | | - |
184 | | - let bin_name = app_settings |
185 | | - .cargo_package_settings() |
186 | | - .name |
187 | | - .clone() |
188 | | - .expect("Cargo manifest must have the `package.name` field"); |
189 | | - |
190 | | - let target: String = if let Some(target) = options.target.clone() { |
191 | | - target |
192 | | - } else { |
193 | | - tauri_utils::platform::target_triple()? |
194 | | - }; |
195 | | - let binary_extension: String = if target.contains("windows") { |
196 | | - "exe" |
197 | | - } else { |
198 | | - "" |
| 155 | + if options.runner.is_none() { |
| 156 | + options.runner = config_.build.runner.clone(); |
199 | 157 | } |
200 | | - .into(); |
201 | | - |
202 | | - let bin_path = out_dir.join(&bin_name).with_extension(&binary_extension); |
203 | | - |
204 | | - let no_default_features = args.contains(&"--no-default-features".into()); |
205 | | - |
206 | | - if options.target == Some("universal-apple-darwin".into()) { |
207 | | - std::fs::create_dir_all(&out_dir).with_context(|| "failed to create project out directory")?; |
208 | | - |
209 | | - let mut lipo_cmd = Command::new("lipo"); |
210 | | - lipo_cmd |
211 | | - .arg("-create") |
212 | | - .arg("-output") |
213 | | - .arg(out_dir.join(&bin_name)); |
214 | | - for triple in ["aarch64-apple-darwin", "x86_64-apple-darwin"] { |
215 | | - let mut args_ = args.clone(); |
216 | | - args_.push("--target".into()); |
217 | | - args_.push(triple.into()); |
218 | | - crate::interface::rust::build_project(runner.clone(), args_) |
219 | | - .with_context(|| format!("failed to build {} binary", triple))?; |
220 | | - let triple_out_dir = app_settings |
221 | | - .get_out_dir(Some(triple.into()), options.debug) |
222 | | - .with_context(|| format!("failed to get {} out dir", triple))?; |
223 | | - lipo_cmd.arg(triple_out_dir.join(&bin_name)); |
224 | | - } |
225 | 158 |
|
226 | | - let lipo_status = lipo_cmd.status()?; |
227 | | - if !lipo_status.success() { |
228 | | - return Err(anyhow::anyhow!(format!( |
229 | | - "Result of `lipo` command was unsuccessful: {}. (Is `lipo` installed?)", |
230 | | - lipo_status |
231 | | - ))); |
232 | | - } |
233 | | - } else { |
234 | | - if let Some(target) = &options.target { |
235 | | - args.push("--target".into()); |
236 | | - args.push(target.clone()); |
237 | | - } |
238 | | - crate::interface::rust::build_project(runner, args).with_context(|| "failed to build app")?; |
| 159 | + if let Some(list) = options.features.as_mut() { |
| 160 | + list.extend(config_.build.features.clone().unwrap_or_default()); |
239 | 161 | } |
240 | 162 |
|
241 | | - if let Some(product_name) = config_.package.product_name.clone() { |
242 | | - #[cfg(target_os = "linux")] |
243 | | - let product_name = product_name.to_kebab_case(); |
| 163 | + let interface = AppInterface::new(config_)?; |
| 164 | + let app_settings = interface.app_settings(); |
| 165 | + let interface_options = options.clone().into(); |
244 | 166 |
|
245 | | - let product_path = out_dir |
246 | | - .join(&product_name) |
247 | | - .with_extension(&binary_extension); |
| 167 | + let bin_path = app_settings.app_binary_path(&interface_options)?; |
| 168 | + let out_dir = bin_path.parent().unwrap(); |
248 | 169 |
|
249 | | - rename(&bin_path, &product_path).with_context(|| { |
250 | | - format!( |
251 | | - "failed to rename `{}` to `{}`", |
252 | | - bin_path.display(), |
253 | | - product_path.display(), |
254 | | - ) |
255 | | - })?; |
256 | | - } |
| 170 | + interface |
| 171 | + .build(interface_options) |
| 172 | + .with_context(|| "failed to build app")?; |
257 | 173 |
|
258 | 174 | if config_.tauri.bundle.active { |
259 | | - let package_types = if let Some(names) = options.bundles { |
| 175 | + let package_types = if let Some(names) = &options.bundles { |
260 | 176 | let mut types = vec![]; |
261 | 177 | for name in names |
262 | | - .into_iter() |
| 178 | + .iter() |
263 | 179 | .flat_map(|n| n.split(',').map(|s| s.to_string()).collect::<Vec<String>>()) |
264 | 180 | { |
265 | 181 | if name == "none" { |
@@ -293,20 +209,9 @@ pub fn command(options: Options) -> Result<()> { |
293 | 209 | } |
294 | 210 | } |
295 | 211 |
|
296 | | - let mut enabled_features = features.clone(); |
297 | | - if !no_default_features { |
298 | | - enabled_features.push("default".into()); |
299 | | - } |
300 | | - let settings = crate::interface::get_bundler_settings( |
301 | | - app_settings, |
302 | | - target, |
303 | | - &enabled_features, |
304 | | - &manifest, |
305 | | - config_, |
306 | | - &out_dir, |
307 | | - package_types, |
308 | | - ) |
309 | | - .with_context(|| "failed to build bundler settings")?; |
| 212 | + let settings = app_settings |
| 213 | + .get_bundler_settings(&options.into(), &manifest, config_, out_dir, package_types) |
| 214 | + .with_context(|| "failed to build bundler settings")?; |
310 | 215 |
|
311 | 216 | // set env vars used by the bundler |
312 | 217 | #[cfg(target_os = "linux")] |
|
0 commit comments