github-pr 0.0.5 → 0.0.6
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 +4 -4
- data/lib/github-pr/cli.rb +48 -0
- data/lib/github-pr/poster.rb +35 -0
- data/lib/github-pr/runner.rb +12 -0
- data/lib/github-pr/token.rb +80 -0
- data/test/test_github-pr.rb +31 -0
- metadata +6 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f69b3788548dbe89a985327b46e8b83a2b6f931
|
4
|
+
data.tar.gz: d2ad0f63f47a71fb07fe95665d27c18d2b708922
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9729044ae72b5c39aaf2eda9af8053e413d360aa3898385804b5ebe26c1bce36dba59a056f924f376741fa1fc23371056c910e349aab3e0338e8c66b7b4aab7d
|
7
|
+
data.tar.gz: 010c856804d641a38cbda5dd9f8e08920e91416bd97174800fed66161ec6def880714358d0570591df431d75decfe368aa264aecc0826f98efcb548691014f22
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module GitHubPr
|
4
|
+
module CLI
|
5
|
+
def self.parse(argv)
|
6
|
+
options = {}
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: github-pr -b master -f shop-redesign -a hovox"
|
9
|
+
opts.separator ""
|
10
|
+
opts.separator "Your current directory must be your git directory"
|
11
|
+
opts.separator "github-pr -b master -a hovox"
|
12
|
+
opts.separator "Will use current branch as feature branch"
|
13
|
+
opts.separator ""
|
14
|
+
opts.separator "github-pr -a hovox"
|
15
|
+
opts.separator "Will use master branch as base branch and current branch as feature branch"
|
16
|
+
opts.separator ""
|
17
|
+
opts.separator "Command should be run from project's directory"
|
18
|
+
|
19
|
+
|
20
|
+
opts.on("-b", "--base BASE", "Base branch") do |b|
|
21
|
+
options[:base] = b
|
22
|
+
end
|
23
|
+
opts.on("-f", "--feature FEATURE", "Feature branch") do |f|
|
24
|
+
options[:feature] = f
|
25
|
+
end
|
26
|
+
opts.on("-a", "--assign USERNAME", "GitHub user name whom to assign") do |a|
|
27
|
+
options[:assign] = a
|
28
|
+
end
|
29
|
+
opts.on("-t", "--title PULLREQUESTTITLE", "Title of the pull request") do |t|
|
30
|
+
options[:title] = t
|
31
|
+
end
|
32
|
+
end.parse!(argv)
|
33
|
+
|
34
|
+
raise 'You must assign to someone' if options[:assign].nil?
|
35
|
+
|
36
|
+
options[:base] = 'master' if options[:base].nil?
|
37
|
+
# e.g. * master cutting '* ' from begining
|
38
|
+
options[:feature] = self.current_branch if options[:feature].nil?
|
39
|
+
options[:title] = options[:feature] if options[:title].nil?
|
40
|
+
|
41
|
+
return options
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.current_branch
|
45
|
+
`git branch | grep "^*"`.chomp[2..-1]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
|
3
|
+
module GitHubPr
|
4
|
+
class Poster
|
5
|
+
def initialize(token)
|
6
|
+
@token = token
|
7
|
+
end
|
8
|
+
|
9
|
+
def post(options)
|
10
|
+
client = Octokit::Client.new(:access_token => @token.get())
|
11
|
+
begin
|
12
|
+
post(client, options)
|
13
|
+
rescue Octokit::Unauthorized
|
14
|
+
client = Octokit::Client.new(:access_token => @token.get(regenerate: true))
|
15
|
+
post(client, options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def post(client, options)
|
19
|
+
pull_request = client.create_pull_request(cut_scheme_and_host(repo_url()),
|
20
|
+
options[:base],
|
21
|
+
options[:feature],
|
22
|
+
options[:title], nil)
|
23
|
+
client.post("/repos/#{repo}/issues/#{pull_request['number']}/assignees",
|
24
|
+
assignees: [options[:assign]])
|
25
|
+
end
|
26
|
+
|
27
|
+
# https://github.com/user/reponame cutting path user/reponame
|
28
|
+
def cut_scheme_and_host(url)
|
29
|
+
URI::parse(url).path[1..-1]
|
30
|
+
end
|
31
|
+
def repo_url
|
32
|
+
`git config --get remote.origin.url`.chomp
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
require "octokit"
|
3
|
+
require 'highline'
|
4
|
+
require 'uri'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module GitHubPr
|
8
|
+
class Token
|
9
|
+
# @token_file_path = File.expand_path '~/.config/gh-pr-token'
|
10
|
+
|
11
|
+
def initialize(token_file_path)
|
12
|
+
@token_file_path = token_file_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def token_from_file
|
16
|
+
File.exists? @token_file_path ? IO.read(@token_file_path) : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def retry_logic(count, initial_note)
|
20
|
+
note = initial_note
|
21
|
+
count.times do |i|
|
22
|
+
begin
|
23
|
+
yield(note)
|
24
|
+
break
|
25
|
+
rescue Exception => e
|
26
|
+
if i == 8
|
27
|
+
raise 'Please remove some personal tokens from your github account, you have too many tokens'
|
28
|
+
end
|
29
|
+
if e.errors[0][:code] != "already_exists" || e.errors[0][:field] != "description"
|
30
|
+
raise e
|
31
|
+
else
|
32
|
+
note = initial_note + (i + 2).to_s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def token_from_github
|
39
|
+
client = Octokit::Client.new(get_username_and_pass())
|
40
|
+
# trying 9 different notes, if all is failed,
|
41
|
+
# then you have to remove some of them
|
42
|
+
retry_logic(9, 'CLI uses') do |note|
|
43
|
+
return client.create_authorization(:scopes => ["repo", "user"], :note => note)[:token]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_dir_if_needed
|
48
|
+
token_dir = File.dirname(@token_file_path)
|
49
|
+
unless File.directory?(token_dir)
|
50
|
+
FileUtils.mkdir_p(token_dir)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_username_and_pass
|
55
|
+
cli = HighLine.new
|
56
|
+
|
57
|
+
github_username = cli.ask("GitHub Username: ")
|
58
|
+
github_password = cli.ask("GitHub Password(Only one time): ") { |q| q.echo = "*" }
|
59
|
+
return {:login => github_username, :password => github_password}
|
60
|
+
end
|
61
|
+
|
62
|
+
def get(regenerate: regenerate = false)
|
63
|
+
create_dir_if_needed()
|
64
|
+
|
65
|
+
if regenerate
|
66
|
+
FileUtils.rm(@token_file_path)
|
67
|
+
end
|
68
|
+
|
69
|
+
token = token_from_file()
|
70
|
+
if token
|
71
|
+
return token
|
72
|
+
end
|
73
|
+
|
74
|
+
token = token_from_github()
|
75
|
+
File.open(token_file_path, 'w+') {|file| file.write token}
|
76
|
+
return token
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'github-pr'
|
3
|
+
|
4
|
+
describe GitHubPr do
|
5
|
+
|
6
|
+
describe "when passed only assigner" do
|
7
|
+
it "must contain assign field" do
|
8
|
+
GitHubPr.parse(['-a', 'hovox'])[:assign].must_equal 'hovox'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "when does not passed assigner argument" do
|
13
|
+
it "must raise an runtime error" do
|
14
|
+
-> { GitHubPr.parse(['-b', 'master', '-f', 'shop']) }.must_raise RuntimeError
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "when does not passed base branch" do
|
19
|
+
it "must take master as base branch" do
|
20
|
+
GitHubPr.parse(['-a', 'hovox'])[:base].must_equal 'master'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe "when does not passed base branch" do
|
26
|
+
it "must take master as base branch" do
|
27
|
+
GitHubPr.parse(['-a', 'hovox'])[:base].must_equal 'master'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-pr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hovhannes Safaryan
|
@@ -47,6 +47,11 @@ extra_rdoc_files: []
|
|
47
47
|
files:
|
48
48
|
- bin/github-pr
|
49
49
|
- lib/github-pr.rb
|
50
|
+
- lib/github-pr/cli.rb
|
51
|
+
- lib/github-pr/poster.rb
|
52
|
+
- lib/github-pr/runner.rb
|
53
|
+
- lib/github-pr/token.rb
|
54
|
+
- test/test_github-pr.rb
|
50
55
|
homepage: http://rubygems.org/gems/github-pr
|
51
56
|
licenses:
|
52
57
|
- MIT
|