Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSL: document the new-style header line #7311

Merged
merged 4 commits into from
Nov 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Here's a Cask for `Alfred.app` as an example. Note that you may repeat
the `app` stanza as many times as you need, to define multiple apps:

```ruby
class Alfred < Cask
cask :v1 => 'alfred' do
version '2.3_264'
sha256 'a32565cdb1673f4071593d4cc9e1c26bc884218b62fef8abc450daa47ba8fa92'

Expand All @@ -49,7 +49,7 @@ end
Here is another Cask for `Unity.pkg`:

```ruby
class Unity < Cask
cask :v1 => 'unity' do
version '4.5.4'
sha256 '6fb72bfacf78df072559dd9a024a9d47e49b5717c8f17d53f05e2fc74a721876'

Expand All @@ -65,7 +65,7 @@ end
And here is one for `Firefox.app`. Note that it has an unversioned download (the download `url` does not contain the version number, unlike the example above). It also suppresses the checksum with `sha256 :no_check` (necessary since the checksum will change when a new version is available). This combination of `version :latest` and `sha256 :no_check` is currently the preferred mechanism when an unversioned download URL is available:

```ruby
class Firefox < Cask
cask :v1 => 'firefox' do
version :latest
sha256 :no_check

Expand Down Expand Up @@ -109,14 +109,12 @@ Once you know the name for your Cask, create it with the handy-dandy
$ brew cask create my-new-cask
```

This will open `$EDITOR` with a template for your new Cask. Hyphens in the
Cask name indicate case-changes in the class name, so the Cask name
'my-new-cask' becomes class `MyNewCask` stored in file `my-new-cask.rb`.
Running the `create` command above will get you a template that looks like
this:
This will open `$EDITOR` with a template for your new Cask, to be stored in
the file `my-new-cask.rb`. Running the `create` command above will get you
a template that looks like this:

```ruby
class MyNewCask < Cask
cask :v1 => 'my-new-cask' do
version ''
sha256 ''

Expand Down
29 changes: 1 addition & 28 deletions developer/bin/cask_namer
Original file line number Diff line number Diff line change
Expand Up @@ -340,29 +340,6 @@ class CaskFileName < String
end
end

class CaskClassName < String
def basename
if Pathname.new(self).exist?
CaskClassName.new(Pathname.new(self).basename.to_s)
else
self
end
end

def remove_extension
self.sub(/#{escaped_cask_file_extension}\Z/i, '')
end

def hyphens_to_camel_case
self.split('-').map(&:capitalize).join
end

def from_cask_name
# or from filename
self.basename.remove_extension.hyphens_to_camel_case
end
end

###
### methods
###
Expand Down Expand Up @@ -398,10 +375,6 @@ def cask_name
@cask_name ||= cask_file_name.remove_extension
end

def class_name
@class_name ||= CaskClassName.new(cask_name).from_cask_name
end

def warnings
return @warnings if @warnings
@warnings = []
Expand All @@ -421,7 +394,7 @@ def report
puts "Proposed canonical App name: #{canonical_name}" if $debug
puts "Proposed Cask name: #{cask_name}"
puts "Proposed file name: #{cask_file_name}"
puts "First Line of Cask: class #{class_name} < Cask"
puts "First Line of Cask: cask :v1 => '#{cask_name}' do"
if warnings.length > 0
STDERR.puts "\n"
STDERR.puts warnings
Expand Down
35 changes: 28 additions & 7 deletions doc/CASK_LANGUAGE_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
This document acts as a complete specification, and covers aspects of the
Cask Domain-Specific Language (DSL) which are not needed in most cases.

* [Casks Are Ruby Classes](#casks-are-ruby-classes)
* [Casks Are Ruby Blocks](#casks-are-ruby-blocks)
* [The Cask Language Is Declarative](#the-cask-language-is-declarative)
* [Required Stanzas](#required-stanzas)
* [At Least One Artifact Stanza Is Also Required](#at-least-one-artifact-stanza-is-also-required)
* [Optional Stanzas](#optional-stanzas)
* [Legacy Stanzas](#legacy-stanzas)
* [Legacy Forms](#legacy-forms)
* [Conditional Statements](#conditional-statements)
* [Header Line Details](#header-line-details)
* [Caveats Stanza Details](#caveats-stanza-details)
* [Checksum Stanza Details](#checksum-stanza-details)
* [URL Stanza Details](#url-stanza-details)
Expand All @@ -30,13 +31,13 @@ Cask Domain-Specific Language (DSL) which are not needed in most cases.
* [Revisions to the Cask DSL](#revisions-to-the-cask-dsl)


## Casks Are Ruby Classes
## Casks Are Ruby Blocks

Each Cask is a Ruby class, derived from class `Cask`. The Cask definition
is always enclosed in a `class ... end` block. Example:
Each Cask is a Ruby block, beginning with a special header line. The Cask
definition itself is always enclosed in a `do ... end` block. Example:

```ruby
class Alfred < Cask
cask :v1 => 'alfred' do
version '2.3_264'
sha256 'a32565cdb1673f4071593d4cc9e1c26bc884218b62fef8abc450daa47ba8fa92'

Expand All @@ -49,7 +50,6 @@ class Alfred < Cask
end
```


## The Cask Language Is Declarative

Each Cask contains a series of stanzas (or "fields") which *declare* how the
Expand Down Expand Up @@ -196,6 +196,27 @@ else
end
```

## Header Line Details

The first non-comment line in a Cask follows the form

