relish 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ @announce
2
+ Feature: Help
3
+
4
+ The `relish help` command displays all available commands
5
+ along with a description of each.
6
+
7
+ The `relish help:<command>` option will display help text
8
+ for that particular command.
9
+
10
+ Scenario: View all available commands with the help command
11
+ When I successfully run "relish help"
12
+ Then the output should contain exactly:
13
+ """
14
+ === Available Commands
15
+
16
+ help # show this usage
17
+ config # display the contents of your options file
18
+ config:show # display the contents of your options file
19
+ config:add --<option> <value> # add a configuration option to your options file
20
+ projects # list your projects
21
+ projects:list # list your projects
22
+ projects:add <org_or_user_handle>/<project_handle> # add a project
23
+ projects:remove <org_or_user_handle>/<project_handle> # remove a project
24
+ push # push features to relishapp.com
25
+
26
+ """
27
+
28
+ Scenario: Specifying no command runs the help command
29
+ When I successfully run "relish"
30
+ Then the output should contain "=== Available Commands"
31
+
32
+ Scenario: Specifying an unknown command gives an error message
33
+ When I run "relish baloney"
34
+ Then it should fail with:
35
+ """
36
+ Unknown command. Run 'relish help' for usage information.
37
+ """
@@ -9,4 +9,4 @@ Feature: Push
9
9
 
10
10
  Scenario: Specify everything at the command-line
11
11
  When I run relish push --host localhost:1234 --project p
12
- Then it should POST to "http://localhost:1234/api/pushes?project_id=p&api_token=1234"
12
+ Then it should POST to "http://localhost:1234/api/pushes?project_id=p"
@@ -1,4 +1,5 @@
1
1
  require 'relish'
2
+ require 'relish/helpers'
2
3
  require 'relish/commands/base'
3
4
  require 'relish/commands/push'
4
5
  require 'relish/commands/config'
@@ -8,14 +9,31 @@ require 'relish/commands/help'
8
9
  module Relish
9
10
  module Command
10
11
 
11
- def self.run(command, args)
12
- command_class, method = get_command_and_method(command, args)
13
- command_class.new(args).send(method)
14
- end
12
+ class << self
13
+ include Relish::Helpers
14
+
15
+ def run(command, args)
16
+ command_class, method = get_command_and_method(command, args)
17
+ command_class.new(args).send(method)
18
+ end
19
+
20
+ def get_command_and_method(command, args)
21
+ command_class, method = command.split(':')
22
+ return get_command(command_class.capitalize), get_method(method)
23
+ rescue NameError
24
+ error "Unknown command. Run 'relish help' for usage information."
25
+ end
26
+
27
+ private
15
28
 
16
- def self.get_command_and_method(command, args)
17
- command_class, method = command.split(':')
18
- return Relish::Command.const_get(command_class.capitalize), (method || :default)
29
+ def get_command(command)
30
+ Relish::Command.const_get(command)
31
+ end
32
+
33
+ def get_method(method)
34
+ method || :default
35
+ end
36
+
19
37
  end
20
38
 
21
39
  end
@@ -57,19 +57,13 @@ module Relish
57
57
  end
58
58
 
59
59
  def valid_option_names
60
- self.class.option_names
61
- end
62
-
63
- def option_names_to_display
64
- self.class.option_names_to_display
60
+ Dsl::Option.names
65
61
  end
66
62
 
67
63
  def validate_cli_options
68
64
  @cli_options.keys.each do |option|
69
65
  unless valid_option_names.include?(option.to_s)
70
- puts "#{option} is not a valid option.\n" +
71
- "Valid options are: #{option_names_to_display.sort.join(', ')}"
72
-
66
+ puts "#{option} is not a valid option."
73
67
  exit 1
74
68
  end
75
69
  end
@@ -2,11 +2,12 @@ module Relish
2
2
  module Command
3
3
  class Config < Base
4
4
 
5
- def default
6
- show
7
- end
5
+ desc 'display the contents of your options file'
6
+ command :default => :show
8
7
 
