From b585670708f8dddc484f610d4a59b42a99933887 Mon Sep 17 00:00:00 2001 From: Jens Reimann Date: Fri, 6 Sep 2024 15:11:50 +0200 Subject: [PATCH] feat: Initial support for cargo profiles This isn't the complete "trunk profile" implementation, but maybe a short term solution in the right direction. This allows setting a cargo profile on multiple levels. The idea is to allow influencing the cargo profile only. The trunk release flag still works as before. However you can now choose a `--cargo-profile` from the command line, from the Trunk.toml, from the `index.html` data attributes. In that order of preference. --- Trunk.toml | 4 ++++ guide/src/assets/index.md | 3 +++ schemas/config.json | 9 +++++++++ src/cmd/build.rs | 6 ++++++ src/config/models/build.rs | 5 +++++ src/config/rt/build.rs | 4 ++++ src/pipelines/rust/mod.rs | 35 ++++++++++++++++++++++++++++------- 7 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Trunk.toml b/Trunk.toml index 1f1273f7..408987f0 100644 --- a/Trunk.toml +++ b/Trunk.toml @@ -8,6 +8,8 @@ trunk-version = "*" target = "index.html" # Build in release mode. release = false +# Use a custom cargo profile +# cargo_profile = "" # The output dir for all final assets. dist = "dist" # The public URL from which assets are to be served. @@ -26,6 +28,8 @@ locked = false minify = "never" # can be one of: never, on_release, always # Allow disabling sub-resource integrity (SRI) no_sri = false +# An optional cargo profile to use +# cargo_profile = "release.trunk" [watch] # Paths to watch. The `build.target`'s parent folder is watched by default. diff --git a/guide/src/assets/index.md b/guide/src/assets/index.md index dd8f6be4..1ca3bf55 100644 --- a/guide/src/assets/index.md +++ b/guide/src/assets/index.md @@ -38,6 +38,9 @@ This will typically look like: ``). - `data-target-path`: (optional) Path where the output is placed inside the dist dir. If not present, the directory is placed in the dist root. The path must be a relative path without `..`. - `data-initializer`: (optional) Path to the (module) JavaScript file of the [initializer](../advanced/initializer.md). +- `data-cargo-profile`: (optional) A cargo profile to use, instead of the default, for both release or dev mode. +- `data-cargo-profile-release`: (optional) A cargo profile to use, instead of the default, for the release mode. Overrides the `data-cargo-profile` setting. +- `data-cargo-profile-dev`: (optional) A cargo profile to use, instead of the default, for the dev mode. Overrides the `data-cargo-profile` setting. ### sass/scss diff --git a/schemas/config.json b/schemas/config.json index 2deb4b56..10d71728 100644 --- a/schemas/config.json +++ b/schemas/config.json @@ -9,6 +9,7 @@ "accept_invalid_certs": false, "all_features": false, "allow_self_closing_script": false, + "cargo_profile": null, "dist": "dist", "filehash": true, "frozen": false, @@ -106,6 +107,14 @@ "default": false, "type": "boolean" }, + "cargo_profile": { + "description": "Cargo profile to use. Conflicts with `release`.", + "default": null, + "type": [ + "string", + "null" + ] + }, "dist": { "description": "The output dir for all final assets", "default": "dist", diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 0d82c234..1192f0c2 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -24,6 +24,10 @@ pub struct Build { #[arg(default_missing_value="true", num_args=0..=1)] pub release: Option, + /// Cargo profile to use for building. + #[arg(long, env = "TRUNK_BUILD_CARGO_PROFILE")] + pub cargo_profile: Option, + /// The output dir for all final assets #[arg(short, long, env = "TRUNK_BUILD_DIST")] pub dist: Option, @@ -122,6 +126,7 @@ impl Build { core, target, release, + cargo_profile, dist, offline, frozen, @@ -142,6 +147,7 @@ impl Build { config.build.target = target.unwrap_or(config.build.target); config.build.release = release.unwrap_or(config.build.release); + config.build.cargo_profile = cargo_profile.or(config.build.cargo_profile); config.build.dist = dist.unwrap_or(config.build.dist); config.build.offline = offline.unwrap_or(config.build.offline); config.build.frozen = frozen.unwrap_or(config.build.frozen); diff --git a/src/config/models/build.rs b/src/config/models/build.rs index 088f1678..349bf89a 100644 --- a/src/config/models/build.rs +++ b/src/config/models/build.rs @@ -23,6 +23,10 @@ pub struct Build { #[serde(default)] pub release: bool, + /// Cargo profile to use. Conflicts with `release`. + #[serde(default)] + pub cargo_profile: Option, + /// The output dir for all final assets #[serde(default = "default::dist")] pub dist: PathBuf, @@ -184,6 +188,7 @@ impl Default for Build { Self { target: default::target(), release: false, + cargo_profile: None, dist: default::dist(), offline: false, frozen: false, diff --git a/src/config/rt/build.rs b/src/config/rt/build.rs index 39f96396..228c0a4e 100644 --- a/src/config/rt/build.rs +++ b/src/config/rt/build.rs @@ -32,6 +32,8 @@ pub struct RtcBuild { pub target_parent: PathBuf, /// Build in release mode. pub release: bool, + /// Cargo profile to use instead of the default selection. + pub cargo_profile: Option, /// Build without network access pub offline: bool, /// Require Cargo.lock and cache are up to date @@ -173,6 +175,7 @@ impl RtcBuild { target, target_parent, release: build.release, + cargo_profile: build.cargo_profile, public_url, filehash: build.filehash, staging_dist, @@ -211,6 +214,7 @@ impl RtcBuild { target, target_parent, release: false, + cargo_profile: None, public_url: Default::default(), filehash: true, final_dist, diff --git a/src/pipelines/rust/mod.rs b/src/pipelines/rust/mod.rs index f011fed5..f4328763 100644 --- a/src/pipelines/rust/mod.rs +++ b/src/pipelines/rust/mod.rs @@ -47,6 +47,8 @@ pub struct RustApp { cfg: Arc, /// Skip building skip_build: bool, + /// Cargo profile to use + cargo_profile: Option, /// The configuration of the features passed to cargo. cargo_features: Features, /// Is this module main or a worker? @@ -186,10 +188,6 @@ impl RustApp { let id = Some(id); let name = bin.clone().unwrap_or_else(|| manifest.package.name.clone()); - let data_features = attrs.get("data-cargo-features").map(|val| val.to_string()); - let data_all_features = attrs.contains_key("data-cargo-all-features"); - let data_no_default_features = attrs.contains_key("data-cargo-no-default-features"); - let loader_shim = attrs.contains_key("data-loader-shim"); if loader_shim { ensure!( @@ -198,14 +196,28 @@ impl RustApp { ); } + // cargo profile + + let cargo_profile = match cfg.release { + true => attrs.get("data-cargo-profile-dev"), + false => attrs.get("data-cargo-profile-release"), + } + .or_else(|| attrs.get("data-cargo-profile")) + .or_else(|| cfg.cargo_profile.as_ref()) + .cloned(); + + // cargo features + + let data_features = attrs.get("data-cargo-features").map(|val| val.to_string()); + let data_all_features = attrs.contains_key("data-cargo-all-features"); + let data_no_default_features = attrs.contains_key("data-cargo-no-default-features"); + // Highlander-rule: There can be only one (prohibits contradicting arguments): ensure!( !(data_all_features && (data_no_default_features || data_features.is_some())), "Cannot combine --all-features with --no-default-features and/or --features" ); - let skip_build = attrs.contains_key("data-trunk-skip"); - let cargo_features = if data_all_features { Features::All } else if data_no_default_features || data_features.is_some() { @@ -219,6 +231,10 @@ impl RustApp { cfg.cargo_features.clone() }; + // skip + + let skip_build = attrs.contains_key("data-trunk-skip"); + // bindings let import_bindings = !attrs.contains_key("data-wasm-no-import"); @@ -246,6 +262,7 @@ impl RustApp { id, cfg, skip_build, + cargo_profile, cargo_features, manifest, ignore_chan, @@ -294,6 +311,7 @@ impl RustApp { id: None, skip_build: false, cargo_features: cfg.cargo_features.clone(), + cargo_profile: None, cfg, manifest, ignore_chan, @@ -365,7 +383,10 @@ impl RustApp { "--manifest-path", &self.manifest.manifest_path, ]; - if self.cfg.release { + if let Some(profile) = &self.cargo_profile { + args.push("--profile"); + args.push(profile); + } else if self.cfg.release { args.push("--release"); } if self.cfg.offline {