Stephen's Space


Argonaut

Argonaut is a script library for parsing command-line arguments to AppleScript/ASObjC scripts. The library provides handlers for specifying arguments and their requirements, parsing arguments at runtime, performing type checking, and running callbacks when specified conditions are met. Argonaut is a high-level framework for argument specification and handling that abstracts away many of the finer implementation details so that you can focus on creating useful command-line scripts.

Installation

Download and unzip Argonaut.zip from https://github.com/SKaplanOfficial/Argonaut/releases/latest. Then, move or copy Argonaut.scptd into your ~/Library/Script Libraries directory. You'll then be able to use Argonaut in future scripts, and you can view the scripting dictionary in Script Editor or Script Debugger just as you would any other.

Usage

To begin, include the library in a script using the statement use script "Argonaut" version "1.0"

This will allow you to use terminology from Argonaut in the rest of the script.

The overall process in working with Argonaut is summarized as:

  1. Add named arguments using the add argument command, specifying as much or as little additional information as you need.
  2. Run the initialize argument parser command, optionally providing a parser configuration record to customize how the parser behaves and add additional information to your script's help text.
  3. Define handlers to run when specific conditions are met, e.g. when all arguments are valid or when no arguments yield errors, and connect them to the parser using the handle arguments command.
  4. Run the script from the command-line using osascript, providing arguments that fit your specifications.

Adding Arguments

Every argument has a unique name associated with it; all other properties are optional. Properties are interwoven such that using different values for the type, for example, influences how validator handlers are applied, and most properties have some impact on how the help text displays.

When running a script from the command-line, arguments are primarily specified by either their full flag (--name) or a shorthand flag (-x) if you define one. Shorthand flags are not automatically derived from the name as you might have multiple arguments beginning with the same letter. Thus, you can specify a custom shorthand flag using add argument "myArg" flag "x", which will register -x as a valid alternate indicator. The value you want to pass in for myArg would come after -x, e.g.: osascript example.scpt -x "value".

By default, arguments accept a single (non-list) value of any type. To enforce a specific data type on the argument's value, specify a type using add argument "myArg" type [type]. The type can be a standard AppleScript class, such as integer or URL, or it can be one of the Argonaut-specific types such as ArgInteger, ArgPath, or ArgURLList. Singular value types will look for a single value immediately following a flag, while list types will match every value up until the next flag occurs or the end of the line.

When users invoke the top-level --help or -h flag on the script, in addition to displaying the global help text, the help text for each argument will be displayed. Users can get more detail about specific arguments by passing "help" as the value, regardless of the argument's data type, which will print out the argument's details.

You can specify dependencies for an argument to require that other arguments are also provided whenever the argument is used. These can be specified as either a list of argument names or a list of argument records. Failing to supply each dependency argument will yield an error.

Validation Handlers (Custom Validators)

Argonaut automatically handles value type validation for each of the built-in argument types, but, if you need to verify other kinds of inputs, you can create a custom handler and provide it as the validator parameter when creating a new argument. The handler must accept two parameters: 1) the name of the argument and 2) the string value. The handler must return a record with fields for the validity of the argument and the augmented value. The validity must be one of the argument state constants.

As an example, consider a script that displays an standard alert given a title, message, and type provided as arguments. Any arbitrary string of text will suffice for the title and message, so both can use the type any or ArgAny (the default). The alert type, however, has to map to one of the AppleScript alert type constants (critical/informational/warning). We can use a custom validation handler to address this as follows:


  use script "Argonaut" version "1.0"
  use scripting additions

  on isAlertType(theArg, value)
    set isValid to invalid
    set augmentedValue to missing value
    
    if value is "critical" then
      set isValid to valid
      set augmentedValue to critical
    else if value is "informational" then
      set isValid to valid
      set augmentedValue to informational
    else if value is "warning" then
      set isValid to valid
      set augmentedValue to warning
    end if
    return {validity:isValid, value:augmentedValue}
  end isAlertType

  on run argv
    add argument "title" help text "The title text of the alert." with required
    add argument "message" help text "The message text of the alert." without required
    add argument "type" help text "The alert type." validator isAlertType details "Must be one of: 'critical', 'informational', or 'warning'." without required
    initialize argument parser
    handle arguments argv
  end run
        

