Each Cask contains a series of stanzas (or “fields”) which *declare* how the software is to be obtained and installed. In a declarative language, the author does not need to worry about **order**. As long as all the needed fields are present, homebrew-cask will figure out what needs to be done at install time.
Exception: `do` blocks such as `postflight` may enclose a block of pure Ruby code. Lines within that block follow a procedural (order-dependent) paradigm.
| `sha256` | no | SHA-256 checksum of the file downloaded from `url`, calculated by the command `shasum -a 256 <file>`. Can be suppressed by using the special value `:no_check`. (see also [Checksum Stanza Details](#checksum-stanza-details))
| `url` | no | URL to the `.dmg`/`.zip`/`.tgz`/`.tbz2` file that contains the application. A [comment](#when-url-and-homepage-hostnames-differ-add-a-comment) should be added if the hostnames in the `url` and `homepage` stanzas differ (see also [URL Stanza Details](#url-stanza-details))
| `app` | yes | relative path to an `.app` that should be linked into the `~/Applications` folder on installation (see also [App Stanza Details](#app-stanza-details))
| `pkg` | yes | relative path to a `.pkg` file containing the distribution (see also [Pkg Stanza Details](#pkg-stanza-details))
| `binary` | yes | relative path to a binary that should be linked into the `/usr/local/bin` folder on installation
| `colorpicker` | yes | relative path to a ColorPicker plugin that should be linked into the `~/Library/ColorPickers` folder on installation
| `font` | yes | relative path to a font that should be linked into the `~/Library/Fonts` folder on installation
| `input_method` | yes | relative path to a input method that should be linked into the `~/Library/Input Methods` folder on installation
| `internet_plugin` | yes | relative path to a service that should be linked into the `~/Library/Internet Plug-Ins` folder on installation
| `prefpane` | yes | relative path to a preference pane that should be linked into the `~/Library/PreferencePanes` folder on installation
| `qlplugin` | yes | relative path to a QuickLook plugin that should be linked into the `~/Library/QuickLook` folder on installation
| `screen_saver` | yes | relative path to a Screen Saver that should be linked into the `~/Library/Screen Savers` folder on installation
| `service` | yes | relative path to a service that should be linked into the `~/Library/Services` folder on installation
| `suite` | yes | relative path to a containing directory that should be linked into the `~/Applications` folder on installation (see also [Suite Stanza Details](#suite-stanza-details))
| `artifact` | yes | relative path to an arbitrary path that should be symlinked on installation. This is only for unusual cases. The `app` stanza is strongly preferred when linking `.app` bundles.
| `installer` | yes | describes an executable which must be run to complete the installation. (see [Installer Stanza Details](#installer-stanza-details))
| `stage_only` | no | `true`. Assert that the Cask contains no activatable artifacts.
| `uninstall` | yes | procedures to uninstall a Cask. Optional unless the `pkg` stanza is used. (see also [Uninstall Stanza Details](#uninstall-stanza-details))
| `zap` | yes | additional procedures for a more complete uninstall, including user files and shared resources. (see also [Zap Stanza Details](#zap-stanza-details))
| `conflicts_with` | yes | a list of conflicts with this Cask (*not yet functional* see also [Conflicts_with Stanza Details](#conflicts_with-stanza-details))
| `caveats` | yes | a string or Ruby block providing the user with Cask-specific information at install time (see also [Caveats Stanza Details](#caveats-stanza-details))
| `container :nested =>` | no | relative path to an inner container that must be extracted before moving on with the installation; this allows us to support dmg inside tar, zip inside dmg, etc.
| `container :type =>` | no | a symbol to override container-type autodetect. may be one of: `:air`, `:bz2`, `:cab`, `:dmg`, `:generic_unar`, `:gzip`, `:otf`, `:pkg`, `:rar`, `:seven_zip`, `:sit`, `:tar`, `:ttf`, `:xar`, `:zip`, `:naked`. (example [parse.rb](https://github.com/caskroom/homebrew-cask/blob/ffdc9a1aa459d80a084ee0d24176409388efe71f/Casks/parse.rb#L12))
The available symbols for OS X versions are: `:cheetah`, `:puma`, `:jaguar`, `:panther`, `:tiger`, `:leopard`, `:snow_leopard`, `:lion`, `:mountain_lion`, `:mavericks`, `:yosemite`, and `:el_capitan`. The corresponding numeric version strings should given as major releases containing a single dot.
Conditionals should be constructed so that the default is the newest OS version or hardware type. When using an `if` statement, test for older versions, and then let the `else` statement hold the latest and greatest. This makes it more likely that the Cask will work without alteration when a new OS is released. Example (from [coconutbattery.rb](../Casks/coconutbattery.rb)):
There are currently some arbitrary limitations on Cask tokens which are in the process of being removed. The Travis bot will catch any errors during the transition.
When `caveats` is a string, it is evaluated at compile time. The following methods are available for interpolation if `caveats` is placed in its customary position at the end of the Cask:
| `caskroom_path` | the containing directory for all staged Casks, typically `/opt/homebrew-cask/Caskroom` (only available with block form)
| `staged_path` | the staged location for this Cask, including version number, *eg*`/opt/homebrew-cask/Caskroom/adium/1.5.10` (only available with block form)
When `caveats` is a Ruby block, evaluation is deferred until install time. Within a block you may refer to the `@cask` instance variable, and invoke any method available on `@cask`.
When a plain URL string is insufficient to fetch a file, additional information may be provided to the `curl`-based downloader, in the form of key/value pairs appended to `url`:
| `:cookies` | a hash of cookies to be set in the download request
| `:referer` | a string holding the URL to set as referrer in the download request
| `:user_agent` | a string holding the user agent to set for the download request. Can also be set to the symbol `:fake`, which will use a generic Browser-like user agent string. we prefer `:fake` when the server does not require a specific user agent.
Examples can be seen in [visit.rb](https://github.com/caskroom/homebrew-cask/blob/cafcd7cf7922022ea607c5811c63d45863c7ed36/Casks/visit.rb#L5) and [vistrails.rb](https://github.com/caskroom/homebrew-cask/blob/cafcd7cf7922022ea607c5811c63d45863c7ed36/Casks/vistrails.rb#L5).
These comments must be added so a user auditing the cask knows the URL is the one provided by the vendor, even though it may look unofficial or suspicious. It is our responsibility as homebrew-cask maintainers to verify both the `url` and `homepage` information when first added (or subsequently modified, apart from versioning). The exception to this rule is a `homepage` of `github.io` with a `url` of `github.com`, since we know this pair of hostnames is connected.
Web browsers may obscure the direct `url` download location for a variety of reasons. Homebrew-cask supplies a script which can read extended file attributes to extract the actual source URL for most files downloaded by a browser on OS X. The script usually emits multiple candidate URLs; you may have to test each of them:
In rare cases, a distribution may not be available over ordinary HTTP/S. Subversion URLs are also supported, and can be specified by appending the following key/value pairs to `url`:
The value of the `appcast` stanza is a string, holding the URL for an appcast which provides information on future updates. Generally, the appcast URL returns Sparkle-compatible XML, though that is not required.
The values for `license` are categories, rather than fully-specified licenses. For example, `:gpl` is a category; we do not distinguish between versions of the GPL. Similarly, `:cc` and `:bsd` comprise many variants. They must always pertain to the license of the software itself, not the vendor’s business model (a free app to access a paid service is still `:gratis`, not `:freemium`).
The `license` stanza is intended as an aid to search/filtering of Casks. For full and complete information, the user must always rely on the vendor’s homepage.
Cask authors should use the most specific license category which is also correct. Generic categories are provided for difficult cases. `:unknown` is also perfectly fine if you are unsure.
Example: [Chromium](http://www.chromium.org/chromium-os/licenses) includes code with multiple licenses, all of which are open source. Chromium licensing is described by the generic category [`:oss`](https://github.com/caskroom/homebrew-cask/blob/54a79f7dcceea9a922a5b608ac99466b9d10a191/Casks/chromium.rb#L7).
| `:vendor` | the full-text official name of the producer of the software: an author or corporate name, as appropriate. As the value is intended as a search target, commonly shared abbreviations such as `Dr.` or `Inc.` should be omitted. (example [google-chrome.rb](../Casks/google-chrome.rb))
where `<parameter>` is one of `:key_id` or `:key_url`, and `<signature>` points to the detached signature of the distribution. Commonly, the signature follows the `url` value. Example: [libreoffice.rb](../Casks/libreoffice.rb).
In the simple case of a string argument to `app`, a symlink is created in the target `~/Applications` directory using the same basename as the source file. For example:
You can rename the target link which appears in your `~/Applications` directory by adding a `:target` key to `app`. Example (from [scala-ide.rb](https://github.com/caskroom/homebrew-cask/blob/84e8df88836a2c11657e09264bd01b96783bb0d1/Casks/scala-ide.rb#L21):
If `:target` has a leading slash, it is interpreted as an absolute path. The containing directory for the absolute path will be created if it does not already exist. Example (from [manopen.rb](https://github.com/caskroom/homebrew-cask/blob/84e8df88836a2c11657e09264bd01b96783bb0d1/Casks/manopen.rb#L12)):
The `:target` key works similarly for most Cask artifacts, such as `app`, `binary`, `colorpicker`, `font`, `input_method`, `prefpane`, `qlplugin`, `service`, `suite`, and `artifact`.
Don’t use `:target` for aesthetic reasons, like removing version numbers (`app "Slack #{version}.app", :target => 'Slack.app'`). With `app`, use it when it makes sense functionally and document your reason cleary in the Cask: was it [for clarity](https://github.com/caskroom/homebrew-cask/blob/6e4eb6ba58ca0d9e6d42a1d78856cc8a35cf5fce/Casks/imagemin.rb#L11); [for consistency](https://github.com/caskroom/homebrew-cask/blob/6e4eb6ba58ca0d9e6d42a1d78856cc8a35cf5fce/Casks/devonthink-pro-office.rb#L14); [to prevent conflicts](https://github.com/caskroom/homebrew-cask/blob/6e4eb6ba58ca0d9e6d42a1d78856cc8a35cf5fce/Casks/flash-player-debugger.rb#L13)? With `binary` you can take some extra liberties to be consistent with other command-line tools, like [changing case](https://github.com/caskroom/homebrew-cask/blob/6e4eb6ba58ca0d9e6d42a1d78856cc8a35cf5fce/Casks/diffmerge.rb#L11) or [removing an extension](https://github.com/caskroom/homebrew-cask/blob/6e4eb6ba58ca0d9e6d42a1d78856cc8a35cf5fce/Casks/filebot.rb#L12).
Some distributions provide a suite of multiple applications, or an application with required data, to be installed together in a subdirectory of `~/Applications`.
`installer :manual` takes a single string value, describing a GUI installer which must be run by the user at a later time. The path may be absolute, or relative to the Cask. Example:
`installer :script` introduces a series of key-value pairs describing a command which will automate completion of the install. The form is similar to `uninstall :script`:
Example use: some distributions are contained in archive formats such as `7z` which are not supported by stock Apple tools. For these cases, a more capable archive reader may be pulled in at install time by declaring a dependency on the Homebrew Formula `unar`:
Only major releases are covered (version numbers containing a single dot). The symbol form is preferred for readability. The following are all valid ways to enumerate the exact OS X release requirements for a Cask:
`depends_on :macos` can also accept a string starting with a comparison operator such as `>=`, followed by an OS X release in the form above. The following are both valid expressions meaning “at least OS X 10.9”:
The value for `depends_on :arch` may be a symbol or an array of symbols, listing the hardware compatibility requirements for a Cask. The requirement is satisfied at install time if any one of multiple `:arch` value matches the user’s hardware.
Several keys are accepted by `conflicts_with`, but none of them are yet enforced by the backend implementation. It is fine to proactively add `conflicts_with` stanzas to Casks in anticipation of future backend support; they are currently just a type of structured comment.
IF YOU CANNOT DESIGN A WORKING `UNINSTALL` STANZA, PLEASE SUBMIT YOUR CASK ANYWAY. The maintainers will help you write an `uninstall` stanza, just ask!
For most Casks, uninstall actions are determined automatically, and an explicit `uninstall` stanza is not needed. However, a Cask which uses the `pkg` stanza will **not** know how to uninstall correctly unless an `uninstall` stanza is given.
The `uninstall` stanza is available for non-`pkg` Casks, and is useful for a few corner cases. However, the documentation below concerns the typical case of using `uninstall` to define procedures for a `pkg`.
Since `pkg` installers can do arbitrary things, different techniques are needed to uninstall in each case. You may need to specify one, or several, of the following key/value pairs as arguments to `uninstall`.
*`:delete` (string or array) - single-quoted, absolute paths of files or directory trees to remove. `:delete` should only be used as a last resort. `:pkgutil` is strongly preferred
For assistance filling in the right values for `uninstall` keys, there are several helper scripts found under `developer/bin` in the homebrew-cask repository. Each of these scripts responds to the `-help` option with additional documentation.
The easiest way to work out an `uninstall` stanza is on a system where the `pkg` is currently installed and operational. To operate on an uninstalled `pkg` file, see [Working With a pkg File Manually](#working-with-a-pkg-file-manually), below.
`:pkgutil` also accepts a regular expression match against multiple package IDs. The regular expressions are somewhat nonstandard. To test a `:pkgutil` regular expression against currently-installed packages, use the command:
Bundle IDs for `:signal` targets may be obtained as for `:quit`. The value for `:signal` is an array-of-arrays, with each cell containing two elements: the desired Unix signal followed by the corresponding bundle ID.
The elements of the `:signal` array are applied in order, only if there is an existing process associated the bundle ID, and stopping when that process terminates. A bundle ID may be repeated to send more than one signal to the same process.
Unlike `:quit` directives, Unix signals originate from the current user, not from the superuser. This is construed as a safety feature, since the superuser is capable of bringing down the system via signals. However, this inconsistency may also be considered a bug, and should be addressed in some fashion in a future version.
*stub* - currently a synonym for `:delete`. In the future this will cause files to be moved to the Trash. It is best not to use this stub until it gains the proper functionality.
1. Unpack `/path/to/my.pkg` (replace with your package name) with `pkgutil --expand /path/to/my.pkg /tmp/expanded.unpkg`.
2. The unpacked package is a folder. Bundle ids are contained within files named `PackageInfo`. These files can be found with the command `find /tmp/expanded.unpkg -name PackageInfo`.
3.`PackageInfo` files are XML files, and bundle ids are found within the `identifier` attributes of `<pkg-info>` tags that look like `<pkg-info ... identifier="com.oracle.jdk7u51" ... >`, where extraneous attributes have been snipped out and replaced with ellipses.
4. Kexts inside packages are also described in `PackageInfo` files. If any kernel extensions are present, the command `find /tmp/expanded.unpkg -name PackageInfo -print0 | xargs -0 grep -i kext` should return a `<bundle id>` tag with a `path` attribute that contains a `.kext` extension, for example `<bundle id="com.wavtap.driver.WavTap" ... path="./WavTap.kext" ... />`.
5. Once bundle ids have been identified, the unpacked package directory can be deleted.
The Ruby blocks defined by `preflight`, `postflight`, `uninstall_preflight`, and `uninstall_postflight` are not evaluated until install time or uninstall time. Within a block, you may refer to the `@cask` instance variable, and invoke any method available on `@cask`.
| `plist_set(key, value)` | `preflight`, `postflight`, `uninstall_preflight` | set a value in the `Info.plist` file for the app bundle. Example: [`rubymine.rb`](https://github.com/caskroom/homebrew-cask/blob/c5dbc58b7c1b6290b611677882b205d702b29190/Casks/rubymine.rb#L12)
| `set_ownership(paths)` | `preflight`, `postflight`, `uninstall_preflight` | set user and group ownership of `paths`. Example: [`unifi-controller.rb`](https://github.com/caskroom/homebrew-cask/blob/8a452a41707af6a661049da6254571090fac5418/Casks/unifi-controller.rb#L13)
| `set_permissions(paths, permissions_str)` | `preflight`, `postflight`, `uninstall_preflight` | set permissions in `paths` to `permissions_str` Example: [`docker-machine.rb`](https://github.com/caskroom/homebrew-cask/blob/8a452a41707af6a661049da6254571090fac5418/Casks/docker-machine.rb#L16)
| `suppress_move_to_applications` | `postflight` | suppress a dialog asking the user to move the app to the `/Applications` folder. Example: [`github.rb`](https://github.com/caskroom/homebrew-cask/blob/c5dbc58b7c1b6290b611677882b205d702b29190/Casks/github.rb#L13).
`plist_set` currently has the limitation that it only operates on the bundle indicated by the first `app` stanza (and the Cask must contain an `app` stanza).
`set_ownership(paths)` defaults user ownership to the current user and group ownership to `staff`. These can be changed by passing in extra options: `set_ownership(paths, user: 'user', group: 'group')`.
`suppress_move_to_applications` optionally accepts a `:key` parameter for apps which use a nonstandard `defaults` key. Example: [`alfred.rb`](https://github.com/caskroom/homebrew-cask/blob/c5dbc58b7c1b6290b611677882b205d702b29190/Casks/alfred.rb).
The `zap` stanza describes a more complete uninstallation of resources associated with a Cask. The `zap` procedures will never be performed by default, but only if the user invokes the `zap` verb:
* Preference files and caches stored within the user’s `~/Library` directory.
* Shared resources such as application updaters. Since shared resources may be removed, other applications may be affected by `brew cask zap`. Understanding that is the responsibility of the end user.
In the exceptional case that the Cask DSL is insufficient, it is possible to define arbitrary Ruby variables and methods inside the Cask by creating a `Utils` namespace. Example:
This should be used sparingly: any method which is needed by two or more Casks should instead be rolled into the core. Care must also be taken that such methods be very efficient.