What about hidden files and folders?
The answers provided here and here in this thread, consider any folder which contains only hidden1 files and/or hidden folders to be empty too - resulting in them being deleted, which may lead to the loss of important data.
A Safer Solution:
Using the following solution an empty folder is considered to be empty, only if it does not contain a file(s) and/or non-empty folder(s) - whether they're visible or hidden. However, the exception to this rule is for any folder containing only a hidden .DS_Store file - they will be considered empty, and therefore deleted too.
This solution utilizes the Bash find command and executes it via AppleScripts do shell script command.
tell application "Finder"
set packageFolder to choose folder with prompt "Please choose your logo package folder"
set posixPath to quoted form of POSIX path of packageFolder
do shell script "find " & posixPath & " -name '.DS_Store' -type f -delete && find " & posixPath & " -empty -type d -delete"
end tell
Explanation:
Essentially, this AppleScript executes the following Bash commands:
find /path/to/directory/ -name '.DS_Store' -type f -delete
find /path/to/directory/ -empty -type d -delete
Let's breakdown the parts of those two commands for a better understanding of what's happening:
The first command:
find - Search a folder hierarchy for file and folder name(s) which meet a given criteria.
path/to/directory/ - This (contrived) path points to the directory where the search should begin from. This will be replaced with a real path, i.e. the path to whichever folder is chosen and assigned to the packageFolder variable via the choose folder command.
We provide that path (as a POSIX path) to the do shell script command via the part which reads:
set posixPath to quoted form of POSIX path of packageFolder
The quoted form part ensures the folder path, (i.e. the one assigned to the posixPath variable), is provided to do shell script avoiding further interpretation by the shell - it essentially ensures the path to the chosen folder, whose name may include spaces, is handled correctly.
-name - The name of the file to search for, i.e. .DS_Store.
-type f - This option specifies that we only want to include a regular file.
-delete - This option deletes all files which match the previously specified criteria, i.e. files named .DS_Store.
The second command:
find - as per the first command.
path/to/directory/ - as per the first command.
-empty - This option specifies that we want to include either a regular file or a directory only if it is empty.
-type d - This option specifies that we only want to include directories.
-delete - as per the first command., however this time we delete empty folders only.
Example Directory (Before and After).
Given a chosen source directory tree like this:
.
├── a
│ ├── .hidden-dir-a
│ │ └── foo.txt
│ └── .hidden-dir-b
├── b
│ └── bb
│ ├── .DS_Store
│ └── bbb
├── c
│ └── .hidden.txt
└── d
├── dd
│ └── ddd
└── quux.txt
The resultant directory tree (i.e. after running the AppleScript) will be:
.
├── a
│ └── .hidden-dir-a
│ └── foo.txt
├── c
│ └── .hidden.txt
└── d
└── quux.txt
Refactor:
The current AppleScript (above) assumes that you're using the path which is assigned to the packageFolder variable elsewhere in your script, hence it hasn't been changed. Consequently, it introduces the line which reads;
set posixPath to quoted form of POSIX path of packageFolder
to obtain a POSIX path equivalent to the chosen folder path.
However, If the packageFolder variable is not used elsewhere, you could refactor the script to the following instead:
tell application "Finder"
set packageFolder to quoted form of (POSIX path of (choose folder with prompt "Please choose your logo package folder"))
do shell script "find " & packageFolder & " -name '.DS_Store' -type f -delete && find " & packageFolder & " -empty -type d -delete"
end tell
1 Hidden files and folders on MacOS are those whose name begins with a dot (.). For instance .gitignore