@@ -31,14 +31,36 @@ impl TomlOrJson {
3131 }
3232 }
3333
34- fn insert_permission ( & mut self , idenitifer : String ) {
34+ fn platforms ( & self ) -> Option < Vec < & str > > {
35+ match self {
36+ TomlOrJson :: Toml ( t) => t. get ( "platforms" ) . and_then ( |k| {
37+ k. as_array ( )
38+ . and_then ( |array| array. iter ( ) . map ( |v| v. as_str ( ) ) . collect ( ) )
39+ } ) ,
40+ TomlOrJson :: Json ( j) => j. get ( "platforms" ) . and_then ( |k| {
41+ if let Some ( array) = k. as_array ( ) {
42+ let mut items = Vec :: new ( ) ;
43+ for item in array {
44+ if let Some ( s) = item. as_str ( ) {
45+ items. push ( s) ;
46+ }
47+ }
48+ Some ( items)
49+ } else {
50+ None
51+ }
52+ } ) ,
53+ }
54+ }
55+
56+ fn insert_permission ( & mut self , identifier : String ) {
3557 match self {
3658 TomlOrJson :: Toml ( t) => {
3759 let permissions = t. entry ( "permissions" ) . or_insert_with ( || {
3860 toml_edit:: Item :: Value ( toml_edit:: Value :: Array ( toml_edit:: Array :: new ( ) ) )
3961 } ) ;
4062 if let Some ( permissions) = permissions. as_array_mut ( ) {
41- permissions. push ( idenitifer )
63+ permissions. push ( identifier )
4264 } ;
4365 }
4466
@@ -48,7 +70,7 @@ impl TomlOrJson {
4870 . entry ( "permissions" )
4971 . or_insert_with ( || serde_json:: Value :: Array ( Vec :: new ( ) ) ) ;
5072 if let Some ( permissions) = permissions. as_array_mut ( ) {
51- permissions. push ( serde_json:: Value :: String ( idenitifer ) )
73+ permissions. push ( serde_json:: Value :: String ( identifier ) )
5274 } ;
5375 }
5476 }
@@ -100,7 +122,13 @@ pub fn command(options: Options) -> Result<()> {
100122 ) ;
101123 }
102124
103- let capabilities = std:: fs:: read_dir ( & capabilities_dir) ?
125+ let known_plugins = crate :: helpers:: plugins:: known_plugins ( ) ;
126+ let known_plugin = options
127+ . identifier
128+ . split_once ( ':' )
129+ . and_then ( |( plugin, _permission) | known_plugins. get ( & plugin) ) ;
130+
131+ let capabilities_iter = std:: fs:: read_dir ( & capabilities_dir) ?
104132 . flatten ( )
105133 . filter ( |e| e. file_type ( ) . map ( |e| e. is_file ( ) ) . unwrap_or_default ( ) )
106134 . filter_map ( |e| {
@@ -109,8 +137,66 @@ pub fn command(options: Options) -> Result<()> {
109137 Some ( c) => ( c == capability. identifier ( ) ) . then_some ( ( capability, path) ) ,
110138 None => Some ( ( capability, path) ) ,
111139 } )
112- } )
113- . collect :: < Vec < _ > > ( ) ;
140+ } ) ;
141+
142+ let ( desktop_only, mobile_only) = known_plugin
143+ . map ( |p| ( p. desktop_only , p. mobile_only ) )
144+ . unwrap_or_default ( ) ;
145+
146+ let expected_capability_config = if desktop_only {
147+ Some ( (
148+ vec ! [
149+ tauri_utils:: platform:: Target :: MacOS . to_string( ) ,
150+ tauri_utils:: platform:: Target :: Windows . to_string( ) ,
151+ tauri_utils:: platform:: Target :: Linux . to_string( ) ,
152+ ] ,
153+ "desktop" ,
154+ ) )
155+ } else if mobile_only {
156+ Some ( (
157+ vec ! [
158+ tauri_utils:: platform:: Target :: Android . to_string( ) ,
159+ tauri_utils:: platform:: Target :: Ios . to_string( ) ,
160+ ] ,
161+ "mobile" ,
162+ ) )
163+ } else {
164+ None
165+ } ;
166+
167+ let capabilities = if let Some ( ( expected_platforms, target_name) ) = expected_capability_config {
168+ let mut capabilities = capabilities_iter
169+ . filter ( |( capability, _path) | {
170+ capability. platforms ( ) . map_or (
171+ false , /* allows any target, so we should skip it since we're adding a target-specific plugin */
172+ |platforms| {
173+ // all platforms must be in the expected platforms list
174+ platforms. iter ( ) . all ( |p| expected_platforms. contains ( & p. to_string ( ) ) )
175+ } ,
176+ )
177+ } )
178+ . collect :: < Vec < _ > > ( ) ;
179+
180+ if capabilities. is_empty ( ) {
181+ let identifier = format ! ( "{target_name}-capability" ) ;
182+ let capability_path = capabilities_dir. join ( target_name) . with_extension ( "json" ) ;
183+ log:: info!(
184+ "Capability matching platforms {expected_platforms:?} not found, creating {}" ,
185+ capability_path. display( )
186+ ) ;
187+ capabilities. push ( (
188+ TomlOrJson :: Json ( serde_json:: json!( {
189+ "identifier" : identifier,
190+ "platforms" : expected_platforms
191+ } ) ) ,
192+ capability_path,
193+ ) ) ;
194+ }
195+
196+ capabilities
197+ } else {
198+ capabilities_iter. collect :: < Vec < _ > > ( )
199+ } ;
114200
115201 let mut capabilities = if capabilities. len ( ) > 1 {
116202 let selections = prompts:: multiselect (
@@ -132,6 +218,11 @@ pub fn command(options: Options) -> Result<()> {
132218 . as_slice ( ) ,
133219 None ,
134220 ) ?;
221+
222+ if selections. is_empty ( ) {
223+ anyhow:: bail!( "You did not select any capabilities to update" ) ;
224+ }
225+
135226 selections
136227 . into_iter ( )
137228 . map ( |idx| capabilities[ idx] . clone ( ) )
@@ -140,6 +231,10 @@ pub fn command(options: Options) -> Result<()> {
140231 capabilities
141232 } ;
142233
234+ if capabilities. is_empty ( ) {
235+ anyhow:: bail!( "Could not find a capability to update" ) ;
236+ }
237+
143238 for ( capability, path) in & mut capabilities {
144239 capability. insert_permission ( options. identifier . clone ( ) ) ;
145240 std:: fs:: write ( & * path, capability. to_string ( ) ?) ?;
0 commit comments