Extend subcommand dispatch to include full paths

Covering all cases
- external commands as executables
- external commands as Ruby libraries
- built-in command verbs

This is intended as a development aid.

A side benefit is that an external command can be constructed
to use a `run` method, rather than having to accomplish everything
at `require` time.
This commit is contained in:
Roland Walker
2014-06-21 14:51:57 -04:00
parent ddb9322882
commit 29a6a1ec10
2 changed files with 50 additions and 2 deletions
+12
View File
@@ -144,6 +144,18 @@ with fully-qualified paths, like this:
$ HOMEBREW_BREW_FILE=/usr/local/bin/brew /System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby /usr/local/Library/brew.rb /usr/local/bin/brew-cask.rb help
```
## How Can I Force a Specific Homebrew-cask Subcommand?
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:
```bash
$ brew cask /usr/local/Cellar/brew-cask/0.37.0/rubylib/cask/cli/info.rb google-chrome
```
This form can also be combined with a specific Ruby interpreter as above.
## Hanging out on IRC
We're on IRC at `#homebrew-cask` on Freenode. If you are going to develop for
+38 -2
View File
@@ -63,14 +63,50 @@ class Cask::CLI
@@lookup.fetch(command_string, command_string)
end
# modified from Homebrew
def self.require? path
require path
true # OK if already loaded
rescue LoadError => e
# HACK :( because we should raise on syntax errors but
# not if the file doesn't exist. TODO make robust!
raise unless e.to_s.include? path
end
def self.run_command(command, *rest)
if command.respond_to?(:run)
# usual case: built-in command verb
command.run(*rest)
elsif which "brewcask-#{command}"
exec "brewcask-#{command}", *ARGV[1..-1]
elsif require? which("brewcask-#{command}.rb").to_s
# external command as Ruby library on PATH, Homebrew-style
exit 0
elsif command.to_s.include?('/') and require? command.to_s
# external command as Ruby library with literal path, useful
# for development and troubleshooting
sym = Pathname.new(command.to_s).basename('.rb').to_s.capitalize
klass = begin
Cask::CLI.const_get(sym)
rescue
nil
end
if klass.respond_to?(:run)
# invoke "run" on a Ruby library which follows our coding conventions
klass.run(*rest)
else
# other Ruby libraries must do everything via "require"
exit 0
end
elsif which "brewcask-#{command}"
# arbitrary external executable on PATH, Homebrew-style
exec "brewcask-#{command}", *ARGV[1..-1]
elsif Pathname.new(command.to_s).executable? and
command.to_s.include?('/') and
not command.to_s.match(%{\.rb$})
# arbitrary external executable with literal path, useful
# for development and troubleshooting
exec command, *ARGV[1..-1]
else
# failure
Cask::CLI::NullCommand.new(command).run
end
end