mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-07 10:22:29 +02:00
initial plugin metadata implementation
This commit is contained in:
@@ -34,6 +34,8 @@ mod codegen;
|
||||
pub mod config;
|
||||
/// Mobile build functions.
|
||||
pub mod mobile;
|
||||
/// Build scripts for Tauri plugins.
|
||||
pub mod plugin;
|
||||
mod static_vcruntime;
|
||||
|
||||
#[cfg(feature = "codegen")]
|
||||
@@ -473,6 +475,8 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let _manifests = plugin::manifests();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
130
core/tauri-build/src/plugin.rs
Normal file
130
core/tauri-build/src/plugin.rs
Normal file
@@ -0,0 +1,130 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env::{var_os, vars_os},
|
||||
fs::{read_to_string, write},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
const PLUGIN_METADATA_KEY: &str = "PLUGIN_MANIFEST_PATH";
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum ScopeType {
|
||||
String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct CapabilityScope {
|
||||
#[serde(default)]
|
||||
allowed: Vec<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
blocked: Vec<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Capability {
|
||||
id: Option<String>,
|
||||
description: String,
|
||||
#[serde(default)]
|
||||
features: Vec<String>,
|
||||
#[serde(default)]
|
||||
scope: CapabilityScope,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Manifest {
|
||||
plugin: String,
|
||||
default_capability: Option<Capability>,
|
||||
capabilities: Vec<Capability>,
|
||||
features: Vec<String>,
|
||||
scope_type: Vec<ScopeType>,
|
||||
}
|
||||
|
||||
impl Manifest {
|
||||
pub fn new(plugin: impl Into<String>) -> Self {
|
||||
Self {
|
||||
plugin: plugin.into(),
|
||||
default_capability: None,
|
||||
capabilities: Vec::new(),
|
||||
features: Vec::new(),
|
||||
scope_type: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_capability(mut self, default_capability: impl AsRef<str>) -> Self {
|
||||
let mut capability: Capability = serde_json::from_str(default_capability.as_ref())
|
||||
.expect("failed to deserialize default capability");
|
||||
assert!(
|
||||
capability.id.is_none(),
|
||||
"default capability cannot have an specific identifier"
|
||||
);
|
||||
capability.id.replace("default".into());
|
||||
self.default_capability.replace(capability);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn capability(mut self, capability: impl AsRef<str>) -> Self {
|
||||
let capability: Capability =
|
||||
serde_json::from_str(capability.as_ref()).expect("failed to deserialize default capability");
|
||||
assert!(
|
||||
capability.id.is_some(),
|
||||
"capability must have an specific identifier"
|
||||
);
|
||||
self.capabilities.push(capability);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn feature(mut self, feature: impl Into<String>) -> Self {
|
||||
self.features.push(feature.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn features<I: IntoIterator<Item = S>, S: Into<String>>(mut self, features: I) -> Self {
|
||||
for feature in features {
|
||||
self = self.feature(feature);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn scope_type(mut self, ty: ScopeType) -> Self {
|
||||
self.scope_type.push(ty);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_manifest(manifest: Manifest) {
|
||||
let manifest_str = serde_json::to_string(&manifest).expect("failed to serialize plugin manifest");
|
||||
let manifest_path = var_os("OUT_DIR")
|
||||
.map(PathBuf::from)
|
||||
.expect(
|
||||
"missing OUT_DIR environment variable.. are you sure you are running this on a build script?",
|
||||
)
|
||||
.join("plugin-manifest.json");
|
||||
write(&manifest_path, manifest_str).expect("failed to save manifest file");
|
||||
|
||||
println!("cargo:{PLUGIN_METADATA_KEY}={}", manifest_path.display());
|
||||
}
|
||||
|
||||
pub(crate) fn manifests() -> HashMap<String, Manifest> {
|
||||
let mut manifests = HashMap::new();
|
||||
|
||||
for (key, value) in vars_os() {
|
||||
let key = key.to_string_lossy();
|
||||
if let Some(_plugin_crate_name) = key
|
||||
.strip_prefix("DEP_")
|
||||
.and_then(|v| v.strip_suffix(&format!("_{PLUGIN_METADATA_KEY}")))
|
||||
.map(|p| p.to_lowercase())
|
||||
{
|
||||
let plugin_manifest_path = PathBuf::from(value);
|
||||
let plugin_manifest_str =
|
||||
read_to_string(&plugin_manifest_path).expect("failed to read plugin manifest");
|
||||
let manifest: Manifest =
|
||||
serde_json::from_str(&plugin_manifest_str).expect("failed to deserialize plugin manifest");
|
||||
|
||||
manifests.insert(manifest.plugin.clone(), manifest);
|
||||
}
|
||||
}
|
||||
|
||||
manifests
|
||||
}
|
||||
1
examples/api/src-tauri/Cargo.lock
generated
1
examples/api/src-tauri/Cargo.lock
generated
@@ -3364,6 +3364,7 @@ dependencies = [
|
||||
"cargo_toml",
|
||||
"heck",
|
||||
"json-patch",
|
||||
"plist",
|
||||
"quote",
|
||||
"semver",
|
||||
"serde",
|
||||
|
||||
1452
examples/api/src-tauri/tauri-plugin-sample/Cargo.lock
generated
1452
examples/api/src-tauri/tauri-plugin-sample/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -3,9 +3,13 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::process::exit;
|
||||
use tauri_build::{
|
||||
mobile::PluginBuilder,
|
||||
plugin::{set_manifest, Manifest, ScopeType},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
if let Err(error) = tauri_build::mobile::PluginBuilder::new()
|
||||
if let Err(error) = PluginBuilder::new()
|
||||
.android_path("android")
|
||||
.ios_path("ios")
|
||||
.run()
|
||||
@@ -13,4 +17,12 @@ fn main() {
|
||||
println!("{error:#}");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
set_manifest(
|
||||
Manifest::new("sample")
|
||||
.default_capability(include_str!("capabilities/default.json"))
|
||||
.capability(include_str!("capabilities/ping.json"))
|
||||
.feature("ping")
|
||||
.scope_type(ScopeType::String),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"features": [],
|
||||
"description": "Default empty capability set",
|
||||
"scope": {
|
||||
"allowed": [],
|
||||
"denied": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"id": "allow-ping",
|
||||
"description": "Allows the ping command",
|
||||
"features": [
|
||||
"ping"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user