singularity_client 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,10 +18,11 @@ Or install it yourself as:
18
18
 
19
19
  ## Configuration
20
20
 
21
- The singularity client configures itself off a `.singularity.yml` file.
21
+ Configuration options may be declared from the command line,
22
+ or defined in a `.singularity.yml` file.
22
23
 
23
24
  By default, the tool will start looking for a `.singularity.yml` in your current working directory,
24
- and will work its way up to the root directory. Specify a path via the `--config` command line option.
25
+ and will work its way up to the root directory. Specify a file via the `--config` command line option.
25
26
 
26
27
  ### Available configurations:
27
28
 
@@ -30,24 +31,28 @@ and will work its way up to the root directory. Specify a path via the `--config
30
31
  <th>Key</th>
31
32
  <th>Description</th>
32
33
  <th>Type</th>
34
+ <th>Required</th>
33
35
  <th>Example</th>
34
36
  </tr>
35
37
  <tr>
36
38
  <td><tt>singularity_url</tt></td>
37
39
  <td>URL for the singularity server</td>
38
40
  <td>String</td>
41
+ <td>Yes</td>
39
42
  <td><tt>'http://singularity.net'</tt></td>
40
43
  </tr>
41
44
  <tr>
42
45
  <td><tt>singularity_port</tt></td>
43
46
  <td>Port the singularity server is operating on</td>
44
47
  <td>String</td>
48
+ <td>Yes</td>
45
49
  <td><tt>'9000'</tt></td>
46
50
  </tr>
47
51
  <tr>
48
52
  <td><tt>github_organization</tt></td>
49
53
  <td>Default github organization to use</td>
50
54
  <td>String</td>
55
+ <td>No</td>
51
56
  <td><tt>'Behance'</tt></td>
52
57
  </tr>
53
58
  </table>
@@ -17,8 +17,15 @@ module SingularityClient
17
17
  pp(JSON.parse(response.body))
18
18
  end
19
19
 
20
- def self.add(config, repo, project)
21
- endpoint = 'config/pull_request'
20
+ ##
21
+ # Add to the singularity config
22
+ # the 'type' parameter can be pull_request or push
23
+ #
24
+ def self.add(config, repo, project, type)
25
+ # This is just to maintain backwards compatability
26
+ type ||= 'pull_request'
27
+
28
+ endpoint = (type == 'push') ? 'config/push' : 'config/pull_request'
22
29
  post_data = {
23
30
  organization: config.organization,
24
31
  repo: repo,
@@ -10,7 +10,7 @@ module SingularityClient
10
10
 
11
11
  def initialize(*args)
12
12
  super
13
- @config_hash = SingularityClient::Config.new(options)
13
+ @cli_options = options
14
14
  end
15
15
 
16
16
  # rubocop:disable AlignHash
@@ -25,21 +25,44 @@ module SingularityClient
25
25
 
26
26
  desc 'config', 'Get the current singularity config object'
27
27
  def config
28
- SingularityClient::API.config(config_hash)
28
+ run(:config)
29
29
  end
30
30
 
31
31
  desc 'add REPO_NAME PROJECT_NAME', 'Add a github repository to singularity'
32
+ long_desc 'This will add both pull requests, and pushes, to singularity'
32
33
  method_option :github_organization, aliases: '-o', type: :string,
33
34
  desc: 'Override the default github organization'
34
35
  def add(repo, project)
35
- SingularityClient::API.add(config_hash, repo, project)
36
+ run(:add, repo, project, 'pull_request')
37
+ run(:add, repo, project, 'push')
38
+ end
39
+
40
+ desc 'addPull REPO_NAME PROJECT_NAME', 'Add repo pulls to singularity'
41
+ method_option :github_organization, aliases: '-o', type: :string,
42
+ desc: 'Override the default github organization'
43
+ def add_pull(repo, project)
44
+ run(:add, repo, project, 'pull_request')
45
+ end
46
+
47
+ desc 'addPush REPO_NAME PROJECT_NAME', 'Add repo pushes to singularity'
48
+ method_option :github_organization, aliases: '-o', type: :string,
49
+ desc: 'Override the default github organization'
50
+ def add_push(repo, project)
51
+ run(:add, repo, project, 'push')
36
52
  end
37
53
 
38
54
  desc 'comment REPO_NAME PR_NUM COMMENT', 'Write comment to a pull request'
39
55
  method_option :github_organization, aliases: '-o', type: :string,
40
56
  desc: 'Override the default github organization'
41
57
  def comment(repo, pr, comment)
42
- SingularityClient::API.comment(config_hash, repo, pr, comment)
58
+ run(:comment, repo, pr, comment)
59
+ end
60
+
61
+ private
62
+
63
+ def run(action, *args)
64
+ config = SingularityClient::Config.new(@cli_options)
65
+ SingularityClient::API.send(action, config, *args)
43
66
  end
44
67
  end
45
68
  end
@@ -6,16 +6,15 @@ require 'pathname'
6
6
  module SingularityClient
7
7
  # Wrapper around the config object
8
8
  class Config
9
- DOTFILE = '.singularity.yml'
10
-
11
9
  attr_accessor :options
12
10
 
13
- def initialize(inputs)
14
- config_file = inputs['config'] || find_config_file('.')
15
- @options = load_from_file(config_file).merge(inputs)
11
+ def initialize(inputs = {})
12
+ @options = ConfigLoader.load_from_file(inputs['config'], inputs['debug'])
13
+ @options = @options.merge(inputs)
16
14
 
17
- puts "DEBUG: Using configuration from #{config_file}" if debug
18
15
  puts "DEBUG: Current configuration: #{@options}" if debug
16
+
17
+ validate_config
19
18
  end
20
19
 
21
20
  def base_uri
@@ -27,22 +26,28 @@ module SingularityClient
27
26
  end
28
27
 
29
28
  def debug
30
- @options.key?('debug')
29
+ @options.key? 'debug'
31
30
  end
32
31
 
33
32
  private
34
33
 
35
- def find_config_file(dir)
36
- Pathname.new(File.expand_path(dir)).ascend do |path|
37
- file = File.join(path.to_s, DOTFILE)
38
- return file if File.exist?(file)
34
+ def validate_config
35
+ required_fields = %w(
36
+ singularity_url
37
+ singularity_port
38
+ )
39
+
40
+ required_fields.all? do |field|
41
+ if @options.key? field
42
+ true
43
+ else
44
+ fail <<-ERR.gsub(/^[\s\t]*/, '').gsub(/[\s\t]*\n/, ' ').strip
45
+ #{field} not defined. Please see
46
+ https://github.com/behance/singularity_client#configuration
47
+ for configuration options
48
+ ERR
49
+ end
39
50
  end
40
-
41
- fail 'Could not find .singularity.yml'
42
- end
43
-
44
- def load_from_file(file)
45
- YAML.load_file(file)
46
51
  end
47
52
  end
48
53
  end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+ require 'pathname'
5
+
6
+ module SingularityClient
7
+ # Wrapper around the config object
8
+ class ConfigLoader
9
+ DOTFILE = '.singularity.yml'
10
+
11
+ def self.load_from_file(file = false, debug = false)
12
+ # If file is defined don't look for one, else find one
13
+ file = find_config_file('.', debug) unless file
14
+
15
+ # If no config file passed in, and none found, return empty hash
16
+ file ? YAML.load_file(file) : {}
17
+ end
18
+
19
+ def self.find_config_file(dir, debug)
20
+ Pathname.new(File.expand_path(dir)).ascend do |path|
21
+ file = File.join(path.to_s, DOTFILE)
22
+ if File.exist?(file)
23
+ puts "DEBUG: Using configuration from #{file}" if debug
24
+ return file
25
+ end
26
+ end
27
+
28
+ puts 'DEBUG: Could not find .singularity.yml' if debug
29
+ end
30
+ end
31
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version
4
4
  module SingularityClient
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
@@ -3,3 +3,4 @@
3
3
  require 'singularity_client/version'
4
4
  require 'singularity_client/api'
5
5
  require 'singularity_client/config'
6
+ require 'singularity_client/config_loader'
@@ -45,15 +45,41 @@ describe SingularityClient::API do
45
45
  end
46
46
 
47
47
  describe '.add' do
48
- subject(:add) do
49
- SingularityClient::API.add(config_obj, 'test_repo', 'test_project')
48
+
49
+ describe 'Adding a pull_request' do
50
+ subject(:add) do
51
+ SingularityClient::API.add(config_obj,
52
+ 'test_repo',
53
+ 'test_project',
54
+ 'pull_request'
55
+ )
56
+ end
57
+
58
+ describe 'when it receives a succesful response' do
59
+ it 'it returns success!' do
60
+ VCR.use_cassette('addPull') do
61
+ expect(STDOUT).to receive(:puts).with('success!')
62
+ add
63
+ end
64
+ end
65
+ end
50
66
  end
51
67
 
52
- describe 'when it receives a succesful response' do
53
- it 'it returns success!' do
54
- VCR.use_cassette('add') do
55
- expect(STDOUT).to receive(:puts).with('success!')
56
- add
68
+ describe 'Adding a push' do
69
+ subject(:add) do
70
+ SingularityClient::API.add(config_obj,
71
+ 'test_repo',
72
+ 'test_project',
73
+ 'push'
74
+ )
75
+ end
76
+
77
+ describe 'when it receives a succesful response' do
78
+ it 'it returns success!' do
79
+ VCR.use_cassette('addPush') do
80
+ expect(STDOUT).to receive(:puts).with('success!')
81
+ add
82
+ end
57
83
  end
58
84
  end
59
85
  end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SingularityClient::ConfigLoader do
6
+ describe '.load_from_file' do
7
+ filepath = 'test/path'
8
+ config = { key: 'value' }
9
+
10
+ describe 'when filepath is provided' do
11
+ it 'loads the provided file' do
12
+ expect(SingularityClient::ConfigLoader)
13
+ .to_not receive(:find_config_file)
14
+
15
+ expect(YAML).to receive(:load_file)
16
+ .with(filepath)
17
+ .and_return(config)
18
+
19
+ expect(
20
+ SingularityClient::ConfigLoader.load_from_file(filepath, false)
21
+ ).to eq(config)
22
+ end
23
+ end
24
+
25
+ describe 'when filepath is not provided' do
26
+ describe 'and a .singularity.yml exists' do
27
+ it 'loads .singularity.yml' do
28
+ expect(SingularityClient::ConfigLoader.load_from_file).to eq(
29
+ 'singularity_url' => 'http://mergeatron.dev-be-aws.net',
30
+ 'singularity_port' => '3306',
31
+ 'github_organization' => 'BehanceOps'
32
+ )
33
+ end
34
+ end
35
+
36
+ describe 'and no singularity.yml exists' do
37
+ it 'returns an empty hash' do
38
+ expect(File).to receive(:exist?)
39
+ .at_least(:once)
40
+ .with(/.*\/.singularity.yml/)
41
+ .and_return(false)
42
+
43
+ expect(SingularityClient::ConfigLoader.load_from_file).to eq({})
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -4,16 +4,20 @@ require 'spec_helper'
4
4
 
5
5
  describe SingularityClient::Config do
6
6
  describe '.initialize' do
7
- describe 'when no .singularity.yml found' do
8
- it 'raises an exception' do
9
- expect(File).to receive(:exist?)
10
- .at_least(:once)
11
- .with(/.*\/.singularity.yml/)
12
- .and_return(false)
13
-
14
- expect { SingularityClient::Config.new({}) }
15
- .to raise_error(RuntimeError, 'Could not find .singularity.yml')
16
- end
7
+ it 'raises an exception if validation fails' do
8
+ expect(File).to receive(:exist?)
9
+ .at_least(:once)
10
+ .with(/.*\/.singularity.yml/)
11
+ .and_return(false)
12
+
13
+ error = <<-ERR.gsub(/^[\s\t]*/, '').gsub(/[\s\t]*\n/, ' ').strip
14
+ singularity_port not defined. Please see
15
+ https://github.com/behance/singularity_client#configuration
16
+ for configuration options
17
+ ERR
18
+ expect do
19
+ SingularityClient::Config.new('singularity_url' => 'test.url')
20
+ end .to raise_error(RuntimeError, error)
17
21
  end
18
22
  end
19
23
 
data/spec/spec_helper.rb CHANGED
@@ -4,6 +4,7 @@ if ENV['COVERAGE']
4
4
  require 'simplecov'
5
5
  SimpleCov.start do
6
6
  add_filter '/spec/'
7
+ add_filter '/.vendor/'
7
8
  end
8
9
  end
9
10
 
@@ -19,12 +19,12 @@ http_interactions:
19
19
  Content-Length:
20
20
  - '16'
21
21
  Date:
22
- - Mon, 02 Jun 2014 20:58:24 GMT
22
+ - Wed, 18 Jun 2014 22:58:24 GMT
23
23
  Connection:
24
24
  - keep-alive
25
25
  body:
26
26
  encoding: US-ASCII
27
27
  string: ! '{"success":true}'
28
- http_version:
29
- recorded_at: Mon, 02 Jun 2014 20:58:24 GMT
28
+ http_version:
29
+ recorded_at: Wed, 18 Jun 2014 22:58:23 GMT
30
30
  recorded_with: VCR 2.9.2
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://mergeatron.dev-be-aws.net:3306/config/push
6
+ body:
7
+ encoding: US-ASCII
8
+ string: organization=some_org&repo=test_repo&project=test_project
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ X-Powered-By:
16
+ - Express
17
+ Content-Type:
18
+ - application/json
19
+ Content-Length:
20
+ - '16'
21
+ Date:
22
+ - Wed, 18 Jun 2014 22:58:24 GMT
23
+ Connection:
24
+ - keep-alive
25
+ body:
26
+ encoding: US-ASCII
27
+ string: ! '{"success":true}'
28
+ http_version:
29
+ recorded_at: Wed, 18 Jun 2014 22:58:23 GMT
30
+ recorded_with: VCR 2.9.2
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: singularity_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-09 00:00:00.000000000 Z
12
+ date: 2014-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -175,14 +175,17 @@ files:
175
175
  - lib/singularity_client/api.rb
176
176
  - lib/singularity_client/cli.rb
177
177
  - lib/singularity_client/config.rb
178
+ - lib/singularity_client/config_loader.rb
178
179
  - lib/singularity_client/request.rb
179
180
  - lib/singularity_client/version.rb
180
181
  - singularity_client.gemspec
181
182
  - spec/singularity_client/api_spec.rb
183
+ - spec/singularity_client/config_loader_spec.rb
182
184
  - spec/singularity_client/config_spec.rb
183
185
  - spec/singularity_client/request_spec.rb
184
186
  - spec/spec_helper.rb
185
- - spec/vcr_cassettes/add.yml
187
+ - spec/vcr_cassettes/addPull.yml
188
+ - spec/vcr_cassettes/addPush.yml
186
189
  - spec/vcr_cassettes/comment.yml
187
190
  - spec/vcr_cassettes/config.yml
188
191
  - spec/vcr_cassettes/error-get.yml
@@ -202,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
202
205
  version: '0'
203
206
  segments:
204
207
  - 0
205
- hash: -4434369719159961746
208
+ hash: -3052736762778204807
206
209
  required_rubygems_version: !ruby/object:Gem::Requirement
207
210
  none: false
208
211
  requirements:
@@ -211,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
214
  version: '0'
212
215
  segments:
213
216
  - 0
214
- hash: -4434369719159961746
217
+ hash: -3052736762778204807
215
218
  requirements: []
216
219
  rubyforge_project:
217
220
  rubygems_version: 1.8.23
@@ -220,10 +223,12 @@ specification_version: 3
220
223
  summary: Singularity Client
221
224
  test_files:
222
225
  - spec/singularity_client/api_spec.rb
226
+ - spec/singularity_client/config_loader_spec.rb
223
227
  - spec/singularity_client/config_spec.rb
224
228
  - spec/singularity_client/request_spec.rb
225
229
  - spec/spec_helper.rb
226
- - spec/vcr_cassettes/add.yml
230
+ - spec/vcr_cassettes/addPull.yml
231
+ - spec/vcr_cassettes/addPush.yml
227
232
  - spec/vcr_cassettes/comment.yml
228
233
  - spec/vcr_cassettes/config.yml
229
234
  - spec/vcr_cassettes/error-get.yml