relish 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ @announce
2
+ Feature: Projects
3
+ In order to add and delete projects
4
+ As a Relish user
5
+ I want to use the projects command
6
+
7
+ # Background:
8
+ # Given my API token "1234" is stored
9
+ #
10
+ # Scenario: Listing all projects
11
+ # When I run relish projects --host localhost:1234
12
+ # Then it should GET to "http://localhost:1234/api/projects?api_token=1234"
13
+ #
14
+ # Scenario: Adding a project
15
+ # When I run relish projects:add rspec-core --host localhost:1234
16
+ # Then it should POST to "http://localhost:1234/api/projects?name=rspec-core&api_token=1234"
@@ -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
- When it should POST to "http://localhost:1234/pushes?project_id=p&api_token=1234"
12
+ Then it should POST to "http://localhost:1234/api/pushes?project_id=p&api_token=1234"
@@ -2,7 +2,7 @@ require 'fake_web'
2
2
  FakeWeb.allow_net_connect = false
3
3
  FakeWeb.register_uri(:any, /.*/, :body => "Faked HTTP response")
4
4
 
5
- When /^it should POST to "http:\/\/localhost:1234([^"]*)"$/ do |path|
5
+ Then /^it should POST to "http:\/\/localhost:1234([^"]*)"$/ do |path|
6
6
  request = FakeWeb.last_request || raise("Fakeweb did not record a request.")
7
7
  request.path.should == path
8
8
  end
@@ -1,4 +1,7 @@
1
1
  $:.unshift(File.dirname(__FILE__) + '/../../lib')
2
2
  require 'relish/command'
3
3
 
4
- Relish::Command::Base::GLOBAL_OPTIONS_FILE = '~/.relish'
4
+ Relish::Command::Base.class_eval do
5
+ remove_const(:GLOBAL_OPTIONS_FILE)
6
+ const_set(:GLOBAL_OPTIONS_FILE, '~/.relish')
7
+ end
@@ -1,5 +1,8 @@
1
1
  require 'relish/commands/base'
2
2
  require 'relish/commands/push'
3
+ require 'relish/commands/config'
4
+ require 'relish/commands/projects'
5
+ require 'relish/commands/help'
3
6
 
4
7
  module Relish
5
8
  module Command
@@ -7,10 +7,11 @@ module Relish
7
7
  GLOBAL_OPTIONS_FILE = File.join(File.expand_path('~'), '.relish')
8
8
  LOCAL_OPTIONS_FILE = '.relish'
9
9
 
10
- attr_reader :args
10
+ attr_accessor :args
11
11
 
12
- def initialize(args)
12
+ def initialize(args = [])
13
13
  @args = args
14
+ @param = get_param
14
15
  @options = get_options
15
16
  end
16
17
 
@@ -22,14 +23,22 @@ module Relish
22
23
  @options['--project'] || @options['-p'] || parsed_options_file['project']
23
24
  end
24
25
 
25
- def host
26
- @options['--host'] || DEFAULT_HOST
26
+ def url
27
+ "http://#{@options['--host'] || DEFAULT_HOST}/api"
28
+ end
29
+
30
+ def resource
31
+ RestClient::Resource.new(url)
27
32
  end
28
33
 
29
34
  def api_token
30
35
  parsed_options_file['api_token']
31
36
  end
32
37
 
38
+ def get_param
39
+ args.shift if args.size.odd?
40
+ end
41
+
33
42
  def get_options
34
43
  parsed_options_file.merge(Hash[*args])
35
44
  end
@@ -3,6 +3,15 @@ module Relish
3
3
  class Config < Base
4
4
 
5
5
  def default
6
+ show
7
+ end
8
+
9
+ def show
10
+ puts(if File.exists?(LOCAL_OPTIONS_FILE)
11
+ IO.read(LOCAL_OPTIONS_FILE)
12
+ else
13
+ "No #{LOCAL_OPTIONS_FILE} file exists"
14
+ end)
6
15
  end
7
16
 
8
17
  end
