relish 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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