In place of a handler, you can instead supply a script object which defines a validate(theArg, value) handler within it. The advantage to this is that you'll be able to access property local to your script. The script above is equivalent to:


  use script "Argonaut" version "1.0"
  use scripting additions

  property importantProperty : "important data"

  script AlertTypeValidator
    on validate(theArg, value)
      log importantProperty
      ...
    end validate
  end script

  on run argv
    ...
    add argument "type" help text "The alert type." validator AlertTypeValidator details "Must be one of: 'critical', 'informational', or 'warning'." without required
    ...
  end run
        

Action Handlers

Similar to validators, you can also supply a handler or script object to specify an action to run when parsing has completed for any given argument. The action runs regardless of whether the value is valid and regardless of whether the argument exists in the input; you will have to handle these conditions in your implementation however you see fit. Both the handler and script object variations must support three parameters: the argument itself, its status, and its value (correctly typed). In the script object, the handler must be named runAction. The example below showcases both variations.


  use script "Argonaut" version "1.0"

  property importantProperty : false

  script ActionRunner
    on runAction(theArg, status, value)
      log class of value
      log importantProperty -- Will work
    end runAction
  end script

  on runAction(theArg, status, value)
    log theArg
    log importantProperty -- Won't work property
  end runAction

  on run argv
    add argument "arg1" type ArgInteger action ActionRunner without required
    add argument "arg2" type ArgFlag action runAction without required
    initialize argument parser
    handle arguments argv
  end run
        

Handling Parsed Values

When you use the handle arguments command, you can supply handlers for several conditions at once. Each handler will be called with the list of arguments passing the condition alongside the summary record of all arguments and values. The value returned by the last handler run (the last one passed to the command) will be returned as the overall result of the command.

If you don't want to use the handle arguments command, you can call check arguments directly and then access arguments and their values with the list arguments command. You will have to filter arguments manually or using filter arguments.

Filtering Arguments

If you find yourself needing to filter arguments beyond the basics handled by handle arguments, you can use filter arguments. This command accepts several parameters for specifying the criteria to filter arguments by, and it accepts a using custom filter parameter for even more granular control.

All of the following are valid calls to filter arguments:

  filter arguments by state valid -- Gets all arguments passed to the script that have a valid value
  filter arguments by type ArgList -- Gets all arguments accepting any kind of list as a value
  filter arguments (list arguments) by type {ArgPath, ArgFlag} -- Gets arguments that are either flags or accept a path value
  filter arguments with required -- Gets all required arguments
  filter arguments without required -- Gets all optional arguments
  filter arguments with has value -- Gets all arguments that have some value specified (even if it is invalid)
  filter arguments using custom filter passesTest -- Gets arguments for which the passesTest handler returns true
  filter arguments using custom filter MyCustomFilter -- Gets arguments for which the passesTest handler of the MyCustomFilter script object returns true
  filter arguments by state valid by type ArgURL -- Gets all arguments whose value is a valid URL
  filter arguments by state excluded with value -- Gets all arguments that aren't directly specified but have a default value

Other Notes


Top-Level Handlers

Handler Parameters Description
add argument
  • type (text or class, optional, defaults to ArgAny)
  • accepted values (list of any, optional)
  • default value (any, optional)
  • flag (text, optional)
  • help text (text, optional)
  • details (text, optional)
  • validator (handler or script, optional)
  • action (handler or script, optional)
  • required (boolean, optional, defaults to true)
  • dependencies (list of text or record, optional)
  • conflicts (list of text or record, optional)
Adds an argument to parse for and configures various aspects of it.
argument names
  • direct parameter (list of record, optional)
