snapshot of https://github.com/tauri-apps/tauri.git (dev, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Audit / audit-js (push) Failing after 0s
bench / bench (map[os:ubuntu-latest runner:xvfb-run --auto-servernum target:x86_64-unknown-linux-gnu], nightly) (push) Failing after 0s
covector version or publish / run-integration-tests (ubuntu-latest) (push) Failing after 0s
Audit / audit-rust (push) Failing after 0s
test `@tauri-apps/cli` / test (ubuntu-latest) (push) Failing after 0s
test `tauri-cli` / test (map[os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
deploy schema worker / deploy (push) Failing after 0s
lint rust / clippy (map[cargo:cargo include: os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
lint rust / clippy (map[cargo:cross include:--package api os:ubuntu-latest target:aarch64-linux-android]) (push) Failing after 0s
supply chain health status / check rust dependencies with cargo vet (push) Failing after 0s
test `@tauri-apps/api` e2e (mobile) / android (push) Failing after 0s
test `@tauri-apps/api` e2e / test (map[name:Linux os:ubuntu-latest]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
Udeps / changes (push) Failing after 0s
Udeps / setup (push) Has been skipped
Udeps / udeps (push) Has been skipped
bench / bench (map[os:macos-latest runner: target:aarch64-apple-darwin], nightly) (push) Has been cancelled
bench / bench (map[os:windows-latest runner: target:x86_64-pc-windows-msvc], nightly) (push) Has been cancelled
covector version or publish / run-integration-tests (macos-latest) (push) Has been cancelled
covector version or publish / run-integration-tests (windows-latest) (push) Has been cancelled
covector version or publish / version-or-publish (push) Has been cancelled
test `@tauri-apps/cli` / test (macos-latest) (push) Has been cancelled
test `tauri-cli` / test (map[args:--no-default-features --features native-tls-vendored os:windows-latest restore-only:true target:aarch64-pc-windows-msvc]) (push) Has been cancelled
test `tauri-cli` / test (map[os:macos-latest target:x86_64-apple-darwin]) (push) Has been cancelled
test `tauri-cli` / test (map[os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:macos-latest target:aarch64-apple-darwin]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include:--package api os:macos-latest target:aarch64-apple-ios]) (push) Has been cancelled
test `@tauri-apps/api` e2e (mobile) / ios (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:Windows os:windows-latest]) (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:macOS os:macos-latest]) (push) Has been cancelled
test `@tauri-apps/cli` / test (windows-latest) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-23 17:00:42 +05:00
commit feda81bf2f
1178 changed files with 156404 additions and 0 deletions

View File

@@ -0,0 +1,396 @@
# Changelog
## \[2.6.3]
### Dependencies
- Upgraded to `tauri-utils@2.9.3`
## \[2.6.2]
### Dependencies
- Upgraded to `tauri-utils@2.9.2`
## \[2.6.1]
### Dependencies
- Upgraded to `tauri-utils@2.9.1`
## \[2.6.0]
### New Features
- [`cc5c97602`](https://www.github.com/tauri-apps/tauri/commit/cc5c976027b0ab2431c13ec5b2e201d4414a8a6e) ([#14486](https://www.github.com/tauri-apps/tauri/pull/14486)) Implement file association for Android and iOS.
### Dependencies
- Upgraded to `tauri-utils@2.9.0`
## \[2.5.4]
### Dependencies
- Upgraded to `tauri-utils@2.8.3`
## \[2.5.3]
### Dependencies
- Upgraded to `tauri-utils@2.8.2`
## \[2.5.2]
### Dependencies
- Upgraded to `tauri-utils@2.8.1`
## \[2.5.1]
### Bug Fixes
- [`4b6b8690a`](https://www.github.com/tauri-apps/tauri/commit/4b6b8690ab886ebdf1307951cffbe03e31280baa) ([#14347](https://www.github.com/tauri-apps/tauri/pull/14347) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.5.0]
### Dependencies
- Upgraded to `tauri-utils@2.8.0`
- [`6aa7f2d85`](https://www.github.com/tauri-apps/tauri/commit/6aa7f2d852870aeba1d4dd0e07f8be2bc9b66286) Upgraded to `tauri-utils@2.8.0`
## \[2.4.0]
### New Features
- [`a0113a8c6`](https://www.github.com/tauri-apps/tauri/commit/a0113a8c6471eccc43b3202cc009901a04e41baa) ([#13888](https://www.github.com/tauri-apps/tauri/pull/13888) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Added `build::mobile::update_info_plist` to allow a plugin to update the iOS project Info.plist file.
### Dependencies
- Upgraded to `tauri-utils@2.7.0`
## \[2.3.1]
### Dependencies
- Upgraded to `tauri-utils@2.6.0`
## \[2.2.1]
### Dependencies
- Upgraded to `tauri-utils@2.5.0`
## \[2.2.0]
### Dependencies
- Upgraded to `tauri-utils@2.4.0`
- [`48b12b440`](https://www.github.com/tauri-apps/tauri/commit/48b12b440478937c46fdfef9f9d95194be117020) Update to `tauri-utils@2.4.0`
## \[2.1.1]
### Dependencies
- Upgraded to `tauri-utils@2.3.1`
## \[2.1.0]
### New Features
- [`013f8f652`](https://www.github.com/tauri-apps/tauri/commit/013f8f652302f2d49c5ec0a075582033d8b074fb) ([#12890](https://www.github.com/tauri-apps/tauri/pull/12890) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Added `build > removeUnusedCommands` to trigger the build scripts and macros to remove unused commands based on the capabilities you defined. Note this won't be accounting for dynamically added ACLs so make sure to check it when using this.
### Performance Improvements
- [`1cd8f55ee`](https://www.github.com/tauri-apps/tauri/commit/1cd8f55eed326d61860fee62ba2d2f4464bdcfcc) ([#13033](https://www.github.com/tauri-apps/tauri/pull/13033) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Don't ship global `bundle.global.js` if `app > withGlobalTauri` is set to false
### Dependencies
- Upgraded to `tauri-utils@2.3.0`
## \[2.0.5]
### Dependencies
- Upgraded to `tauri-utils@2.2.0`
## \[2.0.4]
### Dependencies
- Upgraded to `tauri-utils@2.1.1`
## \[2.0.3]
### Dependencies
- Upgraded to `tauri-utils@2.1.0`
## \[2.0.2]
### Dependencies
- Upgraded to `tauri-utils@2.0.2`
## \[2.0.1]
### What's Changed
- [`0ab2b3306`](https://www.github.com/tauri-apps/tauri/commit/0ab2b330644b6419f6cee1d5377bfb5cdda2ccf9) ([#11205](https://www.github.com/tauri-apps/tauri/pull/11205) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Downgrade MSRV to 1.77.2 to support Windows 7.
### Dependencies
- Upgraded to `tauri-utils@2.0.1`
## \[2.0.0]
### What's Changed
- [`382ed482b`](https://www.github.com/tauri-apps/tauri/commit/382ed482bd08157c39e62f9a0aaad8802f1092cb) Bump MSRV to 1.78.
- [`637285790`](https://www.github.com/tauri-apps/tauri/commit/6372857905ae9c0aedb7f482ddf6cf9f9836c9f2) Promote to v2 stable!
### Dependencies
- Upgraded to `tauri-utils@2.0.0`
## \[2.0.0-rc.13]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.13`
## \[2.0.0-rc.12]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.12`
## \[2.0.0-rc.11]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.11`
## \[2.0.0-rc.10]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.10`
## \[2.0.0-rc.9]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.9`
## \[2.0.0-rc.8]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.8`
## \[2.0.0-rc.7]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.7`
## \[2.0.0-rc.6]
### What's Changed
- [`f4d5241b3`](https://www.github.com/tauri-apps/tauri/commit/f4d5241b377d0f7a1b58100ee19f7843384634ac) ([#10731](https://www.github.com/tauri-apps/tauri/pull/10731) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Update documentation icon path.
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.6`
## \[2.0.0-rc.5]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.5`
## \[2.0.0-rc.4]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.4`
## \[2.0.0-rc.3]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.3`
## \[2.0.0-rc.2]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.2`
## \[2.0.0-rc.1]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.1`
## \[2.0.0-rc.0]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-rc.0`
### Breaking Changes
- [`758d28c8a`](https://www.github.com/tauri-apps/tauri/commit/758d28c8a2d5c9567158e339326b765f72da983e) ([#10390](https://www.github.com/tauri-apps/tauri/pull/10390)) Core plugin permissions are now prefixed with `core:`, the `core:default` permission set can now be used and the `core` plugin name is reserved.
The `tauri migrate` tool will automate the migration process, which involves prefixing all `app`, `event`, `image`, `menu`, `path`, `resources`, `tray`, `webview` and `window` permissions with `core:`.
## \[2.0.0-beta.19]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.19`
## \[2.0.0-beta.18]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.18`
## \[2.0.0-beta.17]
### New Features
- [`8a1ae2dea`](https://www.github.com/tauri-apps/tauri/commit/8a1ae2deaf3086e531ada25b1627f900e2e421fb)([#9843](https://www.github.com/tauri-apps/tauri/pull/9843)) Added an option to use a Xcode project for the iOS plugin instead of a plain SwiftPM project.
### What's Changed
- [`9ac930380`](https://www.github.com/tauri-apps/tauri/commit/9ac930380a5df3fe700e68e75df8684d261ca292)([#9850](https://www.github.com/tauri-apps/tauri/pull/9850)) Emit `cargo:rustc-check-cfg` instruction so Cargo validates custom cfg attributes on Rust 1.80 (or nightly-2024-05-05).
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.17`
## \[2.0.0-beta.16]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.16`
## \[2.0.0-beta.15]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.15`
## \[2.0.0-beta.14]
### Enhancements
- [`bf2635ab6`](https://www.github.com/tauri-apps/tauri/commit/bf2635ab6241a5b82569eafc939046d6e245f3ad)([#9632](https://www.github.com/tauri-apps/tauri/pull/9632)) Improve the error message that is shown when the `links` property is missing from a Tauri Plugin.
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.14`
## \[2.0.0-beta.13]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.13`
## \[2.0.0-beta.12]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.12`
## \[2.0.0-beta.11]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.11`
## \[2.0.0-beta.10]
### New Features
- [`e227fe02f`](https://www.github.com/tauri-apps/tauri/commit/e227fe02f986e145c0731a64693e1c830a9eb5b0)([#9156](https://www.github.com/tauri-apps/tauri/pull/9156)) Allow plugins to define (at compile time) JavaScript that are initialized when `withGlobalTauri` is true.
- [`e227fe02f`](https://www.github.com/tauri-apps/tauri/commit/e227fe02f986e145c0731a64693e1c830a9eb5b0)([#9156](https://www.github.com/tauri-apps/tauri/pull/9156)) Added `Builder::global_api_script_path` to define a JavaScript file containing the initialization script for the plugin API bindings when `withGlobalTauri` is used.
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.10`
## \[2.0.0-beta.9]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.9`
## \[2.0.0-beta.8]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.8`
## \[2.0.0-beta.7]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.7`
## \[2.0.0-beta.6]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.6`
### Breaking Changes
- [`3657ad82`](https://www.github.com/tauri-apps/tauri/commit/3657ad82f88ce528551d032d521c52eed3f396b4)([#9008](https://www.github.com/tauri-apps/tauri/pull/9008)) Allow defining permissions for the application commands via `tauri_build::Attributes::app_manifest`.
## \[2.0.0-beta.5]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.5`
## \[2.0.0-beta.4]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.4`
## \[2.0.0-beta.3]
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.3`
## \[2.0.0-beta.2]
### Enhancements
- [`dd7571a7`](https://www.github.com/tauri-apps/tauri/commit/dd7571a7808676c8063a4983b9c6687dfaf03a09)([#8815](https://www.github.com/tauri-apps/tauri/pull/8815)) Do not generate JSON schema and markdown reference file if the plugin does not define any permissions and delete those files if they exist.
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.2`
## \[2.0.0-beta.1]
### Bug Fixes
- [`4e101f80`](https://www.github.com/tauri-apps/tauri/commit/4e101f801657e7d01ce8c22f9c6468067d0caab2)([#8756](https://www.github.com/tauri-apps/tauri/pull/8756)) Rerun build script when a new permission is added.
### Dependencies
- Upgraded to `tauri-utils@2.0.0-beta.1`
## \[2.0.0-beta.0]
### New Features
- [`74a2a603`](https://www.github.com/tauri-apps/tauri/commit/74a2a6036a5e57462f161d728cbd8a6f121028ca)([#8661](https://www.github.com/tauri-apps/tauri/pull/8661)) Implement access control list for IPC usage.

View File

@@ -0,0 +1,41 @@
[package]
name = "tauri-plugin"
version = "2.6.3"
description = "Build script and runtime Tauri plugin definitions"
authors.workspace = true
homepage.workspace = true
repository.workspace = true
categories.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[package.metadata.docs.rs]
features = ["build", "runtime"]
[features]
build = [
"dep:anyhow",
"dep:serde",
"dep:serde_json",
"dep:glob",
"dep:plist",
"dep:walkdir",
]
runtime = []
[dependencies]
anyhow = { version = "1", optional = true }
serde = { version = "1", optional = true }
tauri-utils = { workspace = true, features = ["build-2"] }
serde_json = { version = "1", optional = true }
glob = { version = "0.3", optional = true }
# Our code requires at least 0.8.22 so don't simplify this to 0.8
schemars = { version = "0.8.22", features = ["preserve_order"] }
walkdir = { version = "2", optional = true }
[target."cfg(target_os = \"macos\")".dependencies]
plist = { version = "1", optional = true }
[lints]
workspace = true

View File

@@ -0,0 +1,231 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! Mobile-specific build utilities.
use std::{
fs::{copy, create_dir, create_dir_all, remove_dir_all},
path::{Path, PathBuf},
};
use anyhow::{Context, Result};
use super::{build_var, cfg_alias};
/// Patches the entitlements file of the iOS project of the application that depends on this
/// plugin, so the plugin can request the capabilities its native code needs
/// (push notifications, app groups, HealthKit, iCloud...).
///
/// It edits `<project>/<app-name>_iOS/<app-name>_iOS.entitlements` of the Xcode project
/// generated by `tauri ios init`, reading its path from the `TAURI_IOS_PROJECT_PATH` and
/// `TAURI_IOS_APP_NAME` environment variables set by the Tauri CLI. It is a no-op when they are
/// not set (a plain `cargo build`, or a desktop build) or when the file does not exist, and the
/// file is only written when the closure actually changed it.
///
/// Must be called from the plugin `build.rs`, ideally guarded by a
/// [`plugin_config`](super::plugin_config) value so the app can opt in to the entitlement.
/// Only available on macOS hosts, where the iOS project can be built.
///
/// # Examples
///
/// ```rust,no_run
/// tauri_plugin::mobile::update_entitlements(|entitlements| {
/// entitlements.insert("aps-environment".into(), "development".into());
/// })
/// .expect("failed to update entitlements");
/// ```
#[cfg(target_os = "macos")]
pub fn update_entitlements<F: FnOnce(&mut plist::Dictionary)>(f: F) -> Result<()> {
if let (Some(project_path), Ok(app_name)) = (
std::env::var_os("TAURI_IOS_PROJECT_PATH").map(PathBuf::from),
std::env::var("TAURI_IOS_APP_NAME"),
) {
update_plist_file(
project_path
.join(format!("{app_name}_iOS"))
.join(format!("{app_name}_iOS.entitlements")),
f,
)?;
}
Ok(())
}
/// Patches the `Info.plist` of the iOS project of the application that depends on this plugin,
/// which is where iOS expects the usage descriptions, URL schemes and background modes a
/// plugin needs to be declared.
///
/// It edits `<project>/<app-name>_iOS/Info.plist` of the Xcode project generated by
/// `tauri ios init`, reading its path from the `TAURI_IOS_PROJECT_PATH` and
/// `TAURI_IOS_APP_NAME` environment variables set by the Tauri CLI. It is a no-op when they are
/// not set (a plain `cargo build`, or a desktop build) or when the file does not exist, and the
/// file is only written when the closure actually changed it.
///
/// Must be called from the plugin `build.rs`. Values that are specific to the application, such
/// as the text shown on a permission prompt, should be read from the plugin configuration with
/// [`plugin_config`](super::plugin_config) instead of hardcoded.
/// Only available on macOS hosts, where the iOS project can be built.
///
/// # Examples
///
/// ```rust,no_run
/// tauri_plugin::mobile::update_info_plist(|plist| {
/// plist.insert(
/// "NSCameraUsageDescription".into(),
/// "This app needs the camera to scan QR codes".into(),
/// );
/// })
/// .expect("failed to update Info.plist");
/// ```
#[cfg(target_os = "macos")]
pub fn update_info_plist<F: FnOnce(&mut plist::Dictionary)>(f: F) -> Result<()> {
if let (Some(project_path), Ok(app_name)) = (
std::env::var_os("TAURI_IOS_PROJECT_PATH").map(PathBuf::from),
std::env::var("TAURI_IOS_APP_NAME"),
) {
update_plist_file(
project_path
.join(format!("{app_name}_iOS"))
.join("Info.plist"),
f,
)?;
}
Ok(())
}
/// Updates the Android manifest by inserting XML content into a specified parent tag.
pub fn update_android_manifest(block_identifier: &str, parent: &str, insert: String) -> Result<()> {
tauri_utils::build::update_android_manifest(block_identifier, parent, insert)
}
pub(crate) fn setup(
android_path: Option<PathBuf>,
#[allow(unused_variables)] ios_path: Option<PathBuf>,
) -> Result<()> {
let target_os = build_var("CARGO_CFG_TARGET_OS")?;
let mobile = target_os == "android" || target_os == "ios";
cfg_alias("mobile", mobile);
cfg_alias("desktop", !mobile);
match target_os.as_str() {
"android" => {
if let Some(path) = android_path {
let manifest_dir = build_var("CARGO_MANIFEST_DIR").map(PathBuf::from)?;
let source = manifest_dir.join(path);
let tauri_library_path = std::env::var("DEP_TAURI_ANDROID_LIBRARY_PATH")
.expect("missing `DEP_TAURI_ANDROID_LIBRARY_PATH` environment variable. Make sure `tauri` is a dependency of the plugin.");
println!("cargo:rerun-if-env-changed=DEP_TAURI_ANDROID_LIBRARY_PATH");
create_dir_all(source.join(".tauri")).context("failed to create .tauri directory")?;
copy_folder(
Path::new(&tauri_library_path),
&source.join(".tauri").join("tauri-api"),
&[],
)
.context("failed to copy tauri-api to the plugin project")?;
println!("cargo:android_library_path={}", source.display());
}
}
#[cfg(target_os = "macos")]
"ios" => {
if let Some(path) = ios_path {
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.unwrap();
let tauri_library_path = std::env::var("DEP_TAURI_IOS_LIBRARY_PATH")
.expect("missing `DEP_TAURI_IOS_LIBRARY_PATH` environment variable. Make sure `tauri` is a dependency of the plugin.");
let tauri_dep_path = path.parent().unwrap().join(".tauri");
create_dir_all(&tauri_dep_path).context("failed to create .tauri directory")?;
copy_folder(
Path::new(&tauri_library_path),
&tauri_dep_path.join("tauri-api"),
&[".build", "Package.resolved", "Tests"],
)
.context("failed to copy tauri-api to the plugin project")?;
tauri_utils::build::link_apple_library(
&std::env::var("CARGO_PKG_NAME").unwrap(),
manifest_dir.join(path),
);
}
}
_ => (),
}
Ok(())
}
fn copy_folder(source: &Path, target: &Path, ignore_paths: &[&str]) -> Result<()> {
let _ = remove_dir_all(target);
for entry in walkdir::WalkDir::new(source) {
let entry = entry?;
let rel_path = entry.path().strip_prefix(source)?;
let rel_path_str = rel_path.to_string_lossy();
if ignore_paths
.iter()
.any(|path| rel_path_str.starts_with(path))
{
continue;
}
let dest_path = target.join(rel_path);
if entry.file_type().is_dir() {
create_dir(&dest_path)
.with_context(|| format!("failed to create directory {}", dest_path.display()))?;
} else {
copy(entry.path(), &dest_path).with_context(|| {
format!(
"failed to copy {} to {}",
entry.path().display(),
dest_path.display()
)
})?;
println!("cargo:rerun-if-changed={}", entry.path().display());
}
}
Ok(())
}
#[cfg(target_os = "macos")]
fn update_plist_file<P: AsRef<Path>, F: FnOnce(&mut plist::Dictionary)>(
path: P,
f: F,
) -> Result<()> {
use std::io::Cursor;
let path = path.as_ref();
if path.exists() {
let plist_str = std::fs::read_to_string(path)?;
let mut plist = plist::Value::from_reader(Cursor::new(&plist_str))?;
if let Some(dict) = plist.as_dictionary_mut() {
f(dict);
let mut plist_buf = Vec::new();
let writer = Cursor::new(&mut plist_buf);
plist::to_writer_xml(writer, &plist)?;
let new_plist_str = String::from_utf8(plist_buf)?;
if new_plist_str != plist_str {
std::fs::write(path, new_plist_str)?;
}
}
}
Ok(())
}
#[cfg(test)]
mod tests {
#[test]
fn update_android_manifest() {
use tauri_utils::build::update_android_manifest;
// This test would require setting up the environment, so we just verify it compiles
// The actual implementation is tested in tauri-utils
let _result = update_android_manifest("test", "activity", "<test></test>".to_string());
}
}

View File

@@ -0,0 +1,220 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use std::{
collections::BTreeMap,
path::{Path, PathBuf},
};
use anyhow::Result;
use tauri_utils::acl::{self, Error};
pub mod mobile;
use serde::de::DeserializeOwned;
use std::{env, io::Cursor};
const RESERVED_PLUGIN_NAMES: &[&str] = &["core", "tauri"];
/// Reads the configuration of the plugin with the given name from the environment.
///
/// Tauri applications configure plugins through the `plugins > $plugin-name` object of their
/// `tauri.conf.json`. The Tauri CLI forwards that object to the build script of the plugin
/// through the `TAURI_<PLUGIN_NAME>_PLUGIN_CONFIG` environment variable (uppercased, with `-`
/// replaced by `_`), so plugins can generate platform-specific files from it - for example
/// adding a usage description to the iOS `Info.plist` with `mobile::update_info_plist`
/// (macOS hosts only).
///
/// Returns `None` when the variable is not set, which is the case when the crate is built
/// without the Tauri CLI (e.g. a plain `cargo build`), so the build script must always be able
/// to run without a configuration.
///
/// Also emits a `cargo:rerun-if-env-changed` instruction for the variable.
///
/// # Examples
///
/// ```rust,no_run
/// // usually a type deriving `serde::Deserialize`
/// let config = tauri_plugin::plugin_config::<serde_json::Value>("my-plugin");
/// let timeout = config
/// .and_then(|c| c.get("timeout").and_then(|t| t.as_u64()))
/// .unwrap_or(30);
/// ```
///
/// # Panics
///
/// Panics if the value of the environment variable is not a valid JSON representation of `T`,
/// which means the plugin configuration on the app's `tauri.conf.json` does not match the
/// expected format.
pub fn plugin_config<T: DeserializeOwned>(name: &str) -> Option<T> {
let config_env_var_name = format!(
"TAURI_{}_PLUGIN_CONFIG",
name.to_uppercase().replace('-', "_")
);
if let Ok(config_str) = env::var(&config_env_var_name) {
println!("cargo:rerun-if-env-changed={config_env_var_name}");
serde_json::from_reader(Cursor::new(config_str))
.map(Some)
.expect("failed to parse configuration")
} else {
None
}
}
/// Builder of the Tauri plugin build script.
///
/// It must be executed from the `build.rs` of every Tauri plugin crate - see
/// [`Self::try_build`] for everything it does.
///
/// # Examples
///
/// ```rust,no_run
/// const COMMANDS: &[&str] = &["ping", "execute"];
///
/// tauri_plugin::Builder::new(COMMANDS)
/// .android_path("android")
/// .ios_path("ios")
/// .build();
/// ```
pub struct Builder<'a> {
commands: &'a [&'static str],
global_scope_schema: Option<schemars::schema::RootSchema>,
global_api_script_path: Option<PathBuf>,
android_path: Option<PathBuf>,
ios_path: Option<PathBuf>,
}
impl<'a> Builder<'a> {
/// Creates a new builder for a plugin exposing the given commands.
///
/// The command names must be written in snake_case, matching the name of the Rust functions
/// annotated with `#[tauri::command]`. An `allow-$command` and a `deny-$command` permission
/// is generated for each of them in the `permissions/autogenerated/commands` directory,
/// where `$command` is the command name with `_` replaced by `-`.
///
/// Note that the default permission of the plugin is **not** autogenerated:
/// it must be defined in a `permissions/default.toml` (or `.json`) file.
pub fn new(commands: &'a [&'static str]) -> Self {
Self {
commands,
global_scope_schema: None,
global_api_script_path: None,
android_path: None,
ios_path: None,
}
}
/// Sets the global scope JSON schema.
pub fn global_scope_schema(mut self, schema: schemars::schema::RootSchema) -> Self {
self.global_scope_schema.replace(schema);
self
}
/// Sets the path to the script that is injected in the webview when the `withGlobalTauri` configuration is set to true.
///
/// This is usually an IIFE that injects the plugin API JavaScript bindings to `window.__TAURI__`.
pub fn global_api_script_path<P: Into<PathBuf>>(mut self, path: P) -> Self {
self.global_api_script_path.replace(path.into());
self
}
/// Sets the Android project path.
pub fn android_path<P: Into<PathBuf>>(mut self, android_path: P) -> Self {
self.android_path.replace(android_path.into());
self
}
/// Sets the iOS project path.
pub fn ios_path<P: Into<PathBuf>>(mut self, ios_path: P) -> Self {
self.ios_path.replace(ios_path.into());
self
}
/// [`Self::try_build`] but will exit automatically if an error is found.
pub fn build(self) {
if let Err(error) = self.try_build() {
println!("{}: {error:#}", env!("CARGO_PKG_NAME"));
std::process::exit(1);
}
}
/// Ensure this crate is properly configured to be a Tauri plugin.
///
/// # Errors
///
/// Errors will occur if environmental variables expected to be set inside of [build scripts]
/// are not found, or if the crate violates Tauri plugin conventions.
pub fn try_build(self) -> Result<()> {
// convention: plugin names should not use underscores
let name = build_var("CARGO_PKG_NAME")?;
if name.contains('_') {
anyhow::bail!("plugin names cannot contain underscores");
}
if RESERVED_PLUGIN_NAMES.contains(&name.as_str()) {
anyhow::bail!("plugin name `{name}` is reserved");
}
let out_dir = PathBuf::from(build_var("OUT_DIR")?);
// requirement: links MUST be set and MUST match the name
let _links = std::env::var("CARGO_MANIFEST_LINKS").map_err(|_| Error::LinksMissing)?;
let autogenerated = Path::new("permissions").join(acl::build::AUTOGENERATED_FOLDER_NAME);
std::fs::create_dir_all(&autogenerated).expect("unable to create permissions dir");
let commands_dir = autogenerated.join("commands");
if !self.commands.is_empty() {
acl::build::autogenerate_command_permissions(&commands_dir, self.commands, "", true);
}
println!("cargo:rerun-if-changed=permissions");
let permissions =
acl::build::define_permissions("./permissions/**/*.*", &name, &out_dir, |_| true)?;
if permissions.is_empty() {
let _ = std::fs::remove_file(format!(
"./permissions/{}/{}",
acl::PERMISSION_SCHEMAS_FOLDER_NAME,
acl::PERMISSION_SCHEMA_FILE_NAME
));
let _ = std::fs::remove_file(autogenerated.join(acl::build::PERMISSION_DOCS_FILE_NAME));
} else {
acl::schema::generate_permissions_schema(&permissions, "./permissions")?;
acl::build::generate_docs(
&permissions,
&autogenerated,
name.strip_prefix("tauri-plugin-").unwrap_or(&name),
)?;
}
let mut permissions_map = BTreeMap::new();
permissions_map.insert(name.clone(), permissions);
tauri_utils::acl::build::generate_allowed_commands(&out_dir, None, permissions_map)?;
if let Some(global_scope_schema) = self.global_scope_schema {
acl::build::define_global_scope_schema(global_scope_schema, &name, &out_dir)?;
}
if let Some(path) = self.global_api_script_path {
tauri_utils::plugin::define_global_api_script_path(&path);
}
mobile::setup(self.android_path, self.ios_path)?;
Ok(())
}
}
fn cfg_alias(alias: &str, has_feature: bool) {
println!("cargo:rustc-check-cfg=cfg({alias})");
if has_feature {
println!("cargo:rustc-cfg={alias}");
}
}
/// Grab an env var that is expected to be set inside of build scripts.
fn build_var(key: &'static str) -> Result<String, Error> {
std::env::var(key).map_err(|_| Error::BuildVar(key))
}

View File

@@ -0,0 +1,85 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! Interface for building Tauri plugins.
//!
//! A Tauri plugin is a Rust crate that extends a Tauri application with commands, state,
//! lifecycle hooks and - optionally - Android and iOS native code. This crate holds the pieces
//! of that interface that are not part of the [`tauri`] crate itself, split in two Cargo
//! features:
//!
//! - **`build`**: helpers for the plugin `build.rs`. [`Builder`] checks the crate against the
//! Tauri plugin conventions (the `links` key must be set and match the crate name, the name
//! cannot contain underscores or be a reserved one), autogenerates the
//! `allow-$command`/`deny-$command` permissions for the plugin commands, parses the
//! permission files, generates their JSON schema and reference documentation, defines the
//! global scope schema and links the Android/iOS projects of the plugin.
//! [`plugin_config`] reads the plugin configuration the Tauri CLI forwards to the build
//! script, and the [`mobile`] module has helpers to patch the generated iOS `Info.plist` and
//! entitlements and the Android manifest.
//! - **`runtime`**: reserved for the runtime side of the plugin interface. It currently
//! exports nothing - use [`tauri::plugin`] to define the plugin itself.
//!
//! # Examples
//!
//! A typical plugin `build.rs`:
//!
//! ```rust,ignore
//! const COMMANDS: &[&str] = &["ping", "execute"];
//!
//! fn main() {
//! tauri_plugin::Builder::new(COMMANDS)
//! .android_path("android")
//! .ios_path("ios")
//! .build();
//! }
//! ```
//!
//! With a configuration type and an iOS `Info.plist` change:
//!
//! ```rust,ignore
//! #[derive(serde::Deserialize)]
//! #[serde(rename_all = "camelCase")]
//! struct Config {
//! camera_usage_description: Option<String>,
//! }
//!
//! fn main() {
//! if let Some(config) = tauri_plugin::plugin_config::<Config>("my-plugin") {
//! if let Some(description) = config.camera_usage_description {
//! tauri_plugin::mobile::update_info_plist(|plist| {
//! plist.insert("NSCameraUsageDescription".into(), description.into());
//! })
//! .expect("failed to update Info.plist");
//! }
//! }
//!
//! tauri_plugin::Builder::new(&["take_picture"]).build();
//! }
//! ```
//!
//! [`tauri`]: https://docs.rs/tauri/latest/tauri/
//! [`tauri::plugin`]: https://docs.rs/tauri/latest/tauri/plugin/index.html
//! [`Builder`]: https://docs.rs/tauri-plugin/latest/tauri_plugin/struct.Builder.html
//! [`plugin_config`]: https://docs.rs/tauri-plugin/latest/tauri_plugin/fn.plugin_config.html
//! [`mobile`]: https://docs.rs/tauri-plugin/latest/tauri_plugin/mobile/index.html
#![doc(
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png",
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png"
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(feature = "build")]
mod build;
#[cfg(feature = "runtime")]
mod runtime;
#[cfg(feature = "build")]
#[cfg_attr(docsrs, doc(cfg(feature = "build")))]
pub use build::*;
#[cfg(feature = "runtime")]
#[cfg_attr(docsrs, doc(cfg(feature = "runtime")))]
#[allow(unused)]
pub use runtime::*;

View File

@@ -0,0 +1,3 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT