Skip to content

Commit d20a728

Browse files
feat: Further improve workspace inheritance, closes #6122, #5070 (#6144)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent 9da9960 commit d20a728

File tree

10 files changed

+202
-91
lines changed

10 files changed

+202
-91
lines changed

.changes/version-inheritance.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
'cli.rs': 'minor'
3+
'tauri-build': 'minor'
34
---
45

5-
Add support for Cargo's workspace inheritance for the package version.
6+
Added support for Cargo's workspace inheritance for package information. The cli now also detects inherited `tauri` and `tauri-build` dependencies and disables manifest rewrites accordingly.

core/tauri-build/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ quote = { version = "1", optional = true }
2222
tauri-codegen = { version = "1.2.1", path = "../tauri-codegen", optional = true }
2323
tauri-utils = { version = "1.2.1", path = "../tauri-utils", features = [ "build", "resources" ] }
2424
cargo_toml = "0.14"
25+
serde = "1"
2526
serde_json = "1"
2627
heck = "0.4"
2728
json-patch = "0.3"

core/tauri-build/src/lib.rs

Lines changed: 114 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
#![cfg_attr(doc_cfg, feature(doc_cfg))]
66

77
pub use anyhow::Result;
8+
use cargo_toml::{Dependency, Manifest};
89
use heck::AsShoutySnakeCase;
910

10-
use tauri_utils::resources::{external_binaries, resource_relpath, ResourcePaths};
11+
use tauri_utils::{
12+
config::Config,
13+
resources::{external_binaries, resource_relpath, ResourcePaths},
14+
};
1115

1216
use std::path::{Path, PathBuf};
1317