Gets the list of argument names.
check arguments
  • direct parameter (list of text)
Validates all arguments. The direct parameter is the list of argument strings to assess.
check for argument
  • direct parameter (record)
  • in (list of text)
  • at index (number, optional, defaults to -1)
Validates the presence and value type of an individual argument. The direct parameter is the argument record to assess. The in parameter is the list of argument strings to assess. The at index parameter is the index of the argument in the list to assess.
filter arguments
  • direct parameter (record, optional)
  • by state (argument state, optional)
  • by type (text or argument type, optional)
  • required (boolean, optional)
  • has value (any, optional)
  • using custom filter (handler or script)
Filters the validated list of arguments based on state, type, requirement setting, and/or value.
handle arguments
  • direct parameter (list of text)
  • when no errors (handler or script, optional)
  • when all valid (handler or script, optional)
  • when all invalid (handler or script, optional)
  • when all excluded (handler or script, optional)
  • when all missing (handler or script, optional)
  • when any valid (handler or script, optional)
  • when any invalid (handler or script, optional)
  • when any excluded (handler or script, optional)
  • when any missing (handler or script, optional)
Runs handlers conditionally, e.g. when all arguments are valid or when any argument is missing.
initialize argument parser
  • configuration (parser configuration)
Prepares the parser, sets up help text, and applies custom settings.
list arguments None Gets the active configuration of all arguments.

Record Types

Parser Configuration

Configuration settings for the argument parser.

Instance Handlers
Handler Description
disconnect() Disconnects from the current WiFi network.
disable() Disables the WiFi interface.
enable() Enables the WiFi interface.
getMACAddress() Gets the MAC address of the WiFi interface. Returns a text string.
getRSSI() Gets the current aggregate RSSI measurement for the WiFi interface.
getSSID() Gets the SSID of the current WiFi network.
connectToNetwork:networkName usingPassword:thePassword Attempts to connect to the network with the given name, using the provided password. Both parameters must be text strings. Returns true if the connection was successful, false otherwise.
getAvailableNetworks() Scans for available WiFi networks and returns the list of network SSIDs.

WLWebsite

Wrapper object around website URLs and data providing access to complex operations.

Instance Handlers
Handler Description
ping over numAttempts Pings the site's host the specified number of times, returning the average. numAttempts must be an integer number, and it defaults to 1. Returns the average ping time in milliseconds as a number.
save in filePath as fileType Saves the website as a text file, HTML file, PDF, PNG, or JPG. filePath must be a valid path as a text string, and fileType must be one of PNG, JPG, HTML, PDF, or TXT. Returns true if the website was saved successfully, false otherwise.
open Opens the website in the default browser.
Instance Properties
Property Type Description
title text The title of the website.
description text A brief description of the website's content.
URL text The URL of the website.
HTML text The raw HTML of the website.
visibleText text The visible text of the website.
favicon NSImage The favicon of the website.
host text The host (i.e. base domain) of the website.
scheme text The URL scheme of the URL.
pathString text The path component of the URL.
query text The query component of the URL.
queryItems record of text The query component of the URL.
port number The port component of the URL.

WLWebScraper

Class for scraping the contents of a website.

Instance Handlers
Handler Description
itemsWithTypes:theTypes forKeyPath:theKeyPath Extracts items of the specified type from the website.
extractLinks() Extracts all links from the website. Returns a list of text strings.
extractPhoneNumbers() Extracts all phone numbers from the website. Returns a list of text strings.
extractTransitInfo() Extracts all transit information from the website. Returns a list of text strings.
extractDates() Extracts all dates from the website. Returns a list of text strings.
extractAddresses() Extracts all addresses from the website. Returns a list of text strings.
Instance Properties
Property Type Description
target text The target URL of the website.

Constants

Name Value Description
PNG "PNG" The PNG file type.
JPG "JPG" The JPG file type.
HTML "HTML" The HTML file type.
PDF "PDF" The PDF file type.
TXT "TXT" The TXT file type.