relish 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,22 +8,32 @@ Feature: Help
8
8
  When I successfully run "relish help"
9
9
  Then the output should contain exactly:
10
10
  """
11
+ A <project> can be scoped by an organization or user handle. For
12
+ example, if an organiztion (rspec) has a project (rspec-core), then
13
+ the <project> would be `rspec/rspec-core`. If a user (justin) has a
14
+ project (my-project), then <project> would be `justin/my-project`.
15
+
16
+ If you leave off the organization or user handle, then it defaults
17
+ to the user (you).
18
+
11
19
  === Available Commands
12
20
 
13
- help # show this usage
14
- config # display the contents of your options file
15
- config:add --<option> <value> # add a configuration option to your options file
16
- projects # list your projects
17
- projects:add <org_or_user_handle>/<project_handle> # add a project
18
- # append :private to make the project private
19
- # example: relish projects:add rspec/rspec-core:private
20
- projects:remove <org_or_user_handle>/<project_handle> # remove a project
21
- push # push features to relishapp.com
22
- collab # list the collaborators for a project
23
- collab:add <org_or_user_handle>/<project_handle>:<collaborator_handle_or_email> # add a collaborator to a project
24
- # example: relish collab:add rspec/rspec-core:justin
25
- collab:remove <org_or_user_handle>/<project_handle>:<collaborator_handle_or_email> # remove a collaborator from a project
26
- # example: relish collab:remove rspec/rspec-core:justin
21
+ help # show this usage
22
+ config # display the contents of your options file
23
+ config:add <option>:<value> # add a configuration option to your options file
24
+ # example: relish config:add project:rspec-core
25
+ # valid configuration options: project
26
+ projects # list your projects
27
+ projects:add <org_or_user_handle>/<project_handle> # add a project
28
+ # append :private to make the project private
29
+ # example: relish projects:add rspec/rspec-core:private
30
+ projects:remove <org_or_user_handle>/<project_handle> # remove a project
31
+ push <project> # push features to relishapp.com
32
+ collab # list the collaborators for a project
33
+ collab:add <project>:<collaborator_handle_or_email> # add a collaborator to a project
34
+ # example: relish collab:add rspec/rspec-core:justin
35
+ collab:remove <project>:<collaborator_handle_or_email> # remove a collaborator from a project
36
+ # example: relish collab:remove rspec/rspec-core:justin
27
37
 
28
38
  """
29
39
 
data/lib/relish.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'relish/core_ext'
2
-
3
1
  module Relish
4
2
  class << self
5
3
 
@@ -1,15 +1,17 @@
1
1
  require 'yaml'
2
2
  require 'json'
3
3
  require 'relish/ui'
4
+ require 'relish/helpers'
4
5
  require 'relish/options_file'
5
6
  require 'relish/commands/dsl'
7
+ require 'relish/commands/param_methods'
6
8
 
7
9
  module Relish
8
10
  module Command
9
11
  class Base
12
+ include Relish::Helpers
10
13
  extend Dsl
11
14
 
12
- option :project
13
15
  option :api_token, :default => lambda { get_and_store_api_token }
14
16
  option :host, :default => lambda { Relish.default_host }, :display => false
15
17
 
@@ -18,7 +20,7 @@ module Relish
18
20
 
19
21
  def initialize(args = [])
20
22
  @args = clean_args(args)
21
- @param = get_param
23
+ @param = get_param.extend(ParamMethods)
22
24
  @cli_options = Hash[*@args]
23
25
 
24
26
  validate_cli_options
@@ -33,6 +35,10 @@ module Relish
33
35
  end
34
36
 
35
37
  private
38
+
39
+ def project
40
+ merged_options['project'] || error('You must specify a project.')
41
+ end
36
42
 
37
43
  def get_and_store_api_token
38
44
  api_token = get_api_token
@@ -62,14 +68,17 @@ module Relish
62
68
  end
63
69
 
64
70
  def validate_cli_options
65
- @cli_options.keys.each do |option|
71
+ cli_options.keys.each do |option|
66
72
  unless valid_option_names.include?(option.to_s)
67
- puts "#{option} is not a valid option."
68
- exit 1
73
+ error "'#{option}' is not a valid option."
69
74
  end
70
75
  end
71
76
  end
72
77
 
78
+ def merged_options
79
+ @merged_options ||= global_options_file.merge(local_options_file)
80
+ end
81
+
73
82
  def global_options_file
74
83
  @global_options ||= OptionsFile.new(Relish.global_options_file)
