thegarage-gitx 1.4.1 → 1.5.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e53179bded6c6d5e54e69a8bacb3116ffcd411e
4
- data.tar.gz: 770a7742c1daec8aafb3b8dee9291f3455498161
3
+ metadata.gz: 9da76850a18efd35f1ad4755e580f74b2bddda17
4
+ data.tar.gz: c80377d9cf9269445ab266348a60c93777061992
5
5
  SHA512:
6
- metadata.gz: 80522f4bbe1c40bb3078b74f945f5921c10797bec6f2ea5f7cf659e2af9e0cceb6fde07c0f71919e4377914afe3f402cc2e00d9f5612a816d0d793136ea23fc1
7
- data.tar.gz: 49e817eb55e0efb84e8feaa93c0c2eced2c3f791472510f88ed92dd04a316b00ae82ae3fa6f20aebcfe659bd588501463c75c530d74ac4c913769bc7daff4aff
6
+ metadata.gz: d8461ef865ca67baf61344ccfdd29a0cf4820878343c606cfac1bde2892e658e6ca116575484097e81cec7809da617fcb08f5fc1c5b9871cd26a6c655d656ffc
7
+ data.tar.gz: 5965d506c234b42a3c014f87a1649173aeceaea0814a31537c0089bed3abafddb641f0f0d0a0bed35fe171a76df3b6098cd609e4a1f1fabe57e3b7d80374b15f
@@ -20,17 +20,25 @@ module Thegarage
20
20
  RestClient.log = Logger.new(STDOUT) if options[:trace]
21
21
  end
22
22
 
23
- desc "reviewrequest", "Create a pull request on github"
23
+ desc "reviewrequest", "Create or update a pull request on github"
24
24
  method_option :description, :type => :string, :aliases => '-d', :desc => 'pull request description'
25
25
  method_option :assignee, :type => :string, :aliases => '-a', :desc => 'pull request assignee'
26
+ method_option :open, :type => :boolean, :aliases => '-o', :desc => 'open the pull request in a web browser'
26
27
  # @see http://developer.github.com/v3/pulls/
27
28
  def reviewrequest
28
29
  update
30
+ fail 'Github authorization token not found' unless github.authorization_token
31
+
32
+ pull_request = github.find_pull_request(current_branch)
33
+ if pull_request.nil?
34
+ changelog = run_cmd "git log #{Thegarage::Gitx::BASE_BRANCH}...#{current_branch} --no-merges --pretty=format:'* %s%n%b'"
35
+ pull_request = github.create_pull_request(current_branch, changelog, options)
36
+ say 'Pull request created: '
37
+ say pull_request['html_url'], :green
38
+ end
39
+ github.assign_pull_request(pull_request, options[:assignee]) if options[:assignee]
29
40
 
30
- changelog = run_cmd "git log #{Thegarage::Gitx::BASE_BRANCH}...#{current_branch} --no-merges --pretty=format:'* %s%n%b'"
31
- url = github.create_pull_request(current_branch, changelog, options)
32
- say 'Pull request created: '
33
- say url, :green
41
+ run_cmd "open #{pull_request['html_url']}" if options[:open]
34
42
  end
35
43
 
36
44
  # TODO: use --no-edit to skip merge messages
@@ -73,7 +81,7 @@ module Thegarage
73
81
  desc 'start', 'start a new git branch with latest changes from master'
74
82
  def start(branch_name = nil)
75
83
  unless branch_name
76
- example_branch = %w{ api-fix-invalid-auth desktop-cleanup-avatar-markup share-form-add-edit-link }.sort_by { rand }.first
84
+ example_branch = %w{ api-fix-invalid-auth desktop-cleanup-avatar-markup share-form-add-edit-link }.shuffle.first
77
85
  repo = Grit::Repo.new(Dir.pwd)
78
86
  remote_branches = repo.remotes.collect {|b| b.name.split('/').last }
