22// SPDX-License-Identifier: Apache-2.0
33// SPDX-License-Identifier: MIT
44
5- use anyhow:: Context ;
65use clap:: Parser ;
76use colored:: Colorize ;
87use regex:: Regex ;
98
109use crate :: {
10+ acl,
1111 helpers:: {
1212 app_paths:: { app_dir, tauri_dir} ,
13- cross_command ,
13+ cargo ,
1414 npm:: PackageManager ,
1515 } ,
1616 Result ,
1717} ;
1818
1919use std:: { collections:: HashMap , process:: Command } ;
2020
21+ #[ derive( Default ) ]
22+ struct PluginMetadata {
23+ desktop_only : bool ,
24+ rust_only : bool ,
25+ builder : bool ,
26+ }
27+
28+ // known plugins with particular cases
29+ fn plugins ( ) -> HashMap < & ' static str , PluginMetadata > {
30+ let mut plugins: HashMap < & ' static str , PluginMetadata > = HashMap :: new ( ) ;
31+
32+ // desktop-only
33+ for p in [
34+ "authenticator" ,
35+ "cli" ,
36+ "global-shortcut" ,
37+ "updater" ,
38+ "window-state" ,
39+ ] {
40+ plugins. entry ( p) . or_default ( ) . desktop_only = true ;
41+ }
42+
43+ // uses builder pattern
44+ for p in [
45+ "global-shortcut" ,
46+ "localhost" ,
47+ "log" ,
48+ "sql" ,
49+ "store" ,
50+ "stronghold" ,
51+ "updater" ,
52+ "window-state" ,
53+ ] {
54+ plugins. entry ( p) . or_default ( ) . builder = true ;
55+ }
56+
57+ // rust-only
58+ #[ allow( clippy:: single_element_loop) ]
59+ for p in [ "localhost" ] {
60+ plugins. entry ( p) . or_default ( ) . rust_only = true ;
61+ }
62+
63+ plugins
64+ }
65+
2166#[ derive( Debug , Parser ) ]
2267#[ clap( about = "Add a tauri plugin to the project" ) ]
2368pub struct Options {
@@ -45,43 +90,16 @@ pub fn command(options: Options) -> Result<()> {
4590
4691 let tauri_dir = tauri_dir ( ) ;
4792
48- let mut cargo = Command :: new ( "cargo" ) ;
49- cargo. current_dir ( & tauri_dir) . arg ( "add" ) . arg ( & crate_name) ;
50-
51- if options. tag . is_some ( ) || options. rev . is_some ( ) || options. branch . is_some ( ) {
52- cargo
53- . arg ( "--git" )
54- . arg ( "https://github.com/tauri-apps/plugins-workspace" ) ;
55- }
56-
57- if metadata. desktop_only {
58- cargo
59- . arg ( "--target" )
60- . arg ( r#"cfg(not(any(target_os = "android", target_os = "ios")))"# ) ;
61- }
62-
63- let npm_spec = match ( options. tag , options. rev , options. branch ) {
64- ( Some ( tag) , None , None ) => {
65- cargo. args ( [ "--tag" , & tag] ) ;
66- format ! ( "tauri-apps/tauri-plugin-{plugin}#{tag}" )
67- }
68- ( None , Some ( rev) , None ) => {
69- cargo. args ( [ "--rev" , & rev] ) ;
70- format ! ( "tauri-apps/tauri-plugin-{plugin}#{rev}" )
71- }
72- ( None , None , Some ( branch) ) => {
73- cargo. args ( [ "--branch" , & branch] ) ;
74- format ! ( "tauri-apps/tauri-plugin-{plugin}#{branch}" )
75- }
76- ( None , None , None ) => npm_name,
77- _ => anyhow:: bail!( "Only one of --tag, --rev and --branch can be specified" ) ,
78- } ;
79-
80- log:: info!( "Installing Cargo dependency {crate_name}..." ) ;
81- let status = cargo. status ( ) . context ( "failed to run `cargo add`" ) ?;
82- if !status. success ( ) {
83- anyhow:: bail!( "Failed to install Cargo dependency" ) ;
84- }
93+ cargo:: install_one ( cargo:: CargoInstallOptions {
94+ name : & crate_name,
95+ branch : options. branch . as_deref ( ) ,
96+ rev : options. rev . as_deref ( ) ,
97+ tag : options. tag . as_deref ( ) ,
98+ cwd : Some ( & tauri_dir) ,
99+ target : metadata
100+ . desktop_only
101+ . then_some ( r#"cfg(not(any(target_os = "android", target_os = "ios")))"# ) ,
102+ } ) ?;
85103
86104 if !metadata. rust_only {
87105 if let Some ( manager) = std:: panic:: catch_unwind ( app_dir)
@@ -90,26 +108,28 @@ pub fn command(options: Options) -> Result<()> {
90108 . map ( PackageManager :: from_project)
91109 . and_then ( |managers| managers. into_iter ( ) . next ( ) )
92110 {
93- let mut cmd = match manager {
94- PackageManager :: Npm => cross_command ( "npm" ) ,
95- PackageManager :: Pnpm => cross_command ( "pnpm" ) ,
96- PackageManager :: Yarn => cross_command ( "yarn" ) ,
97- PackageManager :: YarnBerry => cross_command ( "yarn" ) ,
98- PackageManager :: Bun => cross_command ( "bun" ) ,
111+ let npm_spec = match ( options. tag , options. rev , options. branch ) {
112+ ( Some ( tag) , None , None ) => {
113+ format ! ( "tauri-apps/tauri-plugin-{plugin}#{tag}" )
114+ }
115+ ( None , Some ( rev) , None ) => {
116+ format ! ( "tauri-apps/tauri-plugin-{plugin}#{rev}" )
117+ }
118+ ( None , None , Some ( branch) ) => {
119+ format ! ( "tauri-apps/tauri-plugin-{plugin}#{branch}" )
120+ }
121+ ( None , None , None ) => npm_name,
122+ _ => anyhow:: bail!( "Only one of --tag, --rev and --branch can be specified" ) ,
99123 } ;
100-
101- cmd. arg ( "add" ) . arg ( & npm_spec) ;
102-
103- log:: info!( "Installing NPM dependency {npm_spec}..." ) ;
104- let status = cmd
105- . status ( )
106- . with_context ( || format ! ( "failed to run {manager}" ) ) ?;
107- if !status. success ( ) {
108- anyhow:: bail!( "Failed to install NPM dependency" ) ;
109- }
124+ manager. install ( & [ npm_spec] ) ?;
110125 }
111126 }
112127
128+ let _ = acl:: permission:: add:: command ( acl:: permission:: add:: Options {
129+ identifier : format ! ( "{plugin}:default" ) ,
130+ capability : None ,
131+ } ) ;
132+
113133 // add plugin init code to main.rs or lib.rs
114134 let plugin_init_fn = if plugin == "stronghold" {
115135 "Builder::new(|pass| todo!()).build()"
@@ -119,6 +139,7 @@ pub fn command(options: Options) -> Result<()> {
119139 "init()"
120140 } ;
121141 let plugin_init = format ! ( ".plugin(tauri_plugin_{plugin_snake_case}::{plugin_init_fn})" ) ;
142+
122143 let re = Regex :: new ( r"(tauri\s*::\s*Builder\s*::\s*default\(\))(\s*)" ) ?;
123144 for file in [ tauri_dir. join ( "src/main.rs" ) , tauri_dir. join ( "src/lib.rs" ) ] {
124145 let contents = std:: fs:: read_to_string ( & file) ?;
@@ -143,7 +164,6 @@ pub fn command(options: Options) -> Result<()> {
143164 . arg ( "fmt" )
144165 . current_dir ( & tauri_dir)
145166 . status ( ) ;
146-
147167 return Ok ( ( ) ) ;
148168 }
149169 }
@@ -176,48 +196,3 @@ pub fn command(options: Options) -> Result<()> {
176196
177197 Ok ( ( ) )
178198}
179-
180- #[ derive( Default ) ]
181- struct PluginMetadata {
182- desktop_only : bool ,
183- rust_only : bool ,
184- builder : bool ,
185- }
186-
187- // known plugins with particular cases
188- fn plugins ( ) -> HashMap < & ' static str , PluginMetadata > {
189- let mut plugins: HashMap < & ' static str , PluginMetadata > = HashMap :: new ( ) ;
190-
191- // desktop-only
192- for p in [
193- "authenticator" ,
194- "cli" ,
195- "global-shortcut" ,
196- "updater" ,
197- "window-state" ,
198- ] {
199- plugins. entry ( p) . or_default ( ) . desktop_only = true ;
200- }
201-
202- // uses builder pattern
203- for p in [
204- "global-shortcut" ,
205- "localhost" ,
206- "log" ,
207- "sql" ,
208- "store" ,
209- "stronghold" ,
210- "updater" ,
211- "window-state" ,
212- ] {
213- plugins. entry ( p) . or_default ( ) . builder = true ;
214- }
215-
216- // rust-only
217- #[ allow( clippy:: single_element_loop) ]
218- for p in [ "localhost" ] {
219- plugins. entry ( p) . or_default ( ) . rust_only = true ;
220- }
221-
222- plugins
223- }
0 commit comments