75
84
  end
@@ -4,29 +4,35 @@ module Relish
4
4
 
5
5
  desc 'list the collaborators for a project'
6
6
  command :default do
7
- puts format(resource[resource_path].get(:accept => :json))
7
+ puts format(resource[resource_path_for_no_option].get(:accept => :json))
8
8
  end
9
9
 
10
- usage 'collab:add <org_or_user_handle>/<project_handle>:' +
11
- '<collaborator_handle_or_email>'
10
+ usage 'collab:add <project>:<collaborator_handle_or_email>'
12
11
  desc ['add a collaborator to a project',
13
- 'example: relish collab:add rspec/rspec-core:justin'].join("\n")
12
+ 'example: relish collab:add rspec/rspec-core:justin']
14
13
  command :add do
15
- puts resource[resource_path].post(:handle_or_email => handle_or_email)
14
+ puts resource[resource_path_for_option].post(:handle_or_email => handle_or_email)
16
15
  end
17
16
 
18
- usage 'collab:remove <org_or_user_handle>/<project_handle>:' +
19
- '<collaborator_handle_or_email>'
17
+ usage 'collab:remove <project>:<collaborator_handle_or_email>'
20
18
  desc ['remove a collaborator from a project',
21
- 'example: relish collab:remove rspec/rspec-core:justin'].join("\n")
19
+ 'example: relish collab:remove rspec/rspec-core:justin']
22
20
  command :remove do
23
- puts resource["#{resource_path}/#{handle_or_email}"].delete
21
+ puts resource["#{resource_path_for_option}/#{handle_or_email}"].delete
24
22
  end
25
23
 
26
24
  private
27
-
28
- def resource_path
29
- "projects/#{@param.remove_option}/memberships"
25
+
26
+ def resource_path_for_no_option
27
+ resource_path(@param || project)
28
+ end
29
+
30
+ def resource_path_for_option
31
+ resource_path(@param.extract_project_handle || project)
32
+ end
33
+
34
+ def resource_path(project)
35
+ "projects/#{project}/memberships"
30
36
  end
31
37
 
32
38
  def handle_or_email
@@ -2,6 +2,26 @@ module Relish
2
2
  module Command
3
3
  class Config < Base
4
4
 
5
+ class Option
6
+ VALID_OPTIONS = %w(project)
7
+
8
+ def initialize(param)
9
+ @option, @value = param.split(':')
10
+ validate_option
11
+ end
12
+
13
+ def validate_option
14
+ unless VALID_OPTIONS.include?(@option)
15
+ Relish::Helpers.error "'#{@option}' is not a valid option." +
16
+ " Valid options: #{VALID_OPTIONS.join(', ')}"
17
+ end
18
+ end
19
+
20
+ def to_hash
21
+ {@option => @value}
22
+ end
23
+ end
24
+
5
25
  desc 'display the contents of your options file'
6
26
  command :default do
7
27
  puts(if File.exists?(Relish.local_options_file)
@@ -11,10 +31,13 @@ module Relish
11
31
  end)
12
32
  end
13
33
 
14
- usage 'config:add --<option> <value>'
15
- desc 'add a configuration option to your options file'
34
+ usage 'config:add <option>:<value>'
35
+ desc ['add a configuration option to your options file',
36
+ 'example: relish config:add project:rspec-core',
37
+ "valid configuration options: #{Option::VALID_OPTIONS.join(', ')}"]
16
38
  command :add do
17
- OptionsFile.new(Relish.local_options_file).store(@cli_options)
39
+ option = Option.new(@param)
40
+ OptionsFile.new(Relish.local_options_file).store(option.to_hash)
18
41
  end
19
42
 
20
43
  end
@@ -12,12 +12,13 @@ module Relish
12
12
  Option.names << name.to_s
13
13
  end
14
14
 
15
- def usage(str)
16
- HelpText.next_usage = str
15
+ def usage(text)
16
+ HelpText.next_usage = text
17
17
  end
18
18
 
19
- def desc(str)
20
- HelpText.next_description = str
19
+ def desc(text)
20
+ text = text.join("\n") if text.is_a?(Array)
21
+ HelpText.next_description = text
21
22
  end
22
23
 
23
24
  def command(arg, &block)
@@ -4,6 +4,16 @@ module Relish
4
4
 
5
5
  desc 'show this usage'
6
6
  command :default do