79
87
  until branch_name = ask("What would you like to name your branch? (ex: #{example_branch})") {|q|
@@ -23,40 +23,7 @@ module Thegarage
23
23
  @shell = shell
24
24
  end
25
25
 
26
- # returns the url of the created pull request
27
- # @see http://developer.github.com/v3/pulls/
28
- def create_pull_request(branch, changelog, options = {})
29
- fail 'Github authorization token not found' unless authorization_token
30
- remote = remote_origin_name
31
- body = pull_request_body(changelog, options[:description])
32
-
33
- shell.say "Creating pull request for "
34
- shell.say "#{branch} ", :green
35
- shell.say "against "
36
- shell.say "#{Thegarage::Gitx::BASE_BRANCH} ", :green
37
- shell.say "in "
38
- shell.say remote, :green
39
-
40
- payload = {
41
- :title => branch,
42
- :base => Thegarage::Gitx::BASE_BRANCH,
43
- :head => branch,
44
- :body => body
45
- }.to_json
46
- response = RestClient::Request.new(:url => "https://api.github.com/repos/#{remote}/pulls", :method => "POST", :payload => payload, :headers => request_headers).execute
47
- data = JSON.parse response.body
48
-
49
- assign_pull_request(branch, options[:assignee], data) if options[:assignee]
50
-
51
- url = data['html_url']
52
- url
53
- rescue RestClient::Exception => e
54
- process_error e
55
- throw e
56
- end
57
-
58
- private
59
-
26
+ # returns [Hash] data structure of created pull request
60
27
  # request github authorization token
61
28
  # User-Agent is required
62
29
  # store the token in local git config
@@ -93,19 +60,64 @@ module Thegarage
93
60
  token
94
61
  rescue RestClient::Exception => e
95
62
  process_error e
96
- throw e
97
63
  end
98
64
 
99
- def assign_pull_request(branch, assignee, data)
100
- issue_payload = { :title => branch, :assignee => assignee }.to_json
101
- RestClient::Request.new(:url => data['issue_url'], :method => "PATCH", :payload => issue_payload, :headers => request_headers).execute
65
+ # @see http://developer.github.com/v3/pulls/
66
+ def create_pull_request(branch, changelog, options = {})
67
+ remote = remote_origin_name
68
+ body = pull_request_body(changelog, options[:description])
69
+
70
+ shell.say "Creating pull request for "
71
+ shell.say "#{branch} ", :green
72
+ shell.say "against "
73
+ shell.say "#{Thegarage::Gitx::BASE_BRANCH} ", :green
74
+ shell.say "in "
75
+ shell.say remote, :green
76
+
77
+ payload = {
78
+ :title => branch,
79
+ :base => Thegarage::Gitx::BASE_BRANCH,
80
+ :head => branch,
81
+ :body => body
82
+ }.to_json
83
+ response = RestClient::Request.new(:url => "https://api.github.com/repos/#{remote}/pulls", :method => "POST", :payload => payload, :headers => request_headers).execute
84
+ pull_request = JSON.parse response.body
85
+
86
+ pull_request
87
+ rescue RestClient::Exception => e
88
+ process_error e
89
+ end
90
+
91
+ def assign_pull_request(pull_request, assignee)
92
+ branch = pull_request['head']['ref']
93
+ payload = {
94
+ :title => branch,
95
+ :assignee => assignee
96
+ }.to_json
97
+ RestClient::Request.new(:url => pull_request['issue_url'], :method => "PATCH", :payload => payload, :headers => request_headers).execute
98
+ rescue RestClient::Exception => e
99
+ process_error e
100
+ end
101
+
102
+ # @returns [Hash] data structure of pull request info if found
103
+ # @returns nil if no pull request found
104
+ def find_pull_request(branch)
105
+ payload = {
106
+ course: branch
107
+ }.to_json
108
+ response = RestClient::Request.new(:url => "https://api.github.com/repos/#{remote}/pulls", :method => "GET", :payload => payload, :headers => request_headers).execute
109
+ data = JSON.parse(response.body)
110
+ data.first
102
111
  rescue RestClient::Exception => e
103
112
  process_error e
104
113
  end
105
114
 
115
+ private
116
+
106
117
  def process_error(e)
107
118
  data = JSON.parse e.http_body
108
119
  shell.say "Github request failed: #{data['message']}", :red
120
+ throw e
109
121
  end
110
122
 
111
123
  def request_headers
@@ -1,5 +1,5 @@
1
1
  module Thegarage
2
2
  module Gitx
3
- VERSION = '1.4.1'
3
+ VERSION = '1.5.0.pre1'
4
4
  end
5
5
  end
@@ -24,7 +24,7 @@ describe Thegarage::Gitx::CLI do
24
24
 
25
25
  cli.update
26
26
  end
27
- it 'should run expected commands' do
27
+ it 'runs expected commands' do
28
28
  should meet_expectations
29
29
  end
30
30
  end
@@ -45,7 +45,7 @@ describe Thegarage::Gitx::CLI do
45
45
 
46
46
  cli.integrate
47
47
  end
48
- it 'should default to staging' do
48
+ it 'defaults to staging branch' do
49
49
  should meet_expectations
50
50
  end
51
51
  end
@@ -64,12 +64,12 @@ describe Thegarage::Gitx::CLI do
64
64
 
65
65
  cli.integrate 'prototype'
66
66
  end
67
- it 'should run expected commands' do
67
+ it 'runs expected commands' do
68
68
  should meet_expectations
69
69
  end
70
70
  end
71
71
  context 'when target branch != staging || prototype' do
72
- it 'should raise an error' do
72
+ it 'raises an error' do
73
73
  expect(cli).to receive(:run).with("git pull origin feature-branch", capture: true).ordered
74
74
  expect(cli).to receive(:run).with("git pull origin master", capture: true).ordered
75
75
  expect(cli).to receive(:run).with("git push origin HEAD", capture: true).ordered
@@ -92,7 +92,7 @@ describe Thegarage::Gitx::CLI do
92
92
 
93
93
  cli.release
94
94
  end
95
- it 'should only run update commands' do
95
+ it 'only runs update commands' do
96
96
  should meet_expectations
97
97
  end
98
98
  end
@@ -122,7 +122,7 @@ describe Thegarage::Gitx::CLI do
122
122
 
123
123
  cli.release
124
124
  end
125
- it 'should run expected commands' do
125
+ it 'runs expected commands' do
126
126
  should meet_expectations
127
127
  end
128
128
  end
@@ -153,7 +153,7 @@ describe Thegarage::Gitx::CLI do
153
153
 
154
154
  cli.nuke 'prototype'
155
155
  end
156
- it 'should run expected commands' do
156
+ it 'runs expected commands' do
157
157
  should meet_expectations
158
158
  end
159
159
  end
@@ -181,7 +181,7 @@ describe Thegarage::Gitx::CLI do
181
181
 
182
182
  cli.nuke 'staging'
183
183
  end
184
- it 'should run expected commands' do
184
+ it 'runs expected commands' do
185
185
  should meet_expectations
186
186
  end
187
187
  end
@@ -229,17 +229,17 @@ describe Thegarage::Gitx::CLI do
229
229
 
230
230
  cli.nuke 'prototype'
231
231
  end
232
- it 'should run expected commands' do
232
+ it 'runs expected commands' do
233
233
  should meet_expectations
234
234
  end
235
235
  end
236
236
  context 'when target branch != staging || prototype' do
237
- it 'should raise error' do
237
+ it 'raises error' do
238
238
  lambda {
239
239
  expect(cli).to receive(:ask).and_return('master')
240
240
  expect(cli).to receive(:yes?).and_return(true)
241
241
  cli.nuke 'not-an-integration-branch'
242
- }.should raise_error /Only aggregate branches are allowed to be reset/
242
+ }.should raise_error(/Only aggregate branches are allowed to be reset/)
243
243
  end