9
- def show
8
+ usage 'config:show'
9
+ desc 'display the contents of your options file'
10
+ command :show do
10
11
  puts(if File.exists?(Relish.local_options_file)
11
12
  IO.read(Relish.local_options_file)
12
13
  else
@@ -14,7 +15,9 @@ module Relish
14
15
  end)
15
16
  end
16
17
 
17
- def add
18
+ usage 'config:add --<option> <value>'
19
+ desc 'add a configuration option to your options file'
20
+ command :add do
18
21
  OptionsFile.new(Relish.local_options_file).store(@cli_options)
19
22
  end
20
23
 
@@ -0,0 +1,23 @@
1
+ module Relish
2
+ module Command
3
+ module Dsl
4
+ class Base
5
+
6
+ attr_reader :context
7
+
8
+ def initialize(context)
9
+ @context = context
10
+ end
11
+
12
+ def context_eval(&block)
13
+ context.class_eval(&block)
14
+ end
15
+
16
+ def context_name
17
+ context.name.split('::').last.downcase
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Relish
2
+ module Command
3
+ module Dsl
4
+ class Command < Base
5
+
6
+ def define(name, &block)
7
+ context_eval do
8
+ define_method(name) do
9
+ begin
10
+ instance_exec(&block)
11
+ rescue RestClient::Exception => exception
12
+ warn exception.response
13
+ exit 1
14
+ end
15
+ end
16
+ end
17
+ HelpText.add(name, context_name)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ module Relish
2
+ module Command
3
+ module Dsl
4
+ class HelpText
5
+
6
+ class << self
7
+ attr_accessor :current_command, :next_usage, :next_description
8
+
9
+ def add(name, command)
10
+ self.current_command = name
11
+ commands[command] = [] unless commands.key?(command)
12
+ commands[command].push(get_next_usage => get_next_description)
13
+ reset_accessors
14
+ end
15
+
16
+ def get_next_usage
17
+ next_usage or current_command.to_s
18
+ end
19
+
20
+ def get_next_description
21
+ next_description || raise(
22
+ "please set a description for #{current_command.inspect}"
23
+ )
24
+ end
25
+
26
+ def commands
27
+ @commands ||= {}
28
+ end
29
+
30
+ def reset_accessors
31
+ self.current_command = self.next_usage = self.next_description = nil
32
+ end
33
+
34
+ def clear_commands
35
+ @commands = {}
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ module Relish
2
+ module Command
3
+ module Dsl
4
+ class Option < Base
5
+
6
+ def define(name, options = {})
7
+ name = name.to_s
8
+ default_proc = options[:default] || Proc.new {}
9
+
10
+ context_eval do
11
+ define_method(name) do
12
+ cli_options[name] ||
13
+ local_options_file[name] ||
14
+ global_options_file[name] ||
15
+ instance_exec(&default_proc)
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.names
21
+ @@names ||= []
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,28 +1,37 @@
1
+ require 'relish/commands/dsl/base'
2
+ require 'relish/commands/dsl/option'
3
+ require 'relish/commands/dsl/command'
4
+ require 'relish/commands/dsl/help_text'
5
+
1
6
  module Relish
2
7
  module Command
3
8
  module Dsl
4
9
 
5
10
  def option(name, options = {})
6
- name = name.to_s
7
- default_proc = options[:default] || Proc.new {}
8
-
9
- define_method(name) do
10
- cli_options[name] ||
11
- local_options_file[name] ||
12
- global_options_file[name] ||
13
- instance_exec(&default_proc)
14
- end
15
-
16
- option_names << name
17
- option_names_to_display << name unless options[:display] == false
11
+ Option.new(self).define(name, options)
12
+ Option.names << name.to_s
18
13
  end
19
14
 
20
- def option_names
21
- @@option_names ||= []
15
+ def usage(str)
16
+ HelpText.next_usage = str
22
17
  end
23
18
 