7
+ puts <<-TEXT
8
+ A <project> can be scoped by an organization or user handle. For
9
+ example, if an organiztion (rspec) has a project (rspec-core), then
10
+ the <project> would be `rspec/rspec-core`. If a user (justin) has a
11
+ project (my-project), then <project> would be `justin/my-project`.
12
+
13
+ If you leave off the organization or user handle, then it defaults
14
+ to the user (you).
15
+
16
+ TEXT
7
17
  puts "=== Available Commands\n\n"
8
18
  Dsl::HelpText.commands.each do |command, list|
9
19
  list.each {|hash| Formatter.new(command, hash).format }
@@ -0,0 +1,23 @@
1
+ module Relish
2
+ module Command
3
+ module ParamMethods
4
+
5
+ def extract_option
6
+ include?(':') ? split(':')[1] : self
7
+ end
8
+
9
+ def without_option
10
+ split(':')[0]
11
+ end
12
+
13
+ def has_option?
14
+ include?(':')
15
+ end
16
+
17
+ def extract_project_handle
18
+ self && (has_option? ? true : nil) && without_option
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -10,7 +10,7 @@ module Relish
10
10
  usage 'projects:add <org_or_user_handle>/<project_handle>'
11
11
  desc ['add a project',
12
12
  'append :private to make the project private',
13
- 'example: relish projects:add rspec/rspec-core:private'].join("\n")
13
+ 'example: relish projects:add rspec/rspec-core:private']
14
14
  command :add do
15
15
  puts resource['projects'].post(:handle => handle, :private => private?)
16
16
  end
@@ -31,7 +31,7 @@ module Relish
31
31
  end
32
32
 
33
33
  def handle
34
- @param.remove_option
34
+ @param.without_option
35
35
  end
36
36
 
37
37
  def private?
@@ -8,6 +8,7 @@ module Relish
8
8
  class Push < Base
9
9
  option :version
10
10
 
11
+ usage 'push <project>'
11
12
  desc 'push features to relishapp.com'
12
13
  command :default do
13
14
  post files_as_tar_gz
@@ -28,6 +29,10 @@ module Relish
28
29
  end
29
30
  end
30
31
 
32
+ def project
33
+ @param || super()
34
+ end
35
+
31
36
  def files_as_tar_gz
32
37
  stream = StringIO.new
33
38
  begin
@@ -5,6 +5,7 @@ module Relish
5
5
  $stderr.puts(message)
6
6
  exit 1
7
7
  end
8
+ module_function :error
8
9
 
9
10
  end
10
11
  end
@@ -28,6 +28,10 @@ module Relish
28
28
  options == other
29
29
  end
30
30
 
31
+ def merge(other)
32
+ options.merge(other.options)
33
+ end
34
+
31
35
  # Stored options as a hash
32
36
  def options
33
37
  @options ||= current_options
data/relish.gemspec CHANGED
@@ -1,10 +1,10 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "relish"
3
- s.version = "0.1.0"
3
+ s.version = "0.1.1"
4
4
 
5
5
  s.required_rubygems_version = '>= 1.3.5'
6
6
  s.authors = ["Matt Wynne", "Justin Ko"]
