I’ve been working on a script library to make creating command-line tools with AppleScript a little bit easier for myself, perhaps someone here will also find it helpful. The library is called Argonaut and can be found on GitHub alongside documentation and examples. I’ve included a scripting dictionary for ease of use.
The commands supported are:
add argument - Add an argument to parse for and configure various aspects of it
argument names - Gets the list of argument names
check arguments - Validate all arguments
check for argument - Validate the presence and value type of an individual argument
filter arguments - Filter the validated list of arguments based on state, type, requirement setting, and/or value.
handle arguments - Validate arguments, then run handlers conditionally, e.g. when all arguments are valid or when any argument is missing
initialize argument parser - Prepare the parser, set up help text, and apply custom settings
list arguments - Gets the active configuration of all arguments
And here’s a simple example:
use script "Argonaut" version "1.0"
use scripting additions
on run argv
add argument "url" type ArgURL flag "u" help text "A URL to open"
add argument "app" flag "a" dependencies {"url"} help text "The app to open the URL in. Must be a valid application on the system. The 'url' argument must also be provided." validator appExists without required
set config to {command name:"URL Opener", author:"Stephen Kaplan", short description:"Opens a URL in the specified application, or the default browser if no application is specified."}
initialize argument parser configuration config
handle arguments argv when no errors openURL
set validArgs to filter arguments by state valid
log "Amount valid: " & (count of validArgs)
set excludedArgs to filter arguments by state excluded by type ArgAny
log "Amount excluded: " & (count of excludedArgs)
set invalidArgs to filter arguments by state invalid
log "Amount invalid: " & (count of invalidArgs)
return argument names validArgs
end run
on appExists(argName, theValue)
set allApps to do shell script "mdfind kMDItemContentTypeTree=com.apple.application-bundle"
if theValue & ".app" is in allApps then
return {validity:valid, value:application theValue}
end if
return {validity:invalid, value:missing value}
end appExists
on openURL(argConfigs, argDict)
if argDict's |app| is "" then
open location (argDict's |url|'s path)
else
try
tell (argDict's |app|)
open location (argDict's |url|'s path)
activate
end tell
on error
log "Couldn't open URL in specified application."
end try
end if
end openURL
This is my first script library, so I’m open to feedback on features as well as on the code itself!
Wow, this is a pretty impressive Script Library. What I see looks well factored, and complete with Scripting Definition!
What did you use to write the .sdef? I’ve been using Sdef Editor.app, but it’s getting old and I haven’t seen anything newer.
The biggest issue I’ve had with Script Libraries is Script Debugger and Script Editor continuously crashing. Have you experienced similar issues while developing this library?
I just tried your example script above, and it gives an error when run in Script Debugger:
«script» doesn’t understand the “handle arguments” message.
-1708
When run successively with osascript without arguments, I got different errors on each run, which is very strange. Perhaps my AppleScript environment is borked (macOS 10.14)?
$ osascript Untitled.scpt
Error: Missing required argument 'url'. Call the script again with the '--help' flag to see extended help, or use '--url help' to get help specific to this argument.
Amount valid: 0
Amount excluded: 1
Amount invalid: 0
osascript: couldn't save changes to script Untitled.scpt: errOSASystemError (-1750).
$ osascript Untitled.scpt
Error: Missing required argument 'url'. Call the script again with the '--help' flag to see extended help, or use '--url help' to get help specific to this argument.
Amount valid: 0
Amount excluded: 1
Amount invalid: 0
Segmentation fault: 11
$ osascript Untitled.scpt
Error: Missing required argument 'url'. Call the script again with the '--help' flag to see extended help, or use '--url help' to get help specific to this argument.
Amount valid: 0
Amount excluded: 1
Amount invalid: 0
$ osascript Untitled.scpt
Error: Missing required argument 'url'. Call the script again with the '--help' flag to see extended help, or use '--url help' to get help specific to this argument.
Untitled.scpt: execution error: NSMutableDictionary doesn’t understand the “alloc” message. (-1708)
I was able to run it with -u and -u -a, which worked as expected.
See here: Sdef Editor. Not new, but recompiled so that it also runs with current macOS versions. Not much has changed in the AppleScript definition in recent years.
PS: I have no problems with the Script Library under Ventura 13.5.2. The samples run perfectly.
Thanks for checking the library out! I wrote the sdef from scratch, actually, just editing XML in Xcode. Looked at the dictionary for a lot of apps for reference. Didn’t know Sdef Editor.app existed!
I did run into a few crashes during development, but running from the command line via osascript helped alleviate some of the annoyance (and provided generally more helpful error messages).
The example script doesn’t do any checking to make sure that arguments were passed, so the error you got when running it via script debugger makes sense. I guess the library itself could do that check, but right now it doesn’t.
For the other errors: AppleScript seems to have trouble with script-level properties in libraries. Not sure exactly why those errors are occurring, nor why they change, but I’d guess it’s to do with the properties getting re-saved on each run (and sometimes failing at that). I will look into it and see if I can fix it or at least raise a more insightful error.