24
- def option_names_to_display
25
- @@option_names_to_display ||= []
19
+ def desc(str)
20
+ HelpText.next_description = str
21
+ end
22
+
23
+ def command(arg, &block)
24
+ case arg
25
+ when Hash
26
+ name, alias_target = arg.to_a.flatten
27
+ block = lambda { self.send(alias_target) }
28
+ when Symbol
29
+ name = arg
30
+ else
31
+ raise ArgumentError
32
+ end
33
+
34
+ Command.new(self).define(name, &block)
26
35
  end
27
36
 
28
37
  end
@@ -3,29 +3,26 @@ require 'yaml'
3
3
  module Relish
4
4
  module Command
5
5
  class Help < Base
6
- class << self
7
- def for_command(command, help)
8
- command_help[command] = help
9
- end
10
-
11
- def command_help
12
- @command_help ||= {}
13
- end
14
- end
15
6
 
16
- def default
17
- puts "This is the prefunctory help message for the relish gem."
7
+ desc 'show this usage'
8
+ command :default do
9
+ puts "=== Available Commands\n\n"
18
10
 
19
- puts "Commands:"
20
- Help.command_help.each do |command, help|
21
- message = "relish #{command}".ljust(max_command_length) +
22
- " # " + help
23
- puts message
11
+ Dsl::HelpText.commands.each do |command, list|
12
+ list.each do |hash|
13
+ usage, description = *hash.to_a.flatten
14
+ usage = command if usage == 'default'
15
+ puts "#{usage.ljust(max_command_length)} # #{description}"
16
+ end
24
17
  end
25
18
  end
26
19
 
20
+ private
21
+
27
22
  def max_command_length
28
- Help.command_help.keys.map { |c| c.to_s.length }.max
23
+ Dsl::HelpText.commands.values.map {|v|
24
+ v.map {|v| v.keys.to_s.length }.max
25
+ }.max
29
26
  end
30
27
  end
31
28
  end
@@ -5,30 +5,26 @@ module Relish
5
5
  module Command
6
6
  class Projects < Base
7
7
 
8
- def default; list end
8
+ desc 'list your projects'
9
+ command :default => :list
9
10
 
10
- def list
11
- response = resource['projects'].get(
12
- :params => {:api_token => api_token}, :accept => :json
13
- )
11
+ usage 'projects:list'
12
+ desc 'list your projects'
13
+ command :list do
14
+ response = resource['projects'].get(:accept => :json)
14
15
  puts format(response)
15
- rescue RestClient::Exception => exception
16
- warn exception.response
17
- exit exception.http_code
18
16
  end
19
17
 
20
- def add
18
+ usage 'projects:add <org_or_user_handle>/<project_handle>'
19
+ desc 'add a project'
20
+ command :add do
21
21
  puts resource['projects'].post(:handle => @param)
22
- rescue RestClient::Exception => exception
23
- warn exception.response
24
- exit 1
25
22
  end
26
23
 
27
- def remove
24
+ usage 'projects:remove <org_or_user_handle>/<project_handle>'
25
+ desc 'remove a project'
26
+ command :remove do
28
27
  puts resource["projects/#{@param}"].delete
29
- rescue RestClient::Exception => exception
30
- warn exception.response
31
- exit 1
32
28
  end
33
29
 
34
30
  private
@@ -6,26 +6,21 @@ require 'rest_client'
6
6
  require 'relish/commands/help'
7
7
 
8
8
  module Relish
9
- module Command
10
- Help.for_command(:push, "push your features to relishapp.com")
11
-
9
+ module Command
12
10
  class Push < Base
13
-
14
11
  option :version
15
12
 
16
- def default; run end
17
-
18
- def run
13
+ desc 'push features to relishapp.com'
14
+ command :default do
19
15
  post files_as_tar_gz
20
16
  end
17
+
18
+ private
21
19
 
22
20
  def post(tar_gz_data)
23
21
  resource["pushes?#{parameters}"].post(tar_gz_data,
24
22
  :content_type => 'application/x-gzip')
