relish 0.2.0 → 0.2.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.
@@ -1,9 +1,9 @@
1
1
  @announce
2
2
  Feature: Help
3
-
3
+
4
4
  The `relish help` command displays all available commands
5
5
  along with a description of each.
6
-
6
+
7
7
  Scenario: View all available commands with the help command
8
8
  When I successfully run "relish help"
9
9
  Then the output should contain exactly:
@@ -15,7 +15,7 @@ Feature: Help
15
15
 
16
16
  If you leave off the organization or user handle, then it defaults
17
17
  to the user (you).
18
-
18
+
19
19
  === Available Commands
20
20
 
21
21
  help # show this usage
@@ -32,10 +32,12 @@ Feature: Help
32
32
  # example: relish projects:visibility rspec/rspec-core:private
33
33
  projects:rename <project>:<new handle> # rename a project's handle
34
34
  # example: relish projects:rename rspec/rspec-core:rspec-corez
35
- push <project>:<version> # push features to relishapp.com
35
+ push <project>:<version> # push features to a project
36
36
  # <version> is optional
37
37
  # example: relish push rspec/rspec-core
38
38
  # example: relish push rspec/rspec-core:2.0
39
+ push:org <organization handle> # push markdown files to an organization
40
+ # example: relish push:org rspec
39
41
  collab # list the collaborators for a project
40
42
  collab:add <project>:<collaborator handle or email> # add a collaborator to a project
41
43
  # example: relish collab:add rspec/rspec-core:justin
@@ -46,13 +48,13 @@ Feature: Help
46
48
  # example: relish versions:add rspec/rspec-core:2.0
47
49
  versions:remove <project>:<version> # remove a version from a project
48
50
  # example: relish versions:remove rspec/rspec-core:2.0