244
244
  end
245
245
  context 'when user does not confirm nuking the target branch' do
@@ -255,7 +255,7 @@ describe Thegarage::Gitx::CLI do
255
255
 
256
256
  cli.nuke 'prototype'
257
257
  end
258
- it 'should run expected commands' do
258
+ it 'runs expected commands' do
259
259
  should meet_expectations
260
260
  end
261
261
  end
@@ -269,29 +269,99 @@ describe Thegarage::Gitx::CLI do
269
269
  expect(cli).to receive(:run).with("git fetch --tags", capture: true).ordered
270
270
  expect(cli).to receive(:run).with("git tag -l 'build-master-*'", capture: true).and_return(buildtags).ordered
271
271
 
272
- expect { cli.nuke('prototype') }.to raise_error /No known good tag found for branch/
272
+ expect { cli.nuke('prototype') }.to raise_error(/No known good tag found for branch/)
273
273
  end
274
274
  end
275
275
  end
276
276
 
277
277
  describe '#reviewrequest' do
278
- context 'when github configured correctly' do
279
- let(:github) { double('fake github') }
278
+ let(:github) { double('fake github') }
279
+ let(:pull_request) do
280
+ {
281
+ 'html_url' => 'https://path/to/new/pull/request',
282
+ 'head' => {
283
+ 'ref' => 'branch_name'
284
+ }
285
+ }
286
+ end
287
+ before do
288
+ allow(cli).to receive(:github).and_return(github)
289
+
290
+ expect(cli).to receive(:run).with("git pull origin feature-branch", capture: true).ordered
291
+ expect(cli).to receive(:run).with("git pull origin master", capture: true).ordered
292
+ expect(cli).to receive(:run).with("git push origin HEAD", capture: true).ordered
293
+ end
294
+ context 'when pull request does not exist' do
295
+ let(:authorization_token) { '123123' }
296
+ let(:changelog) { '* made some fixes' }
280
297
  before do