25
23
  puts "sent:\n#{files.join("\n")}"
26
- rescue RestClient::Exception => exception
27
- warn exception.response
28
- exit 1
29
24
  end
30
25
 
31
26
  def parameters
@@ -0,0 +1,10 @@
1
+ module Relish
2
+ module Helpers
3
+
4
+ def error(message)
5
+ $stderr.puts(message)
6
+ exit 1
7
+ end
8
+
9
+ end
10
+ end
data/relish.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "relish"
3
- s.version = "0.0.8"
3
+ s.version = "0.0.9"
4
4
 
5
5
  s.required_rubygems_version = '>= 1.3.5'
6
6
  s.authors = ["Matt Wynne", "Justin Ko"]
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module Relish
4
+ module Command
5
+ module Dsl
6
+ describe Base do
7
+
8
+ describe '#context_eval' do
9
+ let(:context_class) { Class.new }
10
+ let(:base) { described_class.new(context_class) }
11
+ let(:the_block) { Proc.new { "Hi, I'm a block" } }
12
+
13
+ it 'calls class_eval on the context_class with the given block' do
14
+ context_class.should_receive(:class_eval).with(&the_block)
15
+ base.context_eval(&the_block)
16
+ end
17
+ end
18
+
19
+ describe '#context_name' do
20
+ let(:context_class) { Class.new }
21
+ let(:base) { described_class.new(context_class) }
22
+ before { context_class.should_receive(:name).and_return('::Dog') }
23
+
24
+ it 'returns the class name downcased' do
25
+ base.context_name.should eq('dog')
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Relish
4
+ module Command
5
+ module Dsl
6
+ describe Command do
7
+
8
+ describe '#define' do
9
+ let(:context_class) { Class.new }
10
+ let(:command) { described_class.new(context_class) }
11
+ let(:the_instance) { context_class.new }
12
+
13
+ before do
14
+ context_class.should_receive(:name).and_return('::Dog')
15
+ HelpText.stub(:add)
16
+ end
17
+
18
+ it 'defines an instance method on the context class' do
19
+ command.define(:my_command) {}
20
+ the_instance.should respond_to(:my_command)
21
+ end
22
+
23
+ context 'the instance method' do
24
+
25
+ it 'evaluates the block' do
26
+ command.define(:my_command) { 'my command value' }
27
+ the_instance.my_command.should eq('my command value')
28
+ end
29
+
30
+ it 'rescues RestClient::Exception' do
31
+ command.define(:my_command) do
32
+ raise RestClient::Exception.new('uh oh an exception')
33
+ end
34
+ the_instance.should_receive(:warn).with('uh oh an exception')
35
+ the_instance.should_receive(:exit).with(1)
36
+ the_instance.my_command
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ module Relish
4
+ module Command
5
+ module Dsl
6
+ describe HelpText do
7
+
8
+ describe '.add' do
9
+
10
+ it 'adds a command to the hash of commands' do
11
+ HelpText.clear_commands
12
+
13
+ HelpText.should_receive(:get_next_usage).and_return('usage')
14
+ HelpText.should_receive(:get_next_description).and_return('description')
15
+ HelpText.should_receive(:reset_accessors)
16
+
17
+ HelpText.add(:my_command, 'projects')
18
+ HelpText.commands.should eq(
19
+ {'projects' => [{'usage' => 'description'}]}
20
+ )
21
+ end
22
+
23
+ end
24
+
25
+ describe '.get_next_usage' do
26
+
27
+ context 'with next_usage set' do
28
+ before { HelpText.next_usage = 'foo' }
29
+
30
+ it 'returns next_usage' do
31
+ HelpText.get_next_usage.should eq('foo')
32
+ end
33
+ end
34
+
35
+ context 'without next_usage set' do
36
+ before do
37
+ HelpText.next_usage = nil
38
+ HelpText.current_command = 'bar'
39
+ end
40
+
41
+ it 'returns current_command' do
42
+ HelpText.get_next_usage.should eq('bar')
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ describe '.get_next_description' do
49
+
50
+ context 'with next_description set' do
51
+ before { HelpText.next_description = 'foo' }
52
+
53
+ it 'returns next_description' do
54
+ HelpText.get_next_description.should eq('foo')
55
+ end
56
+ end
57
+
58
+ context 'without next_description set' do
59
+ before do
60
+ HelpText.current_command = :bar
61
+ HelpText.next_description = nil
62
+ end
63
+
64
+ it 'raises an exception' do
65
+ expect { HelpText.get_next_description }.to raise_exception(
66
+ 'please set a description for :bar'
67
+ )
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ describe '.reset_accessors' do
74
+ before do
75
+ HelpText.current_command = 'foo'
76
+ HelpText.next_usage = 'foo'
77
+ HelpText.next_description = 'foo'
78
+ end
79
+
80
+ it 'sets all accessors to nil' do
81
+ HelpText.current_command.should eq('foo')
82
+ HelpText.next_usage.should eq('foo')
83
+ HelpText.next_description.should eq('foo')
84
+
85
+ HelpText.reset_accessors
86
+
87
+ HelpText.current_command.should be_nil
88
+ HelpText.next_usage.should be_nil
89
+ HelpText.next_description.should be_nil
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ module Relish
4
+ module Command
5
+ module Dsl
6
+ describe Option do
7
+
8
+ describe '#define' do
9
+ let(:context_class) { Class.new }
10
+ let(:option) { described_class.new(context_class) }
11
+ let(:the_instance) { context_class.new }
12
+
13
+ before do
14
+ option.define(:my_option, :default => lambda { "I'm a proc!" })
15
+ end
16
+
17
+ it 'defines an instance method on the context class' do
18
+ the_instance.should respond_to(:my_option)
19
+ end
20
+
21
+ context 'the instance method' do
22
+
23
+ it 'calls on #cli_options' do
24
+ the_instance.should_receive(:cli_options).and_return(
25
+ 'my_option' => 'a_cli_option_value'
26
+ )
27
+ the_instance.my_option.should eq('a_cli_option_value')
28
+ end
29
+
30
+ it 'calls on #local_options_file' do
31
+ the_instance.should_receive(:cli_options).and_return({})
32
+ the_instance.should_receive(:local_options_file).and_return(
33
+ 'my_option' => 'a_local_option_value'
34
+ )
35
+ the_instance.my_option.should eq('a_local_option_value')
36
+ end
37
+
38
+ it 'calls on #global_options_file' do
39
+ the_instance.should_receive(:cli_options).and_return({})
40
+ the_instance.should_receive(:local_options_file).and_return({})
41
+ the_instance.should_receive(:global_options_file).and_return(
42
+ 'my_option' => 'a_global_option_value'
43
+ )
44
+ the_instance.my_option.should eq('a_global_option_value')
45
+ end
46
+
47
+ it 'calls the :default proc' do
48
+ the_instance.should_receive(:cli_options).and_return({})
49
+ the_instance.should_receive(:local_options_file).and_return({})
50
+ the_instance.should_receive(:global_options_file).and_return({})
51
+ the_instance.my_option.should eq("I'm a proc!")
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ describe '.names' do
59
+ specify { described_class.should_not have(0).names }
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
@@ -7,56 +7,12 @@ module Relish
7
7
  describe '#default' do
