|
@@ -2,15 +2,15 @@
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
-use anyhow::Context;
|
|
|
use clap::Parser;
|
|
|
use colored::Colorize;
|
|
|
use regex::Regex;
|
|
|
|
|
|
use crate::{
|
|
|
+ acl,
|
|
|
helpers::{
|
|
|
app_paths::{app_dir, tauri_dir},
|
|
|
- cross_command,
|
|
|
+ cargo,
|
|
|
npm::PackageManager,
|
|
|
},
|
|
|
Result,
|
|
@@ -18,6 +18,51 @@ use crate::{
|
|
|
|
|
|
use std::{collections::HashMap, process::Command};
|
|
|
|
|
|
+#[derive(Default)]
|
|
|
+struct PluginMetadata {
|
|
|
+ desktop_only: bool,
|
|
|
+ rust_only: bool,
|
|
|
+ builder: bool,
|
|
|
+}
|
|
|
+
|
|
|
+// known plugins with particular cases
|
|
|
+fn plugins() -> HashMap<&'static str, PluginMetadata> {
|
|
|
+ let mut plugins: HashMap<&'static str, PluginMetadata> = HashMap::new();
|
|
|
+
|
|
|
+ // desktop-only
|
|
|
+ for p in [
|
|
|
+ "authenticator",
|
|
|
+ "cli",
|
|
|
+ "global-shortcut",
|
|
|
+ "updater",
|
|
|
+ "window-state",
|
|
|
+ ] {
|
|
|
+ plugins.entry(p).or_default().desktop_only = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // uses builder pattern
|
|
|
+ for p in [
|
|
|
+ "global-shortcut",
|
|
|
+ "localhost",
|
|
|
+ "log",
|
|
|
+ "sql",
|
|
|
+ "store",
|
|
|
+ "stronghold",
|
|
|
+ "updater",
|
|
|
+ "window-state",
|
|
|
+ ] {
|
|
|
+ plugins.entry(p).or_default().builder = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // rust-only
|
|
|
+ #[allow(clippy::single_element_loop)]
|
|
|
+ for p in ["localhost"] {
|
|
|
+ plugins.entry(p).or_default().rust_only = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ plugins
|
|
|
+}
|
|
|
+
|
|
|
#[derive(Debug, Parser)]
|
|
|
#[clap(about = "Add a tauri plugin to the project")]
|
|
|
pub struct Options {
|
|
@@ -45,43 +90,16 @@ pub fn command(options: Options) -> Result<()> {
|
|
|
|
|
|
let tauri_dir = tauri_dir();
|
|
|
|
|
|
- let mut cargo = Command::new("cargo");
|
|
|
- cargo.current_dir(&tauri_dir).arg("add").arg(&crate_name);
|
|
|
-
|
|
|
- if options.tag.is_some() || options.rev.is_some() || options.branch.is_some() {
|
|
|
- cargo
|
|
|
- .arg("--git")
|
|
|
- .arg("https://github.com/tauri-apps/plugins-workspace");
|
|
|
- }
|
|
|
-
|
|
|
- if metadata.desktop_only {
|
|
|
- cargo
|
|
|
- .arg("--target")
|
|
|
- .arg(r#"cfg(not(any(target_os = "android", target_os = "ios")))"#);
|
|
|
- }
|
|
|
-
|
|
|
- let npm_spec = match (options.tag, options.rev, options.branch) {
|
|
|
- (Some(tag), None, None) => {
|
|
|
- cargo.args(["--tag", &tag]);
|
|
|
- format!("tauri-apps/tauri-plugin-{plugin}#{tag}")
|
|
|
- }
|
|
|
- (None, Some(rev), None) => {
|
|
|
- cargo.args(["--rev", &rev]);
|
|
|
- format!("tauri-apps/tauri-plugin-{plugin}#{rev}")
|
|
|
- }
|
|
|
- (None, None, Some(branch)) => {
|
|
|
- cargo.args(["--branch", &branch]);
|
|
|
- format!("tauri-apps/tauri-plugin-{plugin}#{branch}")
|
|
|
- }
|
|
|
- (None, None, None) => npm_name,
|
|
|
- _ => anyhow::bail!("Only one of --tag, --rev and --branch can be specified"),
|
|
|
- };
|
|
|
-
|
|
|
- log::info!("Installing Cargo dependency {crate_name}...");
|
|
|
- let status = cargo.status().context("failed to run `cargo add`")?;
|
|
|
- if !status.success() {
|
|
|
- anyhow::bail!("Failed to install Cargo dependency");
|
|
|
- }
|
|
|
+ cargo::install_one(cargo::CargoInstallOptions {
|
|
|
+ name: &crate_name,
|
|
|
+ branch: options.branch.as_deref(),
|
|
|
+ rev: options.rev.as_deref(),
|
|
|
+ tag: options.tag.as_deref(),
|
|
|
+ cwd: Some(&tauri_dir),
|
|
|
+ target: metadata
|
|
|
+ .desktop_only
|
|
|
+ .then_some(r#"cfg(not(any(target_os = "android", target_os = "ios")))"#),
|
|
|
+ })?;
|
|
|
|
|
|
if !metadata.rust_only {
|
|
|
if let Some(manager) = std::panic::catch_unwind(app_dir)
|
|
@@ -90,26 +108,28 @@ pub fn command(options: Options) -> Result<()> {
|
|
|
.map(PackageManager::from_project)
|
|
|
.and_then(|managers| managers.into_iter().next())
|
|
|
{
|
|
|
- let mut cmd = match manager {
|
|
|
- PackageManager::Npm => cross_command("npm"),
|
|
|
- PackageManager::Pnpm => cross_command("pnpm"),
|
|
|
- PackageManager::Yarn => cross_command("yarn"),
|
|
|
- PackageManager::YarnBerry => cross_command("yarn"),
|
|
|
- PackageManager::Bun => cross_command("bun"),
|
|
|
+ let npm_spec = match (options.tag, options.rev, options.branch) {
|
|
|
+ (Some(tag), None, None) => {
|
|
|
+ format!("tauri-apps/tauri-plugin-{plugin}#{tag}")
|
|
|
+ }
|
|
|
+ (None, Some(rev), None) => {
|
|
|
+ format!("tauri-apps/tauri-plugin-{plugin}#{rev}")
|
|
|
+ }
|
|
|
+ (None, None, Some(branch)) => {
|
|
|
+ format!("tauri-apps/tauri-plugin-{plugin}#{branch}")
|
|
|
+ }
|
|
|
+ (None, None, None) => npm_name,
|
|
|
+ _ => anyhow::bail!("Only one of --tag, --rev and --branch can be specified"),
|
|
|
};
|
|
|
-
|
|
|
- cmd.arg("add").arg(&npm_spec);
|
|
|
-
|
|
|
- log::info!("Installing NPM dependency {npm_spec}...");
|
|
|
- let status = cmd
|
|
|
- .status()
|
|
|
- .with_context(|| format!("failed to run {manager}"))?;
|
|
|
- if !status.success() {
|
|
|
- anyhow::bail!("Failed to install NPM dependency");
|
|
|
- }
|
|
|
+ manager.install(&[npm_spec])?;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ let _ = acl::permission::add::command(acl::permission::add::Options {
|
|
|
+ identifier: format!("{plugin}:default"),
|
|
|
+ capability: None,
|
|
|
+ });
|
|
|
+
|
|
|
// add plugin init code to main.rs or lib.rs
|
|
|
let plugin_init_fn = if plugin == "stronghold" {
|
|
|
"Builder::new(|pass| todo!()).build()"
|
|
@@ -119,6 +139,7 @@ pub fn command(options: Options) -> Result<()> {
|
|
|
"init()"
|
|
|
};
|
|
|
let plugin_init = format!(".plugin(tauri_plugin_{plugin_snake_case}::{plugin_init_fn})");
|
|
|
+
|
|
|
let re = Regex::new(r"(tauri\s*::\s*Builder\s*::\s*default\(\))(\s*)")?;
|
|
|
for file in [tauri_dir.join("src/main.rs"), tauri_dir.join("src/lib.rs")] {
|
|
|
let contents = std::fs::read_to_string(&file)?;
|
|
@@ -143,7 +164,6 @@ pub fn command(options: Options) -> Result<()> {
|
|
|
.arg("fmt")
|
|
|
.current_dir(&tauri_dir)
|
|
|
.status();
|
|
|
-
|
|
|
return Ok(());
|
|
|
}
|
|
|
}
|
|
@@ -176,48 +196,3 @@ pub fn command(options: Options) -> Result<()> {
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
-
|
|
|
-#[derive(Default)]
|
|
|
-struct PluginMetadata {
|
|
|
- desktop_only: bool,
|
|
|
- rust_only: bool,
|
|
|
- builder: bool,
|
|
|
-}
|
|
|
-
|
|
|
-// known plugins with particular cases
|
|
|
-fn plugins() -> HashMap<&'static str, PluginMetadata> {
|
|
|
- let mut plugins: HashMap<&'static str, PluginMetadata> = HashMap::new();
|
|
|
-
|
|
|
- // desktop-only
|
|
|
- for p in [
|
|
|
- "authenticator",
|
|
|
- "cli",
|
|
|
- "global-shortcut",
|
|
|
- "updater",
|
|
|
- "window-state",
|
|
|
- ] {
|
|
|
- plugins.entry(p).or_default().desktop_only = true;
|
|
|
- }
|
|
|
-
|
|
|
- // uses builder pattern
|
|
|
- for p in [
|
|
|
- "global-shortcut",
|
|
|
- "localhost",
|
|
|
- "log",
|
|
|
- "sql",
|
|
|
- "store",
|
|
|
- "stronghold",
|
|
|
- "updater",
|
|
|
- "window-state",
|
|
|
- ] {
|
|
|
- plugins.entry(p).or_default().builder = true;
|
|
|
- }
|
|
|
-
|
|
|
- // rust-only
|
|
|
- #[allow(clippy::single_element_loop)]
|
|
|
- for p in ["localhost"] {
|
|
|
- plugins.entry(p).or_default().rust_only = true;
|
|
|
- }
|
|
|
-
|
|
|
- plugins
|
|
|
-}
|