@@ -0,0 +1,32 @@
1
+ require 'yaml'
2
+
3
+ module Relish
4
+ module Command
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
+
16
+ def default
17
+ puts "This is the prefunctory help message for the relish gem."
18
+
19
+ puts "Commands:"
20
+ Help.command_help.each do |command, help|
21
+ message = "relish #{command}".ljust(max_command_length) +
22
+ " # " + help
23
+ puts message
24
+ end
25
+ end
26
+
27
+ def max_command_length
28
+ Help.command_help.keys.map { |c| c.to_s.length }.max
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+
4
+ module Relish
5
+ module Command
6
+ class Projects < Base
7
+
8
+ def default
9
+ list
10
+ end
11
+
12
+ def list
13
+ response = resource['projects'].get(
14
+ :params => {:api_token => api_token}, :accept => :json
15
+ )
16
+ puts format(response)
17
+ rescue RestClient::Exception => exception
18
+ warn exception.response
19
+ exit 1
20
+ end
21
+
22
+ def format(response)
23
+ json = JSON.parse(response)
24
+ json.map {|h| h['project']['slug']}.join("\n")
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -3,9 +3,12 @@ require 'zlib'
3
3
  require 'archive/tar/minitar'
4
4
  require 'stringio'
5
5
  require 'rest_client'
6
+ require 'relish/commands/help'
6
7
 
7
8
  module Relish
8
9
  module Command
10
+ Help.for_command(:push, "push your features to relishapp.com")
11
+
9
12
  class Push < Base
10
13
 
11
14
  def default
@@ -17,17 +20,16 @@ module Relish
17
20
  end
18
21
 
19
22
  def post(tar_gz_data)
20
- resource = RestClient::Resource.new(url)
21
- resource.post(tar_gz_data, :content_type => 'application/x-gzip')
23
+ resource[parameters].post(tar_gz_data, :content_type => 'application/x-gzip')
22
24
  puts "sent:\n#{files.join("\n")}"
23
25
  rescue RestClient::Exception => exception
24
26
  warn exception.response
25
27
  exit 1
26
28
  end
27
29
 
28
- def url
30
+ def parameters
29
31
  "".tap do |str|
30
- str << "http://#{host}/pushes?"
32
+ str << "pushes?"
31
33
  str << "creator_id=#{organization}&" if organization
32
34
  str << "project_id=#{project}&"
33
35
  str << "version_id=#{version}&" if version
@@ -58,5 +60,8 @@ module Relish
58
60
  end
59
61
 
60
62
  end
63
+
64
+
61
65
  end
62
- end
66
+ end
67
+
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.2"
3
+ s.version = "0.0.4"
4
4
 
5
5
  s.required_rubygems_version = '>= 1.3.5'
6
6
  s.authors = ["Matt Wynne", "Justin Ko"]
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
21
21
  {
22
22
  'archive-tar-minitar' => '~> 0.5.2',
23
23
  'rest-client' => '~> 1.6.1',
24
+ 'json' => '~> 1.4.6'
24
25
  }.each do |lib, version|
25
26
  s.add_runtime_dependency lib, version
26
27
  end
@@ -9,4 +9,18 @@ describe Relish::Command do
9
9
  Relish::Command.run('push', [])
10
10
  end
11
11
 
12
+ it "recognizes the 'config' command" do
13
+ config = double
14
+ config.should_receive(:default)
15
+ Relish::Command::Config.should_receive(:new).with([]).and_return(config)
16
+ Relish::Command.run('config', [])
17
+ end
18
+
19
+ it "recognizes the 'projects' command" do
20
+ projects = double
21
+ projects.should_receive(:default)
22
+ Relish::Command::Projects.should_receive(:new).with([]).and_return(projects)
23
+ Relish::Command.run('projects', [])
24
+ end
25
+
12
26
  end
@@ -24,7 +24,7 @@ module Relish
24
24
  end
25
25
 
26
26
  context 'contained in the options file' do
27
- let(:base) { described_class.new([]) }
27
+ let(:base) { described_class.new }
28
28
 
29
29
  before do
30
30
  base.stub(:parsed_options_file).and_return({meth.to_s => name})
@@ -36,7 +36,7 @@ module Relish
36
36
  end
37
37
 
38
38
  context 'not passed in command line' do
39
- let(:base) { described_class.new([]) }
39
+ let(:base) { described_class.new }
40
40
 
41
41
  context 'and options file does not exist' do
42
42
  it 'returns nil' do
@@ -47,26 +47,34 @@ module Relish
47
47
  end
48
48
  end
49
49
 
50
- describe '#host' do
51
- context 'passed in command line' do
50
+ describe '#url' do
51
+ context 'host passed in command line' do
52
52
  let(:base) { described_class.new(['--host', 'test.com']) }
53
-
54
- it 'returns test.com' do
55
- base.host.should eq('test.com')
56
- end
53
+ specify { base.url.should eq('http://test.com/api') }
57
54
  end