281
- expect(cli).to receive(:github).and_return(github)
282
- expect(github).to receive(:create_pull_request).and_return('https://path/to/new/pull/request')
298
+ expect(github).to receive(:authorization_token).and_return(authorization_token)
299
+ expect(github).to receive(:find_pull_request).and_return(nil)
300
+ expect(github).to receive(:create_pull_request).and_return(pull_request)
283
301
 
284
- expect(cli).to receive(:run).with("git pull origin feature-branch", capture: true).ordered
285
- expect(cli).to receive(:run).with("git pull origin master", capture: true).ordered
286
- expect(cli).to receive(:run).with("git push origin HEAD", capture: true).ordered
287
302
  expect(cli).to receive(:run).with("git log master...feature-branch --no-merges --pretty=format:'* %s%n%b'", capture: true).and_return("2013-01-01 did some stuff").ordered
303
+ cli.reviewrequest
304
+ end
305
+ it 'creates github pull request' do
306
+ should meet_expectations
307
+ end
308
+ it 'runs expected commands' do
309
+ should meet_expectations
310
+ end
311
+ end
312
+ context 'when authorization_token is missing' do
313
+ let(:authorization_token) { nil }
314
+ it do
315
+ expect(github).to receive(:authorization_token).and_return(authorization_token)
316
+ expect { cli.reviewrequest }.to raise_error(/token not found/)
317
+ end
318
+ end
319
+ context 'when pull request already exists' do
320
+ let(:authorization_token) { '123123' }
321
+ before do
322
+ expect(github).to receive(:authorization_token).and_return(authorization_token)
323
+ expect(github).to receive(:find_pull_request).and_return(pull_request)
324
+ expect(github).to_not receive(:create_pull_request)
288
325
 
289
326
  cli.reviewrequest
290
327
  end
291
- it 'should create github pull request' do
328
+ it 'does not create new pull request' do
292
329
  should meet_expectations
293
330
  end
294
- it 'should run expected commands' do
331
+ end
332
+ context 'when --assignee option passed' do
333
+ let(:options) do
334
+ {
335
+ assignee: 'johndoe'
336
+ }
337
+ end
338
+ let(:authorization_token) { '123123' }
339
+ before do
340
+ expect(github).to receive(:authorization_token).and_return(authorization_token)
341
+ expect(github).to receive(:find_pull_request).and_return(pull_request)
342
+ expect(github).to receive(:assign_pull_request)
343
+
344
+ cli.reviewrequest
345
+ end
346
+ it 'calls assign_pull_request method' do
347
+ should meet_expectations
348
+ end
349
+ end
350
+ context 'when --open flag passed' do
351
+ let(:options) do
352
+ {
353
+ open: true
354
+ }
355
+ end
356
+ let(:authorization_token) { '123123' }
357
+ before do
358
+ expect(github).to receive(:authorization_token).and_return(authorization_token)
359
+ expect(github).to receive(:find_pull_request).and_return(pull_request)
360
+
361
+ expect(cli).to receive(:run).with("open #{pull_request['html_url']}", capture: true).ordered
362
+ cli.reviewrequest
363
+ end
364
+ it 'runs open command with pull request url' do
295
365
  should meet_expectations
296
366
  end
297
367
  end
