Skip to content

Commit 0cdfda2

Browse files
authored
refactor: move plugin functionality from tauri-build to tauri-plugin (#8737)
* refactor: move plugin functionality from tauri-build to tauri-plugin * fixes * fix build * move docs function * autogenerated * fix path
1 parent 63d6d47 commit 0cdfda2

35 files changed

Lines changed: 1460 additions & 3838 deletions

File tree

.changes/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@
217217
"path": "./core/tauri-plugin",
218218
"manager": "rust",
219219
"dependencies": [
220-
"tauri"
220+
"tauri-utils"
221221
],
222222
"postversion": "node ../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }"
223223
},
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-build": patch:breaking
3+
---
4+
5+
Moved `mobile::PluginBuilder`, `mobile::update_entitlements`, `config::plugin_config` and `mobile::update_android_manifest` to the new `tauri-plugin` crate.

core/tauri-build/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ glob = "0.3"
4343
toml = "0.8"
4444
schemars = { version = "0.8", features = [ "preserve_order" ] }
4545

46-
[target."cfg(target_os = \"macos\")".dependencies]
47-
swift-rs = { version = "1.0.6", features = [ "build" ] }
48-
plist = "1"
49-
5046
[features]
5147
default = [ "config-json" ]
5248
codegen = [ "tauri-codegen", "quote" ]

core/tauri-build/src/config.rs

Lines changed: 0 additions & 22 deletions
This file was deleted.