8
8
  let(:push) { described_class.new }
9
9
 
10
- it 'calls #run' do
11
- push.should_receive(:run)
10
+ it 'calls #post' do
11
+ push.should_receive(:post)
12
12
  push.default
13
13
  end
14
14
  end
15
15
 
16
- describe '#parameters' do
17
- before { push.should_receive(:project).and_return('rspec') }
18
-
19
- context 'without version' do
20
- let(:push) { described_class.new }
21
-
22
- specify do
23
- push.parameters.should eq("project_id=rspec")
24
- end
25
- end
26
-
27
- context 'with version' do
28
- let(:push) { described_class.new(['--version', 'one']) }
29
-
30
- specify do
31
- push.parameters.should eq("project_id=rspec&version_id=one")
32
- end
33
- end
34
- end
35
-
36
- describe '#version' do
37
- context 'with --version passed in command line' do
38
- let(:push) { described_class.new(['--version', 'one']) }
39
- specify { push.version.should eq('one') }
40
- end
41
-
42
- context 'with --version not passed in command line' do
43
- let(:push) { described_class.new }
44
- specify { push.version.should be_nil }
45
- end
46
- end
47
-
48
- describe '#files_as_tar_gz' do
49
- let(:push) { described_class.new }
50
- specify { expect { push.files_as_tar_gz }.to_not raise_exception }
51
- specify { push.files_as_tar_gz.should be_a(String) }
52
- end
53
-
54
- describe '#files' do
55
- let(:push) { described_class.new }
56
- specify { expect { push.files }.to_not raise_exception }
57
- specify { push.files.should be_a(Array) }
58
- end
59
-
60
16
  end
