55//! ACL items that are only useful inside of build script/codegen context.
66
77use std:: {
8- collections:: { BTreeMap , HashMap , HashSet } ,
8+ collections:: { BTreeMap , HashMap } ,
99 env, fs,
1010 path:: { Path , PathBuf } ,
1111} ;
@@ -205,15 +205,15 @@ pub fn parse_capabilities(pattern: &str) -> Result<BTreeMap<String, Capability>,
205205 let mut capabilities_map = BTreeMap :: new ( ) ;
206206
207207 for path in glob:: glob ( pattern) ?
208- . flatten ( )
209- // filter extension
208+ . flatten ( ) // filter extension
210209 . filter ( |p| {
211210 p. extension ( )
212211 . and_then ( |e| e. to_str ( ) )
213212 . map ( |e| CAPABILITY_FILE_EXTENSIONS . contains ( & e) )
214213 . unwrap_or_default ( )
215214 } )
216215 // filter schema files
216+ // TODO: remove this before stable
217217 . filter ( |p| p. parent ( ) . unwrap ( ) . file_name ( ) . unwrap ( ) != CAPABILITIES_SCHEMA_FOLDER_NAME )
218218 {
219219 match CapabilityFile :: load ( & path) ? {
@@ -244,15 +244,13 @@ pub fn parse_capabilities(pattern: &str) -> Result<BTreeMap<String, Capability>,
244244}
245245
246246/// Permissions that are generated from commands using [`autogenerate_command_permissions`].
247- /// Autogenerated permission sets (allow + deny)
248247pub struct AutogeneratedPermissions {
249- /// List of automatically allowed commands
250- pub allowed : Vec < String > ,
251- /// List of automatically denied commands
252- pub denied : Vec < String > ,
248+ /// The allow permissions generated from commands.
249+ pub allowed : Vec < String > ,
250+ /// The deny permissions generated from commands.
251+ pub denied : Vec < String > ,
253252}
254253
255-
256254/// Autogenerate permission files for a list of commands.
257255pub fn autogenerate_command_permissions (
258256 path : & Path ,
@@ -272,7 +270,6 @@ pub fn autogenerate_command_permissions(
272270 . collect :: < PathBuf > ( )
273271 . join ( PERMISSION_SCHEMAS_FOLDER_NAME )
274272 . join ( PERMISSION_SCHEMA_FILE_NAME ) ;
275-
276273 format ! (
277274 "\n \" $schema\" = \" {}\" \n " ,
278275 dunce:: simplified( & schema_path)
@@ -289,15 +286,15 @@ pub fn autogenerate_command_permissions(
289286 denied : Vec :: new ( ) ,
290287 } ;
291288
292- // -------------------------------------------------
293- // Generate permission files
294- // -------------------------------------------------
289+ let mut generated_files = Vec :: new ( ) ;
290+
295291 for command in commands {
296292 let slugified_command = command. replace ( '_' , "-" ) ;
297293
298294 let toml = format ! (
299295 r###"{license_header}# Automatically generated - DO NOT EDIT!
300296{schema_entry}
297+
301298[[permission]]
302299identifier = "allow-{slugified_command}"
303300description = "Enables the {command} command without any pre-configured scope."
@@ -314,6 +311,8 @@ commands.deny = ["{command}"]
314311 write_if_changed ( & out_path, toml)
315312 . unwrap_or_else ( |_| panic ! ( "unable to autogenerate {out_path:?}" ) ) ;
316313
314+ generated_files. push ( out_path) ;
315+
317316 autogenerated
318317 . allowed
319318 . push ( format ! ( "allow-{slugified_command}" ) ) ;
@@ -322,20 +321,18 @@ commands.deny = ["{command}"]
322321 . push ( format ! ( "deny-{slugified_command}" ) ) ;
323322 }
324323
325- // -------------------------------------------------
326- // 🔥 CLEANUP BLOCK (final version)
327- // -------------------------------------------------
328- let expected: HashSet < String > = commands. iter ( ) . map ( |cmd| format ! ( "{}.toml" , cmd) ) . collect ( ) ;
324+ use std:: collections:: HashSet ;
325+
326+ let expected_files: HashSet < PathBuf > = generated_files. into_iter ( ) . collect ( ) ;
329327
330328 if let Ok ( entries) = fs:: read_dir ( path) {
331329 for entry in entries. flatten ( ) {
332- if entry. file_type ( ) . map ( |ft| ft. is_file ( ) ) . unwrap_or ( false ) {
333- let name = entry. file_name ( ) . to_string_lossy ( ) . to_string ( ) ;
330+ if let Ok ( file_type) = entry. file_type ( ) {
331+ if file_type. is_file ( ) {
332+ let file_path = entry. path ( ) ;
334333
335- if !expected. contains ( & name) {
336- let p = entry. path ( ) ;
337- if let Err ( e) = fs:: remove_file ( & p) {
338- eprintln ! ( "[cleanup] Failed to remove outdated file {:?}: {}" , p, e) ;
334+ if !expected_files. contains ( & file_path) {
335+ let _ = fs:: remove_file ( & file_path) ;
339336 }
340337 }
341338 }
@@ -408,6 +405,10 @@ pub fn generate_docs(
408405 Ok ( ( ) )
409406}
410407
408+ // TODO: We have way too many duplicated code around getting the config files, e.g.
409+ // - crates/tauri-codegen/src/lib.rs (`get_config`)
410+ // - crates/tauri-build/src/lib.rs (`try_build`)
411+ // - crates/tauri-cli/src/helpers/config.rs (`get_internal`)
411412/// Generate allowed commands file for the `generate_handler` macro to remove never allowed commands
412413pub fn generate_allowed_commands (
413414 out_dir : & Path ,
@@ -428,9 +429,12 @@ pub fn generate_allowed_commands(
428429 return Ok ( ( ) ) ;
429430 }
430431
432+ // It's safe to `unwrap` here since we have checked if the result is ok above
431433 let config_directory = PathBuf :: from ( remove_unused_commands_env_var. unwrap ( ) ) ;
432434 let capabilities_path = config_directory. join ( "capabilities" ) ;
433-
435+ // Cargo re-builds if the variable points to an empty path,
436+ // so we check for exists here
437+ // see https://github.com/rust-lang/cargo/issues/4213
434438 if capabilities_path. exists ( ) {
435439 println ! ( "cargo:rerun-if-changed={}" , capabilities_path. display( ) ) ;
436440 }
@@ -450,11 +454,13 @@ pub fn generate_allowed_commands(
450454
451455 println ! ( "cargo:rerun-if-env-changed=TAURI_CONFIG" ) ;
452456
457+ // Set working directory to where `tauri.config.json` is, so that relative paths in it are parsed correctly.
453458 let old_cwd = std:: env:: current_dir ( ) ?;
454- std:: env:: set_current_dir ( & config_directory) ?;
459+ std:: env:: set_current_dir ( config_directory) ?;
455460
456461 let config: Config = serde_json:: from_value ( config) ?;
457462
463+ // Reset working directory.
458464 std:: env:: set_current_dir ( old_cwd) ?;
459465
460466 let acl: BTreeMap < String , crate :: acl:: manifest:: Manifest > = permissions_map
@@ -477,18 +483,15 @@ pub fn generate_allowed_commands(
477483 glob:: Pattern :: escape( & capabilities_path. to_string_lossy( ) )
478484 ) ) ?
479485 } ;
480-
481486 let capabilities = crate :: acl:: get_capabilities ( & config, capabilities_from_files, None ) ?;
482487
483488 let permission_entries = capabilities
484489 . into_iter ( )
485490 . flat_map ( |( _, capabilities) | capabilities. permissions ) ;
486-
487491 let mut allowed_commands = AllowedCommands {
488492 has_app_acl : has_app_manifest ( & acl) ,
489493 ..Default :: default ( )
490494 } ;
491-
492495 for permission_entry in permission_entries {
493496 let Ok ( permissions) =
494497 crate :: acl:: resolved:: get_permissions ( permission_entry. identifier ( ) , & acl)
0 commit comments