If you’d like to hack on the Ruby code that drives this project, please join us, we’d love to have you!
Homebrew-cask is an attempt to make a Linux-style package manager for precompiled OS X software. Homebrew-cask is not yet as featureful as apt
or yum
, but we are trying to be as close as we can get to those tools from the user’s point of view.
We manage installed files via the “symlink farm” method, like GNU Stow and Homebrew. Similarly, we try to avoid sudo
where possible.
Homebrew-cask is designed to work like a traditional Unix tool:
- All functionality should be accessible from the CLI. The user should be freed (freed!) from interacting with a GUI.
- Homebrew-cask should itself be scriptable.
Homebrew-cask is still young, and should be considered in alpha.
We have good support for a variety of artifacts: apps, pkgs, binaries, plugins, and fonts. Homebrew-cask can install and uninstall any of those. However, these commands don’t work well with multiple versions, and most importantly, we currently can’t upgrade
.
Since upgrading is a core feature of every package manager, the implementation of an upgrade
verb is our top priority. For upgrade
to work reliably, we must:
- Maintain unequivocal version information from a variety of sources,
- Track version-specific uninstallation,
- Play nice with self-updating software.
These and more requirements are tracked in our upgrade
roadmap. If you’d like to contribute to upgrade
, that’s an excellent place to start.
Homebrew-cask is independent of Homebrew as a project.
The Homebrew-cask CLI is implemented as a Homebrew subcommand, so we try to match semantics wherever possible. That means that similar functionality should have similar flags and parameters.
However, very little backend code is shared between the two projects. The Homebrew codebase is based on how Homebrew Formulae work, and our Casks are very much unlike Formulae.
Because our backend needs are so different, we are discussing whether we should completely separate our codebase from Homebrew’s (see #5080).
Homebrew Formulae deal with many different build processes, and often include arbitrary Ruby code.
Casks, by contrast, only need to support the few installation methods used by apps, pkg installers, and so on, making them suitable for a declarative DSL.
We encourage Cask authors to use the DSL as much as possible, since that makes things easier for everyone: from maintainers who review pull requests, to first-time contributors, to people who are unfamiliar with Ruby but would like to help.
For software with unusual needs that are not covered by the DSL, we generally accept Casks containing small hacks or arbitrary code. If the hack becomes common enough, we extend the DSL with a simple shorthand that offers the same (or better) functionality.
Cask authors often work directly within the Homebrew directory under /usr/local
. For coding, that is usually not sufficient.
We recommend the following:
-
Fork our repo: https://github.com/caskroom/homebrew-cask/fork
-
Clone a private copy of the repo:
git clone https://github.com/<username>/homebrew-cask.git
- Add the official repo as the
upstream
remote:
cd homebrew-cask
git remote add upstream https://github.com/caskroom/homebrew-cask.git
- Now you have two copies of the homebrew-cask codebase on disk: the released version in
/usr/local/Library/Taps/caskroom/homebrew-cask
, and a development version in your private repo. To symlink theCasks
andrubylib
folders from/usr/local/...
into your private repo, run the following script:
/<path>/<to>/<private>/<repo>/developer/bin/develop_brew_cask
Now you can hack on your private repo, and use the brew cask
CLI like normal — it will interact with your latest code.
- Important: while in development mode, you can’t safely run Homebrew’s
brew update
command. To switch back to production mode, run:
/<path>/<to>/<private>/<repo>/developer/bin/production_brew_cask
You can force a specific version of the Ruby interpreter, and/or an alternate version of the brew-cask
subcommand, by invoking brew cask
with fully-qualified paths, like this:
$ /System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby /usr/local/Library/Taps/caskroom/homebrew-cask/lib/brew-cask-cmd.rb help
If you are developing a subcommand, you can force brew cask
to dispatch a specific file by giving a fully-qualified path to the file containing the subcommand, like this:
$ brew cask /usr/local/Cellar/brew-cask/0.37.0/rubylib/hbc/cli/info.rb google-chrome
This form can also be combined with a specific Ruby interpreter as above.
The environment variable $MACOS_RELEASE
can be overridden at the command line for test purposes:
$ MACOS_RELEASE=10.9 brew cask info <cask>
The environment variable $MACOS_RELEASE_WITH_PATCHLEVEL
is also available, though not consulted directly. Use $MACOS_RELEASE
for testing.
Homebrew-cask requires a Ruby interpreter version 2.0 or above. This is the default system Ruby on Mavericks (10.9) and later.
See the relevant section in CONTRIBUTING.md
.
The first line of a commit message (the summary line) is like the subject line of an email. (See CONTRIBUTING.md). A short but complete summary line helps the maintainers respond to your pull request more quickly.
If you’re making changes - please write some tests for them! Install dependencies and run the whole test suite with:
bundle
rake test
Be sure to run the test suite before submitting. If you forget, Travis-CI will do that for you and embarrass you in front of all your friends. :)
You may also use a set of environment variables to increase verbosity:
TESTOPTS
,TEST
etc. for the old minitest suitesSPEC_OPTS
,SPEC
etc. for rspec suitesVERBOSE_TESTS
to see the standard output from the actual code = ignore theshutup
helper
Example of a very verbose output:
TESTOPTS='-v' SPEC_OPTS='-fd' VERBOSE_TESTS=1 rake test
Advanced users may create their own external commands for homebrew-cask by following conventions similar to external commands for git or Homebrew. An external command may be any executable on your $PATH
which follows the form brewcask-<command>
. (So long as <command>
does not conflict with an existing command verb.) The command will be invoked by exec
and passed any unprocessed arguments from the original command-line. An external command may also be implemented as an executable Ruby file, on your $PATH
, which follows the form brewcask-<command>.rb
. The Ruby file will be required
and will have full access to the Ruby environments of both homebrew-cask and Homebrew. Example external commands may be found in developer/examples
.
We’re on IRC at #homebrew-cask
on Freenode. If you are going to develop for homebrew-cask, it’s a great idea to hang out with us there. Here’s why:
- Discuss your thoughts before coding and maybe get new ideas
- Get feedback from the Travis-CI bot on build failures
- Talk to caskbot about checksums, version info, and releases
- Just to be social!