```ruby
cask <dsl-version> => '<cask-name>' do
```

`<dsl-version>` identifies the version of the Cask DSL, currently `:v1`.

`<cask-name>` should match the Cask filename, without the `.rb` extension,
enclosed in single quotes.

The header line is not entirely strict Ruby: no comma is required after
the Cask name.

There are currently some arbitrary limitations on Cask names which are
in the process of being removed. The Travis bot will catch any errors
during the transition.


## Caveats Stanza Details

### Caveats as a String
Expand Down Expand Up @@ -858,7 +879,7 @@ define arbitrary Ruby variables and methods inside the Cask by creating a
`Utils` namespace. Example:

```ruby
class Appname < Cask
cask :v1 => 'appname' do
module Utils
def self.arbitrary_method
...
Expand Down
29 changes: 8 additions & 21 deletions doc/CASK_NAMING_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ most cases.

* [Find the Canonical Name of the Developer's Distribution](#find-the-canonical-name-of-the-developers-distribution)
* [Cask Name](#cask-name)
* [Cask Class](#cask-class)
* [Cask Naming Examples](#cask-naming-examples)

## Find the Canonical Name of the Developer's Distribution
Expand Down Expand Up @@ -80,30 +79,18 @@ Casks are stored in a Ruby file matching their name. If possible, avoid creatin
Cask files which differ only by the placement of hyphens.


## Cask Class

Casks are implemented as Ruby classes, so a Cask's "class" needs to be a
valid Ruby class name.

When converting a __Cask name__ to its corresponding __class name__:

* convert to UpperCamelCase
* wherever a hyphen occurs in the __Cask name__, remove the hyphen and
create a case change in the __class name__


## Cask Naming Examples

These illustrate most of the naming rules:

App Name on Disk | Canonical App Name | Cask Name | Cask File | Cask Class
-----------------------|--------------------|--------------------|-----------------------|------------------------
`Audio Hijack Pro.app` | Audio Hijack Pro | `audio-hijack-pro` | `audio-hijack-pro.rb` | `AudioHijackPro`
`VLC.app` | VLC | `vlc` | `vlc.rb` | `Vlc`
`BetterTouchTool.app` | BetterTouchTool | `bettertouchtool` | `bettertouchtool.rb` | `Bettertouchtool`
`LPK25 Editor.app` | LPK25 Editor | `lpk25-editor` | `lpk25-editor.rb` | `Lpk25Editor`
`Sublime Text 2.app` | Sublime Text | `sublime-text` | `sublime-text.rb` | `SublimeText`
`1Password.app` | 1Password | `onepassword` | `onepassword.rb` | `Onepassword`
App Name on Disk | Canonical App Name | Cask Name | Cask File
-----------------------|--------------------|--------------------|----------------------
`Audio Hijack Pro.app` | Audio Hijack Pro | `audio-hijack-pro` | `audio-hijack-pro.rb`
`VLC.app` | VLC | `vlc` | `vlc.rb`
`BetterTouchTool.app` | BetterTouchTool | `bettertouchtool` | `bettertouchtool.rb`
`LPK25 Editor.app` | LPK25 Editor | `lpk25-editor` | `lpk25-editor.rb`
`Sublime Text 2.app` | Sublime Text | `sublime-text` | `sublime-text.rb`
`1Password.app` | 1Password | `onepassword` | `onepassword.rb`


# <3 THANK YOU TO ALL CONTRIBUTORS! <3
23 changes: 23 additions & 0 deletions doc/cask_language_deltas.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Cask DSL 1.0 specification.
* [Removals (1.0)](#removals-10)
* [Additions (1.0)](#additions-10)
* [Renames (1.0)](#renames-10)
* [Header Line (1.0)](#header-line-10)
* [All Supported Stanzas (1.0)](#all-supported-stanzas-10)


Expand Down Expand Up @@ -79,6 +80,28 @@ This notice will be removed for the final form.**
**Stub!**


## Header Line (1.0)

The header line was changed from the form

```ruby
class MyApp < Cask
```

to

```ruby
cask :v1 => 'my-app' do
```

Legacy rules for mapping Cask filenames to header class names are no longer
needed. The name `'my-app'` in the header corresponds directly to the
filename `my-app.rb`.

The term `:v1` identifies the DSL version (currently 1.0), and defines the
features which are available for the current Cask.


## References

* [DSL 1.0 transition notice](https://github.com/caskroom/homebrew-cask/issues/5890)
Expand Down
3 changes: 1 addition & 2 deletions lib/cask/cli/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ def self.run(*args)
end

def self.template(cask_name);
cask_class = cask_name.split('-').map(&:capitalize).join
<<-EOS.undent
class #{cask_class} < Cask
cask :v1 => '#{cask_name}' do
version ''
sha256 ''

Expand Down
2 changes: 1 addition & 1 deletion lib/cask/source/path_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def load
#
# limitation: does not support Ruby extended quoting such as %Q{}
#
# in the future, this can be pared down to an "eval"
# todo: in the future, this can be pared down to an "eval"

# read Cask
cask_string = File.open(path, 'rb') do |handle|
Expand Down
2 changes: 1 addition & 1 deletion test/cask/cli/create_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def self.editor_commands
Cask::CLI::Create.run('new-cask')
template = File.read(Cask.path('new-cask'))
template.must_equal <<-TEMPLATE.undent
class NewCask < Cask
cask :v1 => 'new-cask' do
version ''
sha256 ''

Expand Down