right_branch 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 03e90279927b64245f2cafc2605e98d8832f88cb
4
- data.tar.gz: 66ced768c06d6baad8ad0ebbcdc518853de0e64c
3
+ metadata.gz: 4817adc6f712e714088de48667e079a1a0037f17
4
+ data.tar.gz: 5a908039cc340e39f7fbaa4fe06d2621b898159f
5
5
  SHA512:
6
- metadata.gz: 7ff827ae6c9f78c9a9e44271713b1bdbe6566f78241bff29ca36ad67bf8445273bf6498b2415a8bd624c850061ba70c8e229f383c6fa4e7cf1fbc44afb812350
7
- data.tar.gz: 40b149508d08044ff6fed1d8712e47c7615dc713f6334ebe1012f895293d56a711033ca50d60ebd2a7875a6024bda498d822adc7a32f17172861fdfc611d5581
6
+ metadata.gz: 84df2a61749b2cd51a051c67bd9295d82badf0f74eb87a310c429202934f154b54aa8652d64d3b59fd40bfe076ffeeb0d234ae3a63544177a6daa5ad20c66f74
7
+ data.tar.gz: 155b3ba87282af4cab69549d2e93ba6201d561a0ad479d19b58180b890a95ee5d9ddb16e06e49e9167f6466c5e5104ef13184aeeb9b00bccf92b8577805917cc
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Right Branch
2
+
3
+ [![Gem version](http://img.shields.io/gem/v/right_branch.svg)](https://rubygems.org/gems/right_branch)
4
+ [![Build Status](https://travis-ci.org/DyegoCosta/right_branch.svg?branch=master)](https://travis-ci.org/DyegoCosta/right_branch)
5
+
6
+ Currently GitHub does not support switching the target branch of a Pull Request. This tool helps to do that in case a PR is submitted against a wrong branch.
7
+
8
+ ## Getting started
9
+
10
+ Install gem:
11
+
12
+ ```
13
+ $ gem install right_branch
14
+ ```
15
+
16
+ Usage:
17
+
18
+ ```
19
+ $ right_branch [options]
20
+ -u, --username USERNAME Username
21
+ -r, --repository REPOSITORY Repository
22
+ -b, --new-branch NEW_BRANCH New branch
23
+ -p, --pull-request PULL_REQUEST Pull request
24
+ -t, --access-token ACCESS_TOKEN Access token
25
+ --password PASSWORD Password
26
+ ```
27
+
28
+ You can also use environment variables to set default configuration values.
29
+
30
+ ```
31
+ $ export RIGHT_BRANCH_USERNAME=your_default_username
32
+ $ export RIGHT_BRANCH_REPOSITORY=your_default_repository
33
+ $ export RIGHT_BRANCH_ACCESS_TOKEN=your_default_access_token
34
+ ```
35
+
36
+ ## Acess token
37
+
38
+ You can avoid having to type your `username` and `password` by providing an access token
39
+ generated by GitHub.
40
+ If you specify it with the `--access-token` option or have it defined
41
+ as a `RIGHT_BRANCH_ACCESS_TOKEN` envrionment variable, it will be used as you authentication method.
42
+ You can [create access tokens through your GitHub Account Settings][create-access-token].
43
+
44
+ [create-access-token]:https://help.github.com/articles/creating-an-access-token-for-command-line-use
@@ -5,7 +5,7 @@ require_relative '../updater'
5
5
 
6
6
  module RightBranch::Commands
7
7
  class ChangePullRequestTarget
8
- REQUIRED_OPTIONS = %i(username repository new_branch pull_request)
8
+ REQUIRED_OPTIONS = [:repository, :new_branch, :pull_request]
9
9
 
10
10
  attr_accessor :stream
11
11
 
@@ -19,7 +19,13 @@ module RightBranch::Commands
19
19
 
20
20
  def run!
21
21
  options = build_options
22
- updater(options).run!
22
+
23
+ attrs = {
24
+ credentials: build_credentials(options),
25
+ repository: options[:repository]
26
+ }
27
+
28
+ updater(attrs).run!(options[:pull_request], options[:new_branch])
23
29
  rescue ::Octokit::Unauthorized
24
30
  abort 'Invalid credentials to update pull request'
25
31
  rescue ::Octokit::UnprocessableEntity
@@ -39,25 +45,40 @@ module RightBranch::Commands
39
45
  abort missing_key_abort_message(missing, opt_parser)
40
46
  end
41
47
 
42
- if String(options[:password]).empty?
43
- options[:password] = ask("Enter your password: ") { |q| q.echo = '*' }
48
+ if prompt_for_password?(options)
49
+ options[:password] = ask('Enter your password: ') { |q| q.echo = '*' }
44
50
  end
45
51
 
46
52
  options
47
53
  end
48
54
 
55
+ def prompt_for_password?(options)
56
+ String(options[:access_token]).empty? &&
57
+ String(options[:password]).empty?
58
+ end
59
+
60
+ def build_credentials(options)
61
+ if options[:access_token].to_s.empty?
62
+ { login: options[:username], password: options[:password] }
63
+ else
64
+ { access_token: options[:access_token] }
65
+ end
66
+ end
67
+
49
68
  def missing_opt_keys(options)
50
69
  missing = REQUIRED_OPTIONS - options.keys
51
- missing += options.select { |_, v| v.nil? || v.empty? }.keys
52
- missing
70
+ required_blank = options.select do |k, v|
71
+ REQUIRED_OPTIONS.include?(k) && String(v).empty?
72
+ end
73
+ missing += required_blank.keys
53
74
  end
54
75
 
55
76
  def missing_key_abort_message(keys, opt_parser)
56
77
  "Missing required options: #{keys.join(', ')}\n\n#{opt_parser}"
57
78
  end
58
79
 
59
- def updater(options)
60
- RightBranch::Updater.new(options)
80
+ def updater(attrs)
81
+ RightBranch::Updater.new(attrs)
61
82
  end
62
83
 
63
84
  def build_opt_parser(options)
@@ -80,6 +101,10 @@ module RightBranch::Commands
80
101
  options[:pull_request] = v
81
102
  end
82
103
 
104
+ opts.on("-t", "--access-token ACCESS_TOKEN", "Access token") do |v|
105
+ options[:access_token] = v
106
+ end
107
+
83
108
  opts.on("--password PASSWORD", "Password") do |v|
84
109
  options[:password] = v
85
110
  end
@@ -89,6 +114,7 @@ module RightBranch::Commands
89
114
  def fallback_to_options_from_env(options)
90
115
  options[:username] ||= ENV['RIGHT_BRANCH_USERNAME']
91
116
  options[:repository] ||= ENV['RIGHT_BRANCH_REPOSITORY']
117
+ options[:access_token] ||= ENV['RIGHT_BRANCH_ACCESS_TOKEN']
92
118
  end
93
119
  end
94
120
  end
@@ -2,34 +2,30 @@ require 'octokit'
2
2
 
3
3
  module RightBranch
4
4
  class Updater
5
- attr_reader :username, :password, :pull_request,
6
- :new_branch, :repository
5
+ attr_reader :credentials, :repository
7
6
 
8
7
  def initialize(options)
9
- @username = options.fetch(:username)
10
- @password = options.fetch(:password)
11
- @pull_request = options.fetch(:pull_request)
12
- @new_branch = options.fetch(:new_branch)
13
- @repository = options.fetch(:repository)
8
+ @repository = options[:repository]
9
+ @credentials = options[:credentials]
14
10
  end
15
11
 
16
- def run!
17
- old_pr = get_pr(pull_request)
18
- new_pr = submit_pr(old_pr, new_branch)
19
- update_pr(old_pr[:number], state: 'closed')
20
- comment_on_issue old_pr[:number] ,
12
+ def run!(old_pr_number, new_branch)
13
+ new_pr = resubmit_pr(old_pr_number, new_branch)
14
+
15
+ update_pr(old_pr_number, state: 'closed')
16
+
17
+ comment_on_issue old_pr_number ,
21
18
  "Reopened against `#{new_branch}` (##{new_pr.number})"
22
19
  end
23
20
 
24
21
  private
25
22
 
26
23
  def github
27
- @github ||= Octokit::Client.new \
28
- login: username, password: password
24
+ @github ||= Octokit::Client.new(credentials)
29
25
  end
30
26
 
31
- def get_pr(pr)
32
- github.pull_request(repository, pr)
27
+ def get_pr(pr_number)
28
+ github.pull_request(repository, pr_number)
33
29
  end
34
30
 
35
31
  def comment_on_issue(number, comment)
@@ -40,13 +36,15 @@ module RightBranch
40
36
  github.update_pull_request(repository, number, args)
41
37
  end
42
38
 
43
- def submit_pr(pr, new_branch)
39
+ def resubmit_pr(old_pr_number, new_branch)
40
+ old_pr = get_pr(old_pr_number)
41
+
44
42
  github.create_pull_request \
45
43
  repository,
46
44
  new_branch,
47
- pr[:head][:label],
48
- pr[:title],
49
- pr[:body]
45
+ old_pr[:head][:label],
46
+ old_pr[:title],
47
+ old_pr[:body]
50
48
  end
51
49
  end
52
50
  end
@@ -1,3 +1,3 @@
1
1
  module RightBranch
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -73,4 +73,20 @@ describe RightBranch::Commands::ChangePullRequestTarget do
73
73
  "Missing required options: a, b\n\nwow"
74
74
  end
75
75
  end
76
+
77
+ describe '#build_credentials' do
78
+ it 'returns access token if present' do
79
+ actual = subject.send :build_credentials,
80
+ access_token: 'omg', username: 'doge', password: 'wow'
81
+
82
+ expect(actual).to eq({ access_token: 'omg'})
83
+ end
84
+
85
+ it 'returns username and password if no access token is present' do
86
+ actual = subject.send :build_credentials,
87
+ username: 'doge', password: 'wow'
88
+
89
+ expect(actual).to eq({ login: 'doge', password: 'wow' })
90
+ end
91
+ end
76
92
  end
data/spec/updater_spec.rb CHANGED
@@ -1,34 +1,62 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe RightBranch::Updater do
4
- subject { described_class.new default_options }
5
-
6
- let(:default_options) do
7
- {
8
- pull_request: '1',
9
- new_branch: 'test',
10
- username: 'doge',
11
- password: 'very_secure',
12
- repository: 'foo/bar',
13
- }
14
- end
4
+ let(:gh) { double(:github) }
5
+ let(:repo) { 'doge/wow' }
6
+ let(:updater) { described_class.new(repository: repo) }
7
+
8
+ before { allow(updater).to receive(:github).and_return(gh) }
15
9
 
16
- describe '#submit_pr' do
10
+ describe '#resubmit_pr' do
17
11
  it 'creats new pull request againts branch' do
18
- gh = double(:github)
12
+ old_pr_number = 1
19
13
  title, body, label, branch = %w(title body label branch)
20
- pr = { title: title, body: body, head: { label: label } }
21
-
22
- allow(subject).to receive(:github).and_return(gh)
14
+ pr = { title: 'title', body: 'body', head: { label: 'label' } }
15
+ allow(updater).to receive(:get_pr).with(old_pr_number).and_return(pr)
23
16
 
24
17
  expect(gh).to receive(:create_pull_request).with \
25
- default_options[:repository],
26
- branch,
27
- label,
28
- title,
29
- body
18
+ repo, branch, label, title, body
19
+
20
+ updater.send(:resubmit_pr, old_pr_number, branch)
21
+ end
22
+ end
23
+
24
+ describe '#run!' do
25
+ it 'resubmits old pull request' do
26
+ old = '1'
27
+ branch = 'test'
28
+ allow(updater).to receive(:comment_on_issue)
29
+ allow(updater).to receive(:update_pr)
30
+
31
+ expect(updater).to receive(:resubmit_pr)
32
+ .with(old, branch).and_return double(number: '2')
33
+
34
+ updater.run!(old, branch)
35
+ end
36
+
37
+ it 'closes old pr' do
38
+ old = '1'
39
+ new_pr = double(:new_pr, number: '2')
40
+ allow(updater).to receive(:resubmit_pr).and_return new_pr
41
+ allow(updater).to receive(:comment_on_issue)
42
+
43
+ expect(updater).to receive(:update_pr).with \
44
+ old, state: 'closed'
45
+
46
+ updater.run!(old, 'testing')
47
+ end
48
+
49
+ it 'comment on old pr with new pr number' do
50
+ old = '1'
51
+ new_pr = double(:new_pr, number: '2')
52
+ allow(updater).to receive(:resubmit_pr).and_return new_pr
53
+ allow(updater).to receive(:update_pr)
54
+
55
+ allow(updater).to receive(:comment_on_issue).with \
56
+ old, 'Reopened against `testing` (#2)'
57
+
30
58
 
31
- subject.send(:submit_pr, pr, branch)
59
+ updater.run!(old, 'testing')
32
60
  end
33
61
  end
34
62
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_branch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dyego Costa
@@ -58,6 +58,26 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: 3.1.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.8'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 0.8.7
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '0.8'
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 0.8.7
61
81
  description: If you submit a Pull Request to a wrong branch on GitHub you can use
62
82
  this gem to change it
63
83
  email: dyego@dyegocosta.com
@@ -66,6 +86,7 @@ executables:
66
86
  extensions: []
67
87
  extra_rdoc_files: []
68
88
  files:
89
+ - README.md
69
90
  - bin/right_branch
70
91
  - lib/right_branch.rb
71
92
  - lib/right_branch/commands/change_pull_request_target.rb