Library for parsing command-line arguments

Hi all,

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!

Argonaut_1.0.0.zip (149.4 KB)

4 Likes

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.

@HelloImSteven: Great Job!

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.