@@ -242,8 +246,6 @@ pub fn build() {
242246
#[allow(unused_variables)]
243247
pub fn try_build(attributes: Attributes) -> Result<()> {
244248
use anyhow::anyhow;
245-
use cargo_toml::{Dependency, Manifest};
246-
use tauri_utils::config::{Config, TauriConfig};
247249

248250
println!("cargo:rerun-if-env-changed=TAURI_CONFIG");
249251
println!("cargo:rerun-if-changed=tauri.conf.json");
@@ -268,50 +270,33 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
268270

269271
cfg_alias("dev", !has_feature("custom-protocol"));
270272

271-
let mut manifest = Manifest::from_path("Cargo.toml")?;
272-
if let Some(tauri) = manifest.dependencies.remove("tauri") {
273-
let features = match tauri {
274-
Dependency::Simple(_) => Vec::new(),
275-
Dependency::Detailed(dep) => dep.features,
276-
Dependency::Inherited(dep) => dep.features,
277-
};
278-
279-
let all_cli_managed_features = TauriConfig::all_features();
280-
let diff = features_diff(
281-
&features
282-
.into_iter()
283-
.filter(|f| all_cli_managed_features.contains(&f.as_str()))
284-
.collect::<Vec<String>>(),
285-
&config
286-
.tauri
287-
.features()
288-
.into_iter()
289-
.map(|f| f.to_string())
290-
.collect::<Vec<String>>(),
291-
);
292-
293-
let mut error_message = String::new();
294-
if !diff.remove.is_empty() {
295-
error_message.push_str("remove the `");
296-
error_message.push_str(&diff.remove.join(", "));
297-
error_message.push_str(if diff.remove.len() == 1 {
298-
"` feature"
299-
} else {
300-
"` features"
301-
});
302-
if !diff.add.is_empty() {
303-
error_message.push_str(" and ");
304-
}
305-
}
306-
if !diff.add.is_empty() {
307-
error_message.push_str("add the `");
308-
error_message.push_str(&diff.add.join(", "));
309-
error_message.push_str(if diff.add.len() == 1 {
310-
"` feature"
311-
} else {
312-
"` features"
313-
});
273+
let ws_path = get_workspace_dir()?;
274+
let mut manifest =
275+
Manifest::<cargo_toml::Value>::from_slice_with_metadata(&std::fs::read("Cargo.toml")?)?;
276+
277+
if let Ok(ws_manifest) = Manifest::from_path(ws_path.join("Cargo.toml")) {
278+
Manifest::complete_from_path_and_workspace(
279+
&mut manifest,
280+
Path::new("Cargo.toml"),
281+
Some((&ws_manifest, ws_path.as_path())),
282+
)?;
283+
} else {
284+
Manifest::complete_from_path(&mut manifest, Path::new("Cargo.toml"))?;
285+
}
286+
287+
if let Some(tauri_build) = manifest.build_dependencies.remove("tauri-build") {
288+
let error_message = check_features(&config, tauri_build, true);
289+
290+
if !error_message.is_empty() {
291+
return Err(anyhow!("
292+
The `tauri-build` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
293+
Please run `tauri dev` or `tauri build` or {}.
294+
", error_message));
314295
}
296+
}
297+
298+
if let Some(tauri) = manifest.dependencies.remove("tauri") {
299+
let error_message = check_features(&config, tauri, false);
315300

316301
if !error_message.is_empty() {
317302
return Err(anyhow!("
@@ -485,6 +470,89 @@ fn features_diff(current: &[String], expected: &[String]) -> Diff {
485470
Diff { remove, add }
486471
}
487472

473+
fn check_features(config: &Config, dependency: Dependency, is_tauri_build: bool) -> String {
474+
use tauri_utils::config::{PatternKind, TauriConfig};
475+
476+
let features = match dependency {
477+
Dependency::Simple(_) => Vec::new(),
478+
Dependency::Detailed(dep) => dep.features,
479+
Dependency::Inherited(dep) => dep.features,
480+
};
481+
482+
let all_cli_managed_features = if is_tauri_build {
483+
vec!["isolation"]
484+
} else {
485+
TauriConfig::all_features()
486+
};
487+
488+
let expected = if is_tauri_build {
489+
match config.tauri.pattern {
490+
PatternKind::Isolation { .. } => vec!["isolation".to_string()],
491+
_ => vec![],
492+
}
493+
} else {
494+
config
495+
.tauri
496+
.features()
497+
.into_iter()
498+
.map(|f| f.to_string())
499+
.collect::<Vec<String>>()
500+
};
501+
502+
let diff = features_diff(
503+
&features
504+
.into_iter()
505+
.filter(|f| all_cli_managed_features.contains(&f.as_str()))
506+
.collect::<Vec<String>>(),
507+
&expected,
508+
);
509+
510+
let mut error_message = String::new();
511+
if !diff.remove.is_empty() {
512+
error_message.push_str("remove the `");
513+
error_message.push_str(&diff.remove.join(", "));
514+
error_message.push_str(if diff.remove.len() == 1 {
515+
"` feature"
516+
} else {
517+
"` features"
518+
});
519+
if !diff.add.is_empty() {
520+
error_message.push_str(" and ");
521+
}
522+
}
523+
if !diff.add.is_empty() {
524+
error_message.push_str("add the `");
525+
error_message.push_str(&diff.add.join(", "));
526+
error_message.push_str(if diff.add.len() == 1 {
527+
"` feature"
528+
} else {
529+
"` features"
530+
});
531+
}
532+
533+
error_message
534+
}
535+
536+
#[derive(serde::Deserialize)]
537+
struct CargoMetadata {
538+
workspace_root: PathBuf,
539+
}
540+
541+
fn get_workspace_dir() -> Result<PathBuf> {
542+
let output = std::process::Command::new("cargo")
543+
.args(["metadata", "--no-deps", "--format-version", "1"])
544+
.output()?;
545+
546+
if !output.status.success() {
547+
return Err(anyhow::anyhow!(
548+
"cargo metadata command exited with a non zero exit code: {}",
549+
String::from_utf8(output.stderr)?
550+
));
551+
}
552+
553+
Ok(serde_json::from_slice::<CargoMetadata>(&output.stdout)?.workspace_root)
554+
}
555+
488556
#[cfg(test)]
489557
mod tests {
490558
use super::Diff;

examples/workspace/Cargo.lock

Lines changed: 13 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/workspace/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ members = [
66

77
[workspace.package]
88
version = "1.0.0"
9+
10+
[workspace.dependencies]
11+
tauri-build = { path = "../../core/tauri-build", features = [] }
12+
tauri = { path = "../../core/tauri", features = [] }

examples/workspace/src-tauri/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ edition = "2021"
1010
rust-version = "1.59"
1111

1212
[build-dependencies]
13-
tauri-build = { path = "../../../core/tauri-build", features = [] }
13+
tauri-build = { workspace = true }
1414

1515
[dependencies]
1616
serde_json = "1.0"
1717
serde = { version = "1.0", features = ["derive"] }
18-
tauri = { path = "../../../core/tauri", features = [] }
18+
tauri = { workspace = true }
1919
core-api = { path = "../core" }
2020

2121
[features]

tooling/cli/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tooling/cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ kuchiki = "0.8"
8080
tokio = { version = "1", features = [ "macros", "sync" ] }
8181
common-path = "1"
8282
serde-value = "0.7.0"
83+
itertools = "0.10"
8384

8485
[target."cfg(windows)".dependencies]
8586
winapi = { version = "0.3", features = [ "handleapi", "processenv", "winbase", "wincon", "winnt" ] }

0 commit comments

Comments
 (0)