58
55
 
59
- context 'not passed in command line' do
60
- let(:base) { described_class.new([]) }
56
+ context 'host not passed in command line' do
57
+ let(:base) { described_class.new }
61
58
 
62
59
  it 'returns the default host' do
63
- base.host.should eq(Base::DEFAULT_HOST)
60
+ base.url.should eq("http://#{Base::DEFAULT_HOST}/api")
64
61
  end
65
62
  end
66
63
  end
67
64
 
65
+ describe '#resource' do
66
+ let(:base) { described_class.new }
67
+
68
+ before do
69
+ base.should_receive(:url).and_return('url')
70
+ RestClient::Resource.should_receive(:new).with('url')
71
+ end
72
+
73
+ specify { base.resource }
74
+ end
75
+
68
76
  describe '#api_token' do
69
- let(:base) { described_class.new([]) }
77
+ let(:base) { described_class.new }
70
78
  let(:options) { {'api_token' => '12345'} }
71
79
 
72
80
  before do
@@ -78,14 +86,41 @@ module Relish
78
86
  end
79
87
  end
80
88
 
89
+ describe '#get_param' do
90
+
91
+ context 'given a command param' do
92
+ let(:base) do
93
+ base = described_class.new
94
+ base.args = ['param', '--project', 'rspec-core']
95
+ base
96
+ end
97
+
98
+ it 'returns the first arg' do
99
+ base.get_param.should eq('param')
100
+ end
101
+ end
102
+
103
+ context 'not given a command param' do
104
+ let(:base) do
105
+ base = described_class.new
106
+ base.args = ['--project', 'rspec-core']
107
+ base
108
+ end
109
+
110
+ it 'returns nil' do
111
+ base.get_param.should be_nil
112
+ end
113
+ end
114
+ end
115
+
81
116
  describe '#get_options' do
82
- let(:base) { described_class.new(['--project', 'rspec-core']) }
83
117
  let(:options) { {'project' => 'rspec-core'} }
118
+ let(:base) { described_class.new(['--project', 'rspec-core']) }
84
119
 
85
120
  before do
86
121
  base.should_receive(:parsed_options_file).and_return(options)
87
122
  end
88
-
123
+
89
124
  it 'combines the args and options file' do