7
- s.date = "2010-11-13"
7
+ s.date = "2010-11-15"
8
8
  s.description = %q{Client gem for http://relishapp.com}
9
9
  s.email = "jko170@gmail.com"
10
10
 
@@ -3,40 +3,6 @@ require 'spec_helper'
3
3
  module Relish
4
4
  module Command
5
5
  describe Base do
6
-
7
- describe "#project" do
8
- context 'passed in command line' do
9
- let(:base) { described_class.new(["--project", 'rspec-core']) }
10
-
11
- it 'returns the value' do
12
- base.project.should eq('rspec-core')
13
- end
14
- end
15
-
16
- context 'contained in the local options file' do
17
- let(:base) { described_class.new }
18
-
19
- before do
20
- OptionsFile.stub(:new).with(
21
- Relish.local_options_file
22
- ).and_return({'project' => 'rspec-core'})
23
- end
24
-
25
- it 'returns the value' do
26
- base.project.should eq('rspec-core')
27
- end
28
- end
29
-
30
- context 'not passed in command line' do
31
- let(:base) { described_class.new }
32
-
33
- context 'and options file does not exist' do
34
- it 'returns nil' do
35
- base.project.should be_nil
36
- end
37
- end
38
- end
39
- end
40
6
 
41
7
  describe '#url' do
42
8
  context 'host passed in command line' do
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module Relish
4
+ module Command
5
+ describe ParamMethods do
6
+
7
+ let(:foo_bar) { 'foo:bar'.extend(described_class) }
8
+ let(:foo) { 'foo'.extend(described_class) }
9
+
10
+ describe '#extract_option' do
11
+ specify { foo_bar.extract_option.should eq('bar') }
12
+ specify { foo.extract_option.should eq('foo') }
13
+ end
14
+
15
+ describe '#without_option' do
16
+ specify { foo_bar.without_option.should eq('foo') }
17
+ specify { foo.without_option.should eq('foo') }
18
+ end
19
+
20
+ describe '#has_option?' do
21
+ specify { foo_bar.has_option?.should be_true }
22
+ specify { foo.has_option?.should be_false }
23
+ end
24
+
25
+ describe '#extract_project_handle' do
26
+ specify { foo_bar.extract_project_handle.should eq('foo') }
27
+ specify { foo.extract_project_handle.should be_nil }
28
+ end
29
+
30
+ end
31
+ end
32
+ 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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
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-11-13 00:00:00 -07:00
19
+ date: 2010-11-15 00:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -181,7 +181,6 @@ files:
181
181
  - cucumber.yml
182
182
  - features/help.feature
183
183
  - features/projects.feature
184
- - features/push.feature
185
184
  - features/step_definitions/aruba.rb
186
185
  - features/step_definitions/fake_web_steps.rb
187
186
  - features/step_definitions/relish_steps.rb
@@ -197,9 +196,9 @@ files:
197
196
  - lib/relish/commands/dsl/help_text.rb
198
197
  - lib/relish/commands/dsl/option.rb
199
198
  - lib/relish/commands/help.rb
199
+ - lib/relish/commands/param_methods.rb
200
200
  - lib/relish/commands/projects.rb
201
201
  - lib/relish/commands/push.rb
202
- - lib/relish/core_ext.rb
203
202
  - lib/relish/helpers.rb
204
203
  - lib/relish/options_file.rb
205
204
  - lib/relish/ui.rb
@@ -210,9 +209,9 @@ files:
210
209
  - spec/relish/commands/dsl/command_spec.rb
211
210
  - spec/relish/commands/dsl/help_text_spec.rb
212
211
  - spec/relish/commands/dsl/option_spec.rb
212
+ - spec/relish/commands/param_methods_spec.rb
213
213
  - spec/relish/commands/projects_spec.rb
214
214
  - spec/relish/commands/push_spec.rb
215
- - spec/relish/core_ext_spec.rb
216
215
  - spec/relish/options_file_spec.rb
217
216
  - spec/relish_spec.rb
218
217
  - spec/spec_helper.rb
@@ -256,7 +255,6 @@ summary: Client gem for http://relishapp.com
256
255
  test_files:
257
256
  - features/help.feature
258
257
  - features/projects.feature
259
- - features/push.feature
260
258
  - features/step_definitions/aruba.rb
261
259
  - features/step_definitions/fake_web_steps.rb
262
260
  - features/step_definitions/relish_steps.rb
@@ -267,9 +265,9 @@ test_files:
267
265
  - spec/relish/commands/dsl/command_spec.rb
268
266
  - spec/relish/commands/dsl/help_text_spec.rb
269
267
  - spec/relish/commands/dsl/option_spec.rb
268
+ - spec/relish/commands/param_methods_spec.rb
270
269
  - spec/relish/commands/projects_spec.rb
271
270
  - spec/relish/commands/push_spec.rb
272
- - spec/relish/core_ext_spec.rb
273
271
  - spec/relish/options_file_spec.rb
274
272
  - spec/relish_spec.rb
275
273
  - spec/spec_helper.rb
@@ -1,12 +0,0 @@
1
- @announce
2
- Feature: Push
3
- In order to send my features to relishapp.com
4
- As a Relish user dev
5
- I want a push command
6
-
7
- Background:
8
- Given my API token "1234" is stored
9
-
10
- Scenario: Specify everything at the command-line
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"
@@ -1,15 +0,0 @@
1
- module Relish
2
- module StringExtensions
3
- def extract_option
4
- split(':')[1]
5
- end
6
-
7
- def remove_option
8
- split(':')[0]
9
- end
10
- end
11
- end
12
-
13
- class String
14
- include Relish::StringExtensions
15
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe String do
4
- describe '#extract_option' do
5
- specify { 'foo:bar'.extract_option.should eq('bar') }
6
- end
7
-
8
- describe '#remove_option' do
9
- specify { 'foo:bar'.remove_option.should eq('foo') }
10
- end
11
- end