core/tauri-build/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,8 @@ use std::{
3232
mod acl;
3333
#[cfg(feature = "codegen")]
3434
mod codegen;
35-
/// Tauri configuration functions.
36-
pub mod config;
3735
mod manifest;
38-
/// Mobile build functions.
39-
pub mod mobile;
36+
mod mobile;
4037
mod static_vcruntime;
4138

4239
#[cfg(feature = "codegen")]

core/tauri-build/src/mobile.rs

Lines changed: 2 additions & 267 deletions
Original file line numberDiff line numberDiff line change
@@ -2,242 +2,11 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
use std::{
6-
env::{var, var_os},
7-
fs::{copy, create_dir, create_dir_all, read_to_string, remove_dir_all, write},
8-
path::{Path, PathBuf},
9-
};
5+
use std::{fs::write, path::PathBuf};
106

117
use anyhow::{Context, Result};
12-
use serde::{Deserialize, Serialize};
138

14-
#[derive(Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
15-
pub(crate) struct PluginMetadata {
16-
pub path: PathBuf,
17-
}
18-
19-
#[derive(Default)]
20-
pub struct PluginBuilder {
21-
android_path: Option<PathBuf>,
22-
ios_path: Option<PathBuf>,
23-
}
24-
25-
impl PluginBuilder {
26-
/// Creates a new builder for mobile plugin functionality.
27-
pub fn new() -> Self {
28-
Self::default()
29-
}
30-
31-
/// Sets the Android project path.
32-
pub fn android_path<P: Into<PathBuf>>(mut self, android_path: P) -> Self {
33-
self.android_path.replace(android_path.into());
34-
self
35-
}
36-
37-
/// Sets the iOS project path.
38-
pub fn ios_path<P: Into<PathBuf>>(mut self, ios_path: P) -> Self {
39-
self.ios_path.replace(ios_path.into());
40-
self
41-
}
42-
43-
/// Injects the mobile templates in the given path relative to the manifest root.
44-
pub fn run(self) -> Result<()> {
45-
let target_os = var("CARGO_CFG_TARGET_OS").unwrap();
46-
let mobile = target_os == "android" || target_os == "ios";
47-
crate::cfg_alias("mobile", mobile);
48-
crate::cfg_alias("desktop", !mobile);
49-
50-
match target_os.as_str() {
51-
"android" => {
52-
if let Some(path) = self.android_path {
53-
let manifest_dir = var_os("CARGO_MANIFEST_DIR").map(PathBuf::from).unwrap();
54-
let source = manifest_dir.join(path);
55-
56-
let tauri_library_path = std::env::var("DEP_TAURI_ANDROID_LIBRARY_PATH")
57-
.expect("missing `DEP_TAURI_ANDROID_LIBRARY_PATH` environment variable. Make sure `tauri` is a dependency of the plugin.");
58-
println!("cargo:rerun-if-env-changed=DEP_TAURI_ANDROID_LIBRARY_PATH");
59-
60-
create_dir_all(source.join(".tauri")).context("failed to create .tauri directory")?;
61-
copy_folder(
62-
Path::new(&tauri_library_path),
63-
&source.join(".tauri").join("tauri-api"),
64-
&[],
65-
)
66-
.context("failed to copy tauri-api to the plugin project")?;
67-
68-
println!("cargo:android_library_path={}", source.display());
69-
}
70-
}
71-
#[cfg(target_os = "macos")]
72-
"ios" => {
73-
if let Some(path) = self.ios_path {
74-
let manifest_dir = var_os("CARGO_MANIFEST_DIR").map(PathBuf::from).unwrap();
75-
let tauri_library_path = std::env::var("DEP_TAURI_IOS_LIBRARY_PATH")
76-
.expect("missing `DEP_TAURI_IOS_LIBRARY_PATH` environment variable. Make sure `tauri` is a dependency of the plugin.");
77-
78-
let tauri_dep_path = path.parent().unwrap().join(".tauri");
79-
create_dir_all(&tauri_dep_path).context("failed to create .tauri directory")?;
80-
copy_folder(
81-
Path::new(&tauri_library_path),
82-
&tauri_dep_path.join("tauri-api"),
83-
&[".build", "Package.resolved", "Tests"],
84-
)
85-
.context("failed to copy tauri-api to the plugin project")?;
86-
link_swift_library(&var("CARGO_PKG_NAME").unwrap(), manifest_dir.join(path));
87-
}
88-
}
89-
_ => (),
90-
}
91-
92-
Ok(())
93-
}
94-
}
95-
96-
#[cfg(target_os = "macos")]
97-
#[doc(hidden)]
98-
pub fn link_swift_library(name: &str, source: impl AsRef<Path>) {
99-
let source = source.as_ref();
100-
101-
let sdk_root = std::env::var_os("SDKROOT");
102-
std::env::remove_var("SDKROOT");
103-
104-
swift_rs::SwiftLinker::new(
105-
&std::env::var("MACOSX_DEPLOYMENT_TARGET").unwrap_or_else(|_| "10.13".into()),
106-
)
107-
.with_ios(&std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "13.0".into()))
108-
.with_package(name, source)
109-
.link();
110-
111-
if let Some(root) = sdk_root {
112-
std::env::set_var("SDKROOT", root);
113-
}
114-
}
115-
116-
fn copy_folder(source: &Path, target: &Path, ignore_paths: &[&str]) -> Result<()> {
117-
let _ = remove_dir_all(target);
118-
119-
for entry in walkdir::WalkDir::new(source) {
120-
let entry = entry?;
121-
let rel_path = entry.path().strip_prefix(source)?;
122-
let rel_path_str = rel_path.to_string_lossy();
123-
if ignore_paths
124-
.iter()
125-
.any(|path| rel_path_str.starts_with(path))
126-
{
127-
continue;
128-
}
129-
let dest_path = target.join(rel_path);
130-
131-
if entry.file_type().is_dir() {
132-
create_dir(&dest_path)
133-
.with_context(|| format!("failed to create directory {}", dest_path.display()))?;
134-
} else {
135-
copy(entry.path(), &dest_path).with_context(|| {
136-
format!(
137-
"failed to copy {} to {}",
138-
entry.path().display(),
139-
dest_path.display()
140-
)
141-
})?;
142-
println!("cargo:rerun-if-changed={}", entry.path().display());
143-
}
144-
}
145-
146-
Ok(())
147-
}
148-
149-
#[cfg(target_os = "macos")]
150-
fn update_plist_file<P: AsRef<Path>, F: FnOnce(&mut plist::Dictionary)>(
151-
path: P,
152-
f: F,
153-
) -> Result<()> {
154-
use std::io::Cursor;
155-
156-
let path = path.as_ref();
157-
if path.exists() {
158-
let plist_str = read_to_string(path)?;
159-
let mut plist = plist::Value::from_reader(Cursor::new(&plist_str))?;
160-
if let Some(dict) = plist.as_dictionary_mut() {
161-
f(dict);
162-
let mut plist_buf = Vec::new();
163-
let writer = Cursor::new(&mut plist_buf);
164-
plist::to_writer_xml(writer, &plist)?;
165-
let new_plist_str = String::from_utf8(plist_buf)?;
166-
if new_plist_str != plist_str {
167-
write(path, new_plist_str)?;
168-
}
169-
}
170-
}
171-
172-
Ok(())
173-
}
174-
175-
#[cfg(target_os = "macos")]
176-
pub fn update_entitlements<F: FnOnce(&mut plist::Dictionary)>(f: F) -> Result<()> {
177-
if let (Some(project_path), Ok(app_name)) = (
178-
var_os("TAURI_IOS_PROJECT_PATH").map(PathBuf::from),
179-
var("TAURI_IOS_APP_NAME"),
180-
) {
181-
update_plist_file(
182-
project_path
183-
.join(format!("{app_name}_iOS"))
184-
.join(format!("{app_name}_iOS.entitlements")),
185-
f,
186-
)?;
187-
}
188-
189-
Ok(())
190-
}
191-
192-
fn xml_block_comment(id: &str) -> String {
193-
format!("<!-- {id}. AUTO-GENERATED. DO NOT REMOVE. -->")
194-
}
195-
196-
fn insert_into_xml(xml: &str, block_identifier: &str, parent_tag: &str, contents: &str) -> String {
197-
let block_comment = xml_block_comment(block_identifier);
198-
199-
let mut rewritten = Vec::new();
200-
let mut found_block = false;
201-
let parent_closing_tag = format!("</{parent_tag}>");
202-
for line in xml.split('\n') {
203-
if line.contains(&block_comment) {
204-
found_block = !found_block;
205-
continue;
206-
}
207-
208-
// found previous block which should be removed
209-
if found_block {
210-
continue;
211-
}
212-
213-
if let Some(index) = line.find(&parent_closing_tag) {
214-
let identation = " ".repeat(index + 4);
215-
rewritten.push(format!("{}{}", identation, block_comment));
216-
for l in contents.split('\n') {
217-
rewritten.push(format!("{}{}", identation, l));
218-
}
219-
rewritten.push(format!("{}{}", identation, block_comment));
220-
}
221-
222-
rewritten.push(line.to_string());
223-
}
224-
225-
rewritten.join("\n")
226-
}
227-
228-
pub fn update_android_manifest(block_identifier: &str, parent: &str, insert: String) -> Result<()> {
229-
if let Some(project_path) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
230-
let manifest_path = project_path.join("app/src/main/AndroidManifest.xml");
231-
let manifest = read_to_string(&manifest_path)?;
232-
let rewritten = insert_into_xml(&manifest, block_identifier, parent, &insert);
233-
if rewritten != manifest {
234-
write(manifest_path, rewritten)?;
235-
}
236-
}
237-
Ok(())
238-
}
239-
240-
pub(crate) fn generate_gradle_files(project_dir: PathBuf) -> Result<()> {
9+
pub fn generate_gradle_files(project_dir: PathBuf) -> Result<()> {
24110
let gradle_settings_path = project_dir.join("tauri.settings.gradle");
24211
let app_build_gradle_path = project_dir.join("app").join("tauri.build.gradle.kts");
24312

@@ -289,37 +58,3 @@ dependencies {"
28958

29059
Ok(())
29160
}
292-
293-
#[cfg(test)]
294-
mod tests {
295-
#[test]
296-
fn insert_into_xml() {
297-
let manifest = r#"<manifest>
298-
<application>
299-
<intent-filter>
300-
</intent-filter>
301-
</application>
302-
</manifest>"#;
303-
let id = "tauritest";
304-
let new = super::insert_into_xml(manifest, id, "application", "<something></something>");
305-
306-
let block_id_comment = super::xml_block_comment(id);
307-
let expected = format!(
308-
r#"<manifest>
309-
<application>
310-
<intent-filter>
311-
</intent-filter>
312-
{block_id_comment}
313-
<something></something>
314-
{block_id_comment}
315-
</application>
316-
</manifest>"#
317-
);
318-
319-
assert_eq!(new, expected);
320-
321-
// assert it's still the same after an empty update
322-
let new = super::insert_into_xml(&expected, id, "application", "<something></something>");
323-
assert_eq!(new, expected);
324-
}
325-
}

core/tauri-plugin/Cargo.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,28 @@ rust-version = { workspace = true }
1111

1212
[features]
1313
build = [
14+
"dep:anyhow",
1415
"dep:serde",
15-
"dep:cargo_metadata",
1616
"dep:serde_json",
1717
"dep:glob",
1818
"dep:toml",
19+
"dep:plist",
20+
"dep:walkdir",
1921
]
2022
runtime = []
2123

2224
[dependencies]
25+
anyhow = { version = "1", optional = true }
2326
serde = { version = "1", optional = true }
24-
cargo_metadata = { version = "0.18", optional = true }
25-
tauri = { version = "2.0.0-alpha.20", default-features = false, path = "../tauri" }
27+
tauri-utils = { version = "2.0.0-alpha.13", default-features = false, path = "../tauri-utils" }
2628
serde_json = { version = "1", optional = true }
2729
glob = { version = "0.3", optional = true }
2830
toml = { version = "0.8", optional = true }
2931
schemars = { version = "0.8", features = [ "preserve_order" ] }
32+
walkdir = { version = "1", optional = true }
33+
34+
[target."cfg(target_os = \"macos\")".dependencies]
35+
plist = { version = "1", optional = true }
3036

3137
[package.metadata.docs.rs]
3238
features = ["build", "runtime"]

0 commit comments

Comments
 (0)