49
-
51
+
50
52
  """
51
-
53
+
52
54
  Scenario: Specifying no command runs the help command
53
55
  When I successfully run "relish"
54
56
  Then the output should contain "=== Available Commands"
55
-
57
+
56
58
  Scenario: Specifying an unknown command gives an error message
57
59
  When I run "relish baloney"
58
60
  Then it should fail with:
@@ -12,13 +12,13 @@ module Relish
12
12
  class Base
13
13
  include Relish::Helpers
14
14
  extend Dsl
15
-
15
+
16
16
  option :api_token, :default => lambda { get_and_store_api_token }
17
17
  option :host, :default => lambda { Relish.default_host }
18
-
18
+
19
19
  attr_writer :args
20
20
  attr_reader :cli_options
21
-
21
+
22
22
  def initialize(args = [])
23
23
  @args = clean_args(args)
24
24
  @param = get_param.extend(ParamMethods)
@@ -26,17 +26,17 @@ module Relish
26
26
 
27
27
  validate_cli_options
28
28
  end
29
-
29
+
30
30
  def url
31
31
  "http://#{host}/api"
32
32
  end
33
-
33
+
34
34
  def get_param
35
35
  @args.shift if @args.size.odd?
36
36
  end
37
37
 
38
38
  private
39
-
39
+
40
40
  def project
41
41
  merged_options['project'] || error(:project_blank)
42
42
  end
@@ -46,28 +46,28 @@ module Relish
46
46
  global_options_file.store('api_token' => api_token)
47
47
  api_token
48
48
  end
49
-
49
+
50
50
  def get_api_token
51
51
  email, password = ui.get_credentials
52
-
52
+
53
53
  raw_response = resource(:user => email, :password => password)['token'].get
54
54
  String.new(raw_response.to_s)
55
55
  end
56
-
56
+
57
57
  def resource(options = {})
58
58
  options[:user] ||= api_token
59
59
  options[:password] ||= 'X'
60
60
  RestClient::Resource.new(url, options)
61
61
  end
62
-
62
+
63
63
  def clean_args(args)
64
64
  args.inject([]) {|cleaned, arg| cleaned << arg.sub('--', '') }
65
65
  end
66
-
66
+
67
67
  def valid_option_names
68
68
  Dsl::Option.names
69
69
  end
70
-
70
+
71
71
  def validate_cli_options
72
72
  cli_options.keys.each do |option|
73
73
  unless valid_option_names.include?(option.to_s)
@@ -75,11 +75,11 @@ module Relish
75
75
  end
76
76
  end
77
77
  end
78
-
78
+
79
79
  def merged_options
80
80
  @merged_options ||= global_options_file.merge(local_options_file)
81
81
  end
82
-
82
+
83
83
  def global_options_file
84
84
  @global_options ||= OptionsFile.new(Relish.global_options_file)
85
85
  end
@@ -87,11 +87,11 @@ module Relish
87
87
  def local_options_file
88
88
  @local_options ||= OptionsFile.new(Relish.local_options_file)
89
89
  end
90
-
90
+
91
91
  def ui
92
92
  @ui ||= Ui.new
93
93
  end
94
-
94
+
95
95
  def json_parse(response, &block)
96
96
  JSON.parse(response).inject([]) do |parsed_output, hash|
97
97
  parsed_output << block.call(hash)
@@ -99,11 +99,11 @@ module Relish
99
99
  rescue JSON::ParserError
100
100
  response
101
101
  end
102
-
102
+
103
103
  def escape(str)
104
104
  CGI.escape(str)
105
105
  end
106
-
106
+
107
107
  end
108
108
  end
109
109
  end
@@ -3,38 +3,38 @@ module Relish
3
3
  class Collab < Base
4
4
  include ResourceMethods
5
5
  resource_path :memberships
6
-
6
+
7
7
  desc 'list the collaborators for a project'
8
8
  command :default do
9
9
  puts format(resource[resource_path_for_no_option].get(:accept => :json))
10
10
  end
11
-
11
+
12
12
  usage 'collab:add <project>:<collaborator handle or email>'
13
- desc ['add a collaborator to a project',
14
- 'example: relish collab:add rspec/rspec-core:justin']
13
+ desc 'add a collaborator to a project',
14
+ 'example: relish collab:add rspec/rspec-core:justin'
15
15
  command :add do
16
16
  puts resource[resource_path_for_option].post(:handle_or_email => handle_or_email)
17
17
  end
18
-
18
+
19
19
  usage 'collab:remove <project>:<collaborator handle or email>'
20
- desc ['remove a collaborator from a project',
21
- 'example: relish collab:remove rspec/rspec-core:justin']
20
+ desc 'remove a collaborator from a project',
21
+ 'example: relish collab:remove rspec/rspec-core:justin'
22
22
  command :remove do
23
23
  puts resource["#{resource_path_for_option}/#{handle_or_email}"].delete
24
24
  end
25
-
25
+
26
26
  private
27
-
27
+
28
28
  def handle_or_email
29
29
  @param.extract_option
30
30
  end
31
-
31
+
32
32
  def format(response)
33
33
  json_parse(response) do |hash|
34
34
  "#{hash['user']['handle']} (#{hash['user']['email']})"
35
35
  end
36
36
  end
37
-
37
+
38
38
  end
39
39
  end
40
40
  end
@@ -1,22 +1,22 @@
1
1
  module Relish
2
2
  module Command
3
3
  class Config < Base
4
-
4
+
5
5
  class Option
6
6
  VALID_OPTIONS = %w(project)
7
-
7
+
8
8
  def initialize(param)
9
9
  @option, @value = param.split(':')
10
10
  validate_option
11
11
  end
12
-
12
+
13
13
  def validate_option
14
14
  unless VALID_OPTIONS.include?(@option)
15
15
  Relish::Helpers.error "'#{@option}' is not a valid option." +
16
16
  " Valid options: #{VALID_OPTIONS.join(', ')}"
17
17
  end
18
18
  end
19
-
19
+
20
20
  def to_hash
21
21
  {@option => @value}
22
22
  end
@@ -30,16 +30,16 @@ module Relish
30
30
  "No #{Relish.local_options_file} file exists"
31
31
  end)
32
32
  end
33
-
33
+
34
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(', ')}"]
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(', ')}"
38
38
  command :add do
39
39
  option = Option.new(@param)
40
40
  OptionsFile.new(Relish.local_options_file).store(option.to_hash)
41
41
  end
42
-
42
+
43
43
  end
44
44
  end
45
45
  end
@@ -6,21 +6,20 @@ require 'relish/commands/dsl/help_text'
6
6
  module Relish
7
7
  module Command
8
8
  module Dsl
9
-
9
+
10
10
  def option(name, options = {})
11
11
  Option.new(self).define(name, options)
12
12
  Option.names << name.to_s
13
13
  end
14
-
14
+
15
15
  def usage(text)
16
16
  HelpText.next_usage = text
17
17
  end
18
-
19
- def desc(text)
20
- text = text.join("\n") if text.is_a?(Array)
21
- HelpText.next_description = text
18
+
19
+ def desc(*text)
20
+ HelpText.next_description = text.join("\n")
22
21
  end
23
-
22
+
24
23
  def command(arg, &block)
25
24
  case arg
26
25
  when Hash
@@ -31,10 +30,10 @@ module Relish
31
30
  else
32
31
  raise ArgumentError
33
32
  end
34
-
33
+
35
34
  Command.new(self).define(name, &block)
36
35
  end
37
-
36
+
38
37
  end
39
38
  end
40
39
  end
@@ -1,75 +1,75 @@
1
1
  module Relish
2
2
  module Command
3
3
  class Projects < Base
4
-
4
+
5
5
  desc 'list your projects'
6
6
  command :default do
7
7
  puts format(resource['projects'].get(:accept => :json))
8
8
  end
9
-
9
+
10
10
  usage 'projects:add <org or user handle>/<project handle>'
11
- desc ['add a project',
12
- 'append :private to make the project private',
13
- 'example: relish projects:add rspec/rspec-core:private']
11
+ desc 'add a project',
12
+ 'append :private to make the project private',
13
+ 'example: relish projects:add rspec/rspec-core:private'
14
14
  command :add do
15
15
  puts resource['projects'].post(:handle => handle_to_add, :private => private?)
16
16
  end
17
-
17
+
18
18
  usage 'projects:remove <project>'
19
19
  desc 'remove a project'
20
20
  command :remove do
21
21
  puts resource["projects/#{escape(handle_to_remove)}"].delete
22
22
  end
23
-
23
+
24
24
  usage 'projects:visibility <project>:<public or private>'
25
- desc ['set the status of a project',
26
- 'example: relish projects:visibility rspec/rspec-core:private']
25
+ desc 'set the status of a project',
26
+ 'example: relish projects:visibility rspec/rspec-core:private'
27
27
  command :visibility do
28
28
  puts resource["projects/#{escape(handle_to_update)}"].put(
29
29
  :project => { :private => private? }
30
30
  )
31
31
  end
32
-
32
+
33
33
  usage 'projects:rename <project>:<new handle>'
34
- desc ["rename a project's handle",
35
- 'example: relish projects:rename rspec/rspec-core:rspec-corez']
34
+ desc "rename a project's handle",
35
+ 'example: relish projects:rename rspec/rspec-core:rspec-corez'
36
36
  command :rename do
37
37
  puts resource["projects/#{escape(handle_to_update)}"].put(
38
38
  :project => { :handle => rename_handle }
39
39
  )
40
40
  end
41
-
41
+
42
42
  private
43
-
43
+
44
44
  def format(response)
45
- json_parse(response) do |hash|
45
+ json_parse(response) do |hash|
46
46
  result = hash['project']['full_handle']
47
47
  result << " (private)" if hash['project']['private']
48
48
  result
49
49
  end
50
50
  end
51
-
51
+
52
52
  def handle_to_add
53
53
  handle || error(:project_blank)
54
54
  end
55
55
  alias_method :handle_to_update, :handle_to_add
56
-
56
+
57
57
  def handle_to_remove
58
58
  handle || project
59
59
  end
60
-
60
+
61
61
  def handle
62
62
  @param.without_option if @param
63
63
  end
64
-
64
+
65
65
  def rename_handle
66
66
  @param.has_option? ? @param.extract_option : error(:handle_blank)
67
67
  end
68
-
68
+
69
69
  def private?
70
70
  @param.extract_option == 'private'
71
71
  end
72
-
72
+
73
73
  end
74
74
  end
75
75
  end
@@ -4,41 +4,52 @@ require 'stringio'
4
4
  require 'rest_client'
5
5
 
6
6
  module Relish
7
- module Command
7
+ module Command
8
8
  class Push < Base
9
-
9
+
10
10
  usage 'push <project>:<version>'
11
- desc ['push features to relishapp.com',
12
- '<version> is optional',
13
- 'example: relish push rspec/rspec-core',
14
- 'example: relish push rspec/rspec-core:2.0']
11
+ desc 'push features to a project',
12
+ '<version> is optional',
13
+ 'example: relish push rspec/rspec-core',
14
+ 'example: relish push rspec/rspec-core:2.0'
15
15
  command :default do
16
- post files_as_tar_gz
16
+ post files_as_tar_gz, project_params
17
+ end
18
+
19
+ usage 'push:org <organization handle>'
20
+ desc 'push markdown files to an organization',
21
+ 'example: relish push:org rspec'
22
+ command :org do
23
+ post files_as_tar_gz, organization_params
17
24
  end
18
-
25
+
19
26
  private
20
-
21
- def post(tar_gz_data)
22
- resource["pushes?#{parameters}"].post(tar_gz_data,
27
+
28
+ def post(tar_gz_data, params)
29
+ resource["pushes?#{params}"].post(tar_gz_data,
23
30
  :content_type => 'application/x-gzip')
24
31
  puts "sent:\n#{files.join("\n")}"
25
32
  end
26
-
27
- def parameters
33
+
34
+ def project_params
28
35
  "".tap do |str|
29
36
  str << "project_id=#{project}"
30
37
  str << "&version_id=#{version}" if version
31
38
  end
32
39
  end
33
-
40
+
41
+ def organization_params
42
+ "organization_id=#{@param}"
43
+ end
44
+
34
45
  def project
35
46
  (@param.without_option if @param) || super()
36
47
  end
37
-
48
+
38
49
  def version
39
50
  @param.extract_option if @param.has_option?
40
51
  end
41
-
52
+
42
53
  def files_as_tar_gz
43
54
  stream = StringIO.new
44
55
  begin
@@ -52,14 +63,14 @@ module Relish
52
63
  end
53
64
  stream.string
54
65
  end
55
-
66
+
56
67
  def files
57
68
  Dir["features/**/*.{feature,md,markdown}"] +
58
69
  Dir["features/**/.nav"]
59
70
  end
60
-
71
+
61
72
  end
62
-
73
+
63
74
 
64
75
  end
65
76
  end
@@ -3,40 +3,40 @@ module Relish
3
3
  class Versions < Base
4
4
  include ResourceMethods
5
5
  resource_path :versions
6
-
6
+
7
7
  desc 'list the versions for a project'
8
8
  command :default do
9
9
  puts format(resource[resource_path_for_no_option].get(:accept => :json))
10
10
  end
11
11
 
12
12
  usage 'versions:add <project>:<version>'
13
- desc ['add a version to a project',
14
- 'example: relish versions:add rspec/rspec-core:2.0']
13
+ desc 'add a version to a project',
14
+ 'example: relish versions:add rspec/rspec-core:2.0'
15
15
  command :add do
16
16
  puts resource[resource_path_for_option].post(
17
17
  :version => { :name => version_name }
18
18
  )
19
19
  end
20
-
20
+
21
21
  usage 'versions:remove <project>:<version>'
22
- desc ['remove a version from a project',
23
- 'example: relish versions:remove rspec/rspec-core:2.0']
22
+ desc 'remove a version from a project',
23
+ 'example: relish versions:remove rspec/rspec-core:2.0'
24
24
  command :remove do
25
25
  puts resource["#{resource_path_for_option}/#{version_name}"].delete
26
26
  end
27
-
27
+
28
28
  private
29
-
29
+
30
30
  def version_name
31
31
  @param && @param.extract_option || error(:version_blank)
32
32
  end
33
-
33
+
34
34
  def format(response)
35
35
  json_parse(response) do |hash|
36
36
  "#{hash['version']['name']}"
37
37
  end
38
38
  end
39
-
39
+
40
40
  end
41
41
  end
42
42
  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.2.0"
3
+ s.version = "0.2.1"
4
4
 
5
5
  s.required_rubygems_version = '>= 1.3.5'
6
6
  s.authors = ["Matt Wynne", "Justin Ko"]
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.rdoc_options = ["--charset=UTF-8"]
13
13
  s.rubygems_version = "1.3.6"
14
14
  s.summary = %q{Client gem for http://relishapp.com}
15
-
15
+
16
16
  s.require_path = "lib"
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
25
25
  }.each do |lib, version|
26
26
  s.add_runtime_dependency lib, version
27
27
  end
28
-
28
+
29
29
  {
30
30
  'bundler' => '~> 1.0.0',
31
31
  'rake' => '~> 0.8.7',
@@ -3,23 +3,22 @@ require 'spec_helper'
3
3
  module Relish
4
4
  module Command
5
5
  describe Config do
6
-
7
-
6
+
8
7
  describe '#default' do
9
8
  let(:config) { described_class.new }
10
-
9
+
11
10
  context 'with a local options file' do
12
11
  before do
13
12
  File.should_receive(:exists?).and_return(true)
14
13
  IO.should_receive(:read).and_return('options')
15
14
  end
16
-
15
+
17
16
  it 'outputs the contents' do
18
17
  config.should_receive(:puts).with('options')
19
18
  config.default
20
19
  end
21
20
  end
22
-
21
+
23
22
  context 'without a local options file' do
24
23
  it 'outputs the correct message' do
25
24
  config.should_receive(:puts).with('No .relish file exists')
@@ -27,7 +26,7 @@ module Relish
27
26
  end
28
27
  end
29
28
  end
30
-
29
+
31
30
  end
32
31
  end
33
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: 23
5
- prerelease: false
4
+ hash: 21
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Wynne
@@ -212,8 +212,6 @@ files:
212
212
  - spec/relish/commands/dsl/command_spec.rb
213
213
  - spec/relish/commands/dsl/help_text_spec.rb
214
214
  - spec/relish/commands/dsl/option_spec.rb
215
- - spec/relish/commands/projects_spec.rb
216
- - spec/relish/commands/push_spec.rb
217
215
  - spec/relish/error_messages_spec.rb
218
216
  - spec/relish/options_file_spec.rb
219
217
  - spec/relish/param_methods_spec.rb
@@ -252,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
252
250
  requirements: []
253
251
 
254
252
  rubyforge_project:
255
- rubygems_version: 1.3.7
253
+ rubygems_version: 1.4.2
256
254
  signing_key:
257
255
  specification_version: 3
258
256
  summary: Client gem for http://relishapp.com
@@ -269,8 +267,6 @@ test_files:
269
267
  - spec/relish/commands/dsl/command_spec.rb
270
268
  - spec/relish/commands/dsl/help_text_spec.rb
271
269
  - spec/relish/commands/dsl/option_spec.rb
272
- - spec/relish/commands/projects_spec.rb
273
- - spec/relish/commands/push_spec.rb
274
270
  - spec/relish/error_messages_spec.rb
275
271
  - spec/relish/options_file_spec.rb
276
272
  - spec/relish/param_methods_spec.rb
@@ -1,7 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Relish
4
- module Command
5
-
6
- end
7
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Relish
4
- module Command
5
- describe Push do
6
-
7
- describe '#default' do
8
- let(:push) { described_class.new }
9
-
10
- it 'calls #post' do
11
- push.should_receive(:post)
12
- push.default
13
- end
14
- end
15
-
16
- end
17
- end
18
- end