90
125
  base.get_options.should eq(
91
126
  {'project' => 'rspec-core', '--project' => 'rspec-core'}
@@ -94,7 +129,7 @@ module Relish
94
129
  end
95
130
 
96
131
  describe '#parsed_options_file' do
97
- let(:base) { described_class.new([]) }
132
+ let(:base) { described_class.new }
98
133
 
99
134
  context 'with options file that exists' do
100
135
  let(:options) do
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ module Relish
4
+ module Command
5
+ describe Config do
6
+
7
+ describe '#default' do
8
+ let(:config) { described_class.new }
9
+
10
+ it 'calls #show' do
11
+ config.should_receive(:show)
12
+ config.default
13
+ end
14
+ end
15
+
16
+ describe '#show' do
17
+ let(:config) { described_class.new }
18
+
19
+ context 'with a local options file' do
20
+ before do
21
+ File.should_receive(:exists?).and_return(true)
22
+ IO.should_receive(:read).and_return('options')
23
+ end
24
+
25
+ it 'outputs the contents' do
26
+ config.should_receive(:puts).with('options')
27
+ config.show
28
+ end
29
+ end
30
+
31
+ context 'without a local options file' do
32
+ it 'outputs the correct message' do
33
+ config.should_receive(:puts).with('No .relish file exists')
34
+ config.show
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module Relish
4
+ module Command
5
+ describe Projects do
6
+
7
+ describe '#default' do
8
+ let(:projects) { described_class.new }
9
+
10
+ it 'calls #list' do
11
+ projects.should_receive(:list)
12
+ projects.default
13
+ end
14
+ end
15
+
16
+ # describe '#url' do
17
+ # context 'given a name' do
18
+ # let(:projects) { described_class.new(['rspec-core']) }
19
+
20
+
21
+
22
+ end
23
+ end
24
+ end
@@ -5,7 +5,7 @@ module Relish
5
5
  describe Push do
6
6
 
7
7
  describe '#default' do
8
- let(:push) { described_class.new([]) }
8
+ let(:push) { described_class.new }
9
9
 
10
10
  it 'calls #run' do
11
11
  push.should_receive(:run)
@@ -13,18 +13,18 @@ module Relish
13
13
  end
14
14
  end
15
15
 
16
- describe '#url' do
16
+ describe '#parameters' do
17
17
  before do
18
18
  push.should_receive(:project).and_return('rspec')
19
19
  push.should_receive(:api_token).and_return('abc')
20
20
  end
21
21
 
22
22
  context 'without version' do
23
- let(:push) { described_class.new([]) }
23
+ let(:push) { described_class.new }
24
24
 
25
25
  specify do
26
- push.url.should eq(
27
- "http://relishapp.com/pushes?project_id=rspec&api_token=abc"
26
+ push.parameters.should eq(
27
+ "pushes?project_id=rspec&api_token=abc"
28
28
  )
29
29
  end
30
30
  end
@@ -33,8 +33,8 @@ module Relish
33
33
  let(:push) { described_class.new(['--version', 'one']) }
34
34
 
35
35
  specify do
36
- push.url.should eq(
37
- "http://relishapp.com/pushes?project_id=rspec&version_id=one&api_token=abc"
36
+ push.parameters.should eq(
37
+ "pushes?project_id=rspec&version_id=one&api_token=abc"
38
38
  )
39
39
  end
40
40
  end
@@ -47,19 +47,19 @@ module Relish
47
47
  end
48
48
 
49
49
  context 'with --version not in @options' do
50
- let(:push) { described_class.new([]) }
50
+ let(:push) { described_class.new }
51
51
  specify { push.version.should be_nil }
52
52
  end
53
53
  end
54
54
 
55
55
  describe '#files_as_tar_gz' do
56
- let(:push) { described_class.new([]) }
56
+ let(:push) { described_class.new }
57
57
  specify { expect { push.files_as_tar_gz }.to_not raise_exception }
58
58
  specify { push.files_as_tar_gz.should be_a(String) }
59
59
  end
60
60
 
61
61
  describe '#files' do
62
- let(:push) { described_class.new([]) }
62
+ let(:push) { described_class.new }
63
63
  specify { expect { push.files }.to_not raise_exception }
64
64
  specify { push.files.should be_a(Array) }
65
65
  end
data/spec/spec_helper.rb CHANGED
@@ -8,6 +8,11 @@ RSpec.configure do |config|
8
8
  config.color_enabled = true
9
9
 
10
10
  config.before(:suite) do
11
- Relish::Command::Base::GLOBAL_OPTIONS_FILE = '~/.relish'
11
+
12
+ Relish::Command::Base.class_eval do
13
+ remove_const(:GLOBAL_OPTIONS_FILE)
14
+ const_set(:GLOBAL_OPTIONS_FILE, '~/.relish')
15
+ end
16
+
12
17
  end
13
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: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Wynne
@@ -20,9 +20,25 @@ date: 2010-09-23 00:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
- name: rest-client
23
+ name: json
24
24
  prerelease: false
25
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 11
31
+ segments:
32
+ - 1
33
+ - 4
34
+ - 6
35
+ version: 1.4.6
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rest-client
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
26
42
  none: false
27
43
  requirements:
28
44
  - - ~>
@@ -34,11 +50,11 @@ dependencies:
34
50
  - 1
35
51
  version: 1.6.1
36
52
  type: :runtime
37
- version_requirements: *id001
53
+ version_requirements: *id002
38
54
  - !ruby/object:Gem::Dependency
39
55
  name: archive-tar-minitar
40
56
  prerelease: false
41
- requirement: &id002 !ruby/object:Gem::Requirement
57
+ requirement: &id003 !ruby/object:Gem::Requirement
42
58
  none: false
43
59
  requirements:
44
60
  - - ~>
@@ -50,11 +66,11 @@ dependencies:
50
66
  - 2
51
67
  version: 0.5.2
52
68
  type: :runtime
53
- version_requirements: *id002
69
+ version_requirements: *id003
54
70
  - !ruby/object:Gem::Dependency
55
71
  name: fakeweb
56
72
  prerelease: false
57
- requirement: &id003 !ruby/object:Gem::Requirement
73
+ requirement: &id004 !ruby/object:Gem::Requirement
58
74
  none: false
59
75
  requirements:
60
76
  - - ~>
@@ -66,11 +82,11 @@ dependencies:
66
82
  - 0
67
83
  version: 1.3.0
68
84
  type: :development
69
- version_requirements: *id003
85
+ version_requirements: *id004
70
86
  - !ruby/object:Gem::Dependency
71
87
  name: rake
72
88
  prerelease: false
73
- requirement: &id004 !ruby/object:Gem::Requirement
89
+ requirement: &id005 !ruby/object:Gem::Requirement
74
90
  none: false
75
91
  requirements:
76
92
  - - ~>
@@ -82,11 +98,11 @@ dependencies:
82
98
  - 7
83
99
  version: 0.8.7
84
100
  type: :development
85
- version_requirements: *id004
101
+ version_requirements: *id005
86
102
  - !ruby/object:Gem::Dependency
87
103
  name: rspec
88
104
  prerelease: false
89
- requirement: &id005 !ruby/object:Gem::Requirement
105
+ requirement: &id006 !ruby/object:Gem::Requirement
90
106
  none: false
91
107
  requirements:
92
108
  - - ~>
@@ -98,11 +114,11 @@ dependencies:
98
114
  - 0
99
115
  version: 2.0.0
100
116
  type: :development
101
- version_requirements: *id005
117
+ version_requirements: *id006
102
118
  - !ruby/object:Gem::Dependency
103
119
  name: aruba
104
120
  prerelease: false
105
- requirement: &id006 !ruby/object:Gem::Requirement
121
+ requirement: &id007 !ruby/object:Gem::Requirement
106
122
  none: false
107
123
  requirements:
108
124
  - - ~>
@@ -114,11 +130,11 @@ dependencies:
114
130
  - 2
115
131
  version: 0.2.2
116
132
  type: :development
117
- version_requirements: *id006
133
+ version_requirements: *id007
118
134
  - !ruby/object:Gem::Dependency
119
135
  name: bundler
120
136
  prerelease: false
121
- requirement: &id007 !ruby/object:Gem::Requirement
137
+ requirement: &id008 !ruby/object:Gem::Requirement
122
138
  none: false
123
139
  requirements:
124
140
  - - ~>
@@ -130,11 +146,11 @@ dependencies:
130
146
  - 0
131
147
  version: 1.0.0
132
148
  type: :development
133
- version_requirements: *id007
149
+ version_requirements: *id008
134
150
  - !ruby/object:Gem::Dependency
135
151
  name: cucumber
136
152
  prerelease: false
137
- requirement: &id008 !ruby/object:Gem::Requirement
153
+ requirement: &id009 !ruby/object:Gem::Requirement
138
154
  none: false
139
155
  requirements:
140
156
  - - ~>
@@ -146,7 +162,7 @@ dependencies:
146
162
  - 1
147
163
  version: 0.9.1
148
164
  type: :development
149
- version_requirements: *id008
165
+ version_requirements: *id009
150
166
  description: Client gem for http://relishapp.com
151
167
  email: jko170@gmail.com
152
168
  executables:
@@ -163,6 +179,7 @@ files:
163
179
  - Rakefile
164
180
  - bin/relish
165
181
  - cucumber.yml
182
+ - features/projects.feature
166
183
  - features/push.feature
167
184
  - features/step_definitions/aruba.rb
168
185
  - features/step_definitions/fake_web_steps.rb
@@ -171,10 +188,14 @@ files:
171
188
  - lib/relish/command.rb
172
189
  - lib/relish/commands/base.rb
173
190
  - lib/relish/commands/config.rb
191
+ - lib/relish/commands/help.rb
192
+ - lib/relish/commands/projects.rb
174
193
  - lib/relish/commands/push.rb
175
194
  - relish.gemspec
176
195
  - spec/relish/command_spec.rb
177
196
  - spec/relish/commands/base_spec.rb
197
+ - spec/relish/commands/config_spec.rb
198
+ - spec/relish/commands/projects_spec.rb
178
199
  - spec/relish/commands/push_spec.rb
179
200
  - spec/spec_helper.rb
180
201
  has_rdoc: true
@@ -214,6 +235,7 @@ signing_key:
214
235
  specification_version: 3
215
236
  summary: Client gem for http://relishapp.com
216
237
  test_files:
238
+ - features/projects.feature
217
239
  - features/push.feature
218
240
  - features/step_definitions/aruba.rb
219
241
  - features/step_definitions/fake_web_steps.rb
@@ -221,5 +243,7 @@ test_files:
221
243
  - features/support/env.rb
222
244
  - spec/relish/command_spec.rb
223
245
  - spec/relish/commands/base_spec.rb
246
+ - spec/relish/commands/config_spec.rb
247
+ - spec/relish/commands/projects_spec.rb
224
248
  - spec/relish/commands/push_spec.rb
225
249
  - spec/spec_helper.rb