@@ -307,7 +377,7 @@ describe Thegarage::Gitx::CLI do
307
377
  ENV['TRAVIS_BUILD_NUMBER'] = env_travis_build_number
308
378
  end
309
379
  context 'when ENV[\'TRAVIS_BRANCH\'] is nil' do
310
- it 'should raise Unknown Branch error' do
380
+ it 'raises Unknown Branch error' do
311
381
  expect { cli.buildtag }.to raise_error "Unknown branch. ENV['TRAVIS_BRANCH'] is required."
312
382
  end
313
383
  end
@@ -344,7 +414,7 @@ describe Thegarage::Gitx::CLI do
344
414
  cli.buildtag
345
415
  end
346
416
  end
347
- it 'should create a tag for the branch and push it to github' do
417
+ it 'creates a tag for the branch and push it to github' do
348
418
  should meet_expectations
349
419
  end
350
420
  end
@@ -10,12 +10,12 @@ describe Thegarage::Gitx::Github do
10
10
  let(:shell) { double('fake shell', say: nil, ask: nil) }
11
11
  subject { Thegarage::Gitx::Github.new(repo, shell) }
12
12
 
13
- describe '#create_pull_request' do
13
+ describe '#authorization_token' do
14
14
  context 'when github.user is not configured' do
15
15
  it 'raises error' do
16
16
  expect do
17
- subject.create_pull_request 'example-branch', 'changelog'
18
- end.to raise_error /Github user not configured/
17
+ subject.authorization_token
18
+ end.to raise_error(/Github user not configured/)
19
19
  end
20
20
  end
21
21
  context 'when config.authorization_token is nil' do
@@ -39,24 +39,31 @@ describe Thegarage::Gitx::Github do
39
39
  with(:body => expected_auth_body).
40
40
  to_return(:status => 200, :body => JSON.dump(token: authorization_token), :headers => {})
41
41
 
42
- stub_request(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/pulls").
43
- to_return(:status => 200, :body => %q({"html_url": "http://github.com/repo/project/pulls/1"}), :headers => {})
44
-
45
- expect(shell).to receive(:ask).with('Github password for ryan@codecrate.com: ', {:echo => false}).and_return(github_password).any_number_of_times
42
+ expect(shell).to receive(:ask).with('Github password for ryan@codecrate.com: ', {:echo => false}).and_return(github_password)
46
43
 
47
- expect(subject).to receive(:input_from_editor).and_return('scrubbed text')
48
- subject.create_pull_request 'example-branch', 'changelog'
44
+ @auth_token = subject.authorization_token
49
45
  end
50
- it 'creates authorization_token' do
46
+ it 'stores authorization_token in git config' do
51
47
  expect(repo_config).to include('thegarage.gitx.githubauthtoken' => authorization_token)
52
48
  end
53
- it 'should create github pull request' do
54
- should meet_expectations
49
+ it { expect(@auth_token).to eq authorization_token }
50
+ end
51
+ context 'when there is an existing authorization_token' do
52
+ let(:authorization_token) { '123981239123' }
53
+ let(:repo_config) do
54
+ {
55
+ 'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx',
56
+ 'github.user' => 'ryan@codecrate.com',
57
+ 'thegarage.gitx.githubauthtoken' => authorization_token
58
+ }
55
59
  end
56
- it 'should run expected commands' do
57
- should meet_expectations
60
+ before do
61
+ @auth_token = subject.authorization_token
58
62
  end
63
+ it { expect(@auth_token).to eq authorization_token }
59
64
  end
65
+ end
66
+ describe '#create_pull_request' do
60
67
  context 'when there is an existing authorization_token' do
61
68
  let(:authorization_token) { '123981239123' }
62
69
  let(:repo_config) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thegarage-gitx
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Sonnek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-10 00:00:00.000000000 Z
11
+ date: 2014-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grit
@@ -200,9 +200,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
200
200
  version: '0'
201
201
  required_rubygems_version: !ruby/object:Gem::Requirement
202
202
  requirements:
203
- - - '>='
203
+ - - '>'
204
204
  - !ruby/object:Gem::Version
205
- version: '0'
205
+ version: 1.3.1
206
206
  requirements: []
207
207
  rubyforge_project:
208
208
  rubygems_version: 2.0.3