61
17
  end
62
18
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relish
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 8
10
- version: 0.0.8
9
+ - 9
10
+ version: 0.0.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Wynne
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-09-23 00:00:00 +01:00
19
+ date: 2010-09-23 00:00:00 -06:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -179,6 +179,7 @@ files:
179
179
  - Rakefile
180
180
  - bin/relish
181
181
  - cucumber.yml
182
+ - features/help.feature
182
183
  - features/projects.feature
183
184
  - features/push.feature
184
185
  - features/step_definitions/aruba.rb
@@ -190,15 +191,24 @@ files:
190
191
  - lib/relish/commands/base.rb
191
192
  - lib/relish/commands/config.rb
192
193
  - lib/relish/commands/dsl.rb
194
+ - lib/relish/commands/dsl/base.rb
195
+ - lib/relish/commands/dsl/command.rb
196
+ - lib/relish/commands/dsl/help_text.rb
197
+ - lib/relish/commands/dsl/option.rb
193
198
  - lib/relish/commands/help.rb
194
199
  - lib/relish/commands/projects.rb
195
200
  - lib/relish/commands/push.rb
201
+ - lib/relish/helpers.rb
196
202
  - lib/relish/options_file.rb
197
203
  - lib/relish/ui.rb
198
204
  - relish.gemspec
199
205
  - spec/relish/command_spec.rb
200
206
  - spec/relish/commands/base_spec.rb
201
207
  - spec/relish/commands/config_spec.rb
208
+ - spec/relish/commands/dsl/base_spec.rb
209
+ - spec/relish/commands/dsl/command_spec.rb
210
+ - spec/relish/commands/dsl/help_text_spec.rb
211
+ - spec/relish/commands/dsl/option_spec.rb
202
212
  - spec/relish/commands/projects_spec.rb
203
213
  - spec/relish/commands/push_spec.rb
204
214
  - spec/relish/options_file_spec.rb
@@ -241,6 +251,7 @@ signing_key:
241
251
  specification_version: 3
242
252
  summary: Client gem for http://relishapp.com
243
253
  test_files:
254
+ - features/help.feature
244
255
  - features/projects.feature
245
256
  - features/push.feature
246
257
  - features/step_definitions/aruba.rb
@@ -250,6 +261,10 @@ test_files:
250
261
  - spec/relish/command_spec.rb
251
262
  - spec/relish/commands/base_spec.rb
252
263
  - spec/relish/commands/config_spec.rb
264
+ - spec/relish/commands/dsl/base_spec.rb
265
+ - spec/relish/commands/dsl/command_spec.rb
266
+ - spec/relish/commands/dsl/help_text_spec.rb
267
+ - spec/relish/commands/dsl/option_spec.rb
253
268
  - spec/relish/commands/projects_spec.rb
254
269
  - spec/relish/commands/push_spec.rb
255
270
  - spec/relish/options_file_spec.rb