mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-11 07:55:34 +03:00
feat(cli): add support for Cargo's workspace inheritance for the package version, closes #5070 (#5775)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
f7a080a121
commit
cd8c074ae6
5
.changes/version-inheritance.md
Normal file
5
.changes/version-inheritance.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'cli.rs': 'minor'
|
||||||
|
---
|
||||||
|
|
||||||
|
Add support for Cargo's workspace inheritance for the package version.
|
@ -3,7 +3,7 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
declare -a examples=("api" "sidecar" "updater" "resources" "tauri-dynamic-lib")
|
declare -a examples=("api" "sidecar" "updater" "resources" "tauri-dynamic-lib" "workspace")
|
||||||
declare -a tooling=("bench" "cli" "webdriver")
|
declare -a tooling=("bench" "cli" "webdriver")
|
||||||
|
|
||||||
for example in "${examples[@]}"
|
for example in "${examples[@]}"
|
||||||
|
@ -21,7 +21,8 @@ exclude = [
|
|||||||
"examples/updater/src-tauri",
|
"examples/updater/src-tauri",
|
||||||
"examples/resources/src-tauri",
|
"examples/resources/src-tauri",
|
||||||
"examples/sidecar/src-tauri",
|
"examples/sidecar/src-tauri",
|
||||||
"examples/web/core"
|
"examples/web/core",
|
||||||
|
"examples/workspace"
|
||||||
]
|
]
|
||||||
|
|
||||||
# default to small, optimized workspace release binaries
|
# default to small, optimized workspace release binaries
|
||||||
|
3111
examples/workspace/Cargo.lock
generated
Normal file
3111
examples/workspace/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
8
examples/workspace/Cargo.toml
Normal file
8
examples/workspace/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"core",
|
||||||
|
"src-tauri"
|
||||||
|
]
|
||||||
|
|
||||||
|
[workspace.package]
|
||||||
|
version = "1.0.0"
|
6
examples/workspace/core/Cargo.toml
Normal file
6
examples/workspace/core/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "core-api"
|
||||||
|
version = { workspace = true }
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
3
examples/workspace/core/src/lib.rs
Normal file
3
examples/workspace/core/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub fn run() {
|
||||||
|
println!("run!");
|
||||||
|
}
|
13
examples/workspace/index.html
Normal file
13
examples/workspace/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Workspace Example!</h1>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
3
examples/workspace/src-tauri/.gitignore
vendored
Normal file
3
examples/workspace/src-tauri/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
/target/
|
27
examples/workspace/src-tauri/Cargo.toml
Normal file
27
examples/workspace/src-tauri/Cargo.toml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[package]
|
||||||
|
name = "app"
|
||||||
|
version = { workspace = true }
|
||||||
|
description = "A Tauri App"
|
||||||
|
authors = ["you"]
|
||||||
|
license = ""
|
||||||
|
repository = ""
|
||||||
|
default-run = "app"
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.59"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tauri-build = { path = "../../../core/tauri-build", features = [] }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
tauri = { path = "../../../core/tauri", features = [] }
|
||||||
|
core-api = { path = "../core" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# by default Tauri runs in production mode
|
||||||
|
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
|
||||||
|
default = [ "custom-protocol" ]
|
||||||
|
# this feature is used for production builds where `devPath` points to the filesystem
|
||||||
|
# DO NOT remove this
|
||||||
|
custom-protocol = [ "tauri/custom-protocol" ]
|
3
examples/workspace/src-tauri/build.rs
Normal file
3
examples/workspace/src-tauri/build.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
tauri_build::build()
|
||||||
|
}
|
11
examples/workspace/src-tauri/src/main.rs
Normal file
11
examples/workspace/src-tauri/src/main.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#![cfg_attr(
|
||||||
|
all(not(debug_assertions), target_os = "windows"),
|
||||||
|
windows_subsystem = "windows"
|
||||||
|
)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
core_api::run();
|
||||||
|
tauri::Builder::default()
|
||||||
|
.run(tauri::generate_context!())
|
||||||
|
.expect("error while running tauri application");
|
||||||
|
}
|
66
examples/workspace/src-tauri/tauri.conf.json
Normal file
66
examples/workspace/src-tauri/tauri.conf.json
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"distDir": [
|
||||||
|
"../index.html"
|
||||||
|
],
|
||||||
|
"devPath": [
|
||||||
|
"../index.html"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"package": {
|
||||||
|
"productName": "workspace"
|
||||||
|
},
|
||||||
|
"tauri": {
|
||||||
|
"allowlist": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
|
"bundle": {
|
||||||
|
"active": true,
|
||||||
|
"category": "DeveloperTool",
|
||||||
|
"copyright": "",
|
||||||
|
"deb": {
|
||||||
|
"depends": []
|
||||||
|
},
|
||||||
|
"externalBin": [],
|
||||||
|
"icon": [
|
||||||
|
"../../.icons/32x32.png",
|
||||||
|
"../../.icons/128x128.png",
|
||||||
|
"../../.icons/128x128@2x.png",
|
||||||
|
"../../.icons/icon.icns",
|
||||||
|
"../../.icons/icon.ico"
|
||||||
|
],
|
||||||
|
"identifier": "com.tauri.workspace",
|
||||||
|
"longDescription": "",
|
||||||
|
"macOS": {
|
||||||
|
"entitlements": null,
|
||||||
|
"exceptionDomain": "",
|
||||||
|
"frameworks": [],
|
||||||
|
"providerShortName": null,
|
||||||
|
"signingIdentity": null
|
||||||
|
},
|
||||||
|
"resources": [],
|
||||||
|
"shortDescription": "",
|
||||||
|
"targets": "all",
|
||||||
|
"windows": {
|
||||||
|
"certificateThumbprint": null,
|
||||||
|
"digestAlgorithm": "sha256",
|
||||||
|
"timestampUrl": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"csp": null
|
||||||
|
},
|
||||||
|
"updater": {
|
||||||
|
"active": false
|
||||||
|
},
|
||||||
|
"windows": [
|
||||||
|
{
|
||||||
|
"fullscreen": false,
|
||||||
|
"height": 600,
|
||||||
|
"resizable": true,
|
||||||
|
"title": "Workspace",
|
||||||
|
"width": 800
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
20
tooling/cli/Cargo.lock
generated
20
tooling/cli/Cargo.lock
generated
@ -2005,6 +2005,15 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-float"
|
||||||
|
version = "2.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_info"
|
name = "os_info"
|
||||||
version = "3.5.0"
|
version = "3.5.0"
|
||||||
@ -2755,6 +2764,16 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-value"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
|
||||||
|
dependencies = [
|
||||||
|
"ordered-float",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.137"
|
version = "1.0.137"
|
||||||
@ -3152,6 +3171,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde-value",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shared_child",
|
"shared_child",
|
||||||
"tauri-bundler",
|
"tauri-bundler",
|
||||||
|
@ -79,6 +79,7 @@ html5ever = "0.25"
|
|||||||
kuchiki = "0.8"
|
kuchiki = "0.8"
|
||||||
tokio = { version = "1", features = [ "macros", "sync" ] }
|
tokio = { version = "1", features = [ "macros", "sync" ] }
|
||||||
common-path = "1"
|
common-path = "1"
|
||||||
|
serde-value = "0.7.0"
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies]
|
[target."cfg(windows)".dependencies]
|
||||||
winapi = { version = "0.3", features = [ "handleapi", "processenv", "winbase", "wincon", "winnt" ] }
|
winapi = { version = "0.3", features = [ "handleapi", "processenv", "winbase", "wincon", "winnt" ] }
|
||||||
|
@ -502,11 +502,77 @@ impl Rust {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Taken from https://github.com/rust-lang/cargo/blob/70898e522116f6c23971e2a554b2dc85fd4c84cd/src/cargo/util/toml/mod.rs#L1008-L1065
|
||||||
|
/// Enum that allows for the parsing of `field.workspace = true` in a Cargo.toml
|
||||||
|
///
|
||||||
|
/// It allows for things to be inherited from a workspace or defined as needed
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum MaybeWorkspace<T> {
|
||||||
|
Workspace(TomlWorkspaceField),
|
||||||
|
Defined(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, T: Deserialize<'de>> serde::de::Deserialize<'de> for MaybeWorkspace<T> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<MaybeWorkspace<T>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let value = serde_value::Value::deserialize(deserializer)?;
|
||||||
|
if let Ok(workspace) = TomlWorkspaceField::deserialize(
|
||||||
|
serde_value::ValueDeserializer::<D::Error>::new(value.clone()),
|
||||||
|
) {
|
||||||
|
return Ok(MaybeWorkspace::Workspace(workspace));
|
||||||
|
}
|
||||||
|
T::deserialize(serde_value::ValueDeserializer::<D::Error>::new(value))
|
||||||
|
.map(MaybeWorkspace::Defined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MaybeWorkspace<T> {
|
||||||
|
fn resolve(
|
||||||
|
self,
|
||||||
|
label: &str,
|
||||||
|
get_ws_field: impl FnOnce() -> anyhow::Result<T>,
|
||||||
|
) -> anyhow::Result<T> {
|
||||||
|
match self {
|
||||||
|
MaybeWorkspace::Defined(value) => Ok(value),
|
||||||
|
MaybeWorkspace::Workspace(TomlWorkspaceField { workspace: true }) => {
|
||||||
|
get_ws_field().context(format!(
|
||||||
|
"error inheriting `{}` from workspace root manifest's `workspace.package.{}`",
|
||||||
|
label, label
|
||||||
|
))
|
||||||
|
}
|
||||||
|
MaybeWorkspace::Workspace(TomlWorkspaceField { workspace: false }) => Err(anyhow::anyhow!(
|
||||||
|
"`workspace=false` is unsupported for `package.{}`",
|
||||||
|
label,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn _as_defined(&self) -> Option<&T> {
|
||||||
|
match self {
|
||||||
|
MaybeWorkspace::Workspace(_) => None,
|
||||||
|
MaybeWorkspace::Defined(defined) => Some(defined),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
|
pub struct TomlWorkspaceField {
|
||||||
|
workspace: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// The `workspace` section of the app configuration (read from Cargo.toml).
|
/// The `workspace` section of the app configuration (read from Cargo.toml).
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
struct WorkspaceSettings {
|
struct WorkspaceSettings {
|
||||||
/// the workspace members.
|
/// the workspace members.
|
||||||
members: Option<Vec<String>>,
|
members: Option<Vec<String>>,
|
||||||
|
package: Option<WorkspacePackageSettings>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
struct WorkspacePackageSettings {
|
||||||
|
/// the workspace members.
|
||||||
|
version: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
@ -521,7 +587,7 @@ pub struct CargoPackageSettings {
|
|||||||
/// the package's name.
|
/// the package's name.
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
/// the package's version.
|
/// the package's version.
|
||||||
pub version: Option<String>,
|
pub version: Option<MaybeWorkspace<String>>,
|
||||||
/// the package's description.
|
/// the package's description.
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
/// the package's homepage.
|
/// the package's homepage.
|
||||||
@ -741,6 +807,9 @@ impl RustAppSettings {
|
|||||||
.version
|
.version
|
||||||
.clone()
|
.clone()
|
||||||
.expect("Cargo manifest must have the `package.version` field")
|
.expect("Cargo manifest must have the `package.version` field")
|
||||||
|
.resolve("version", || {
|
||||||
|
get_workspace_version()?.context("Workspace Cargo manifest must have the `workspace.package.version` field if a member tries to inherit the version")
|
||||||
|
}).expect("Cargo project does not have a version")
|
||||||
}),
|
}),
|
||||||
description: cargo_package_settings
|
description: cargo_package_settings
|
||||||
.description
|
.description
|
||||||
@ -842,6 +911,27 @@ pub fn get_workspace_dir() -> crate::Result<PathBuf> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_workspace_version() -> crate::Result<Option<String>> {
|
||||||
|
// This will already fail because `cargo metadata` fails if there is no version in the workspace root when a package tries to inherit it.
|
||||||
|
let toml_path = get_workspace_dir()
|
||||||
|
.map(|p| p.join("Cargo.toml"))
|
||||||
|
.with_context(|| "failed to get workspace Cargo.toml file")?;
|
||||||
|
|
||||||
|
let mut toml_str = String::new();
|
||||||
|
let mut toml_file = File::open(toml_path).with_context(|| "failed to open Cargo.toml")?;
|
||||||
|
toml_file
|
||||||
|
.read_to_string(&mut toml_str)
|
||||||
|
.with_context(|| "failed to read Cargo.toml")?;
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
toml::from_str::<CargoSettings>(&toml_str)
|
||||||
|
.with_context(|| "failed to parse Cargo.toml")?
|
||||||
|
.workspace
|
||||||
|
.and_then(|ws| ws.package)
|
||||||
|
.and_then(|p| p.version),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn tauri_config_to_bundle_settings(
|
fn tauri_config_to_bundle_settings(
|
||||||
manifest: &Manifest,
|
manifest: &Manifest,
|
||||||
|
Loading…
Reference in New Issue
Block a user