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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3fe09fc99ab0eb7a14a246fd5f5dbe5de8a97da6
4
- data.tar.gz: 885fd69a06a16bf12c975e5f6c9f8962290f3380
3
+ metadata.gz: 3f69b3788548dbe89a985327b46e8b83a2b6f931
4
+ data.tar.gz: d2ad0f63f47a71fb07fe95665d27c18d2b708922
5
5
  SHA512:
6
- metadata.gz: dc5feec10da90ab57af3d7a3493238730c9a721256c4ee9faf6a3cddf64ef7e5d45772c0852afa0f71b116cd43997f7d6ada9e66e335949e49c9bbc7b434b07f
7
- data.tar.gz: 312495485804afb77c49244c3f3b75dd53997e6dd7bde09817d3403935a2f6d3797a43e3df3e204b96668bb2c7d495c4d8addc396e50f42426410b7fa469ba7e
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,12 @@
1
+
2
+ module GitHubPr
3
+ module Runner
4
+ def self.run(opts)
5
+ options = CLI.parse(opts)
6
+ puts options
7
+
8
+ poster = Poster.new(Token.new(File.expand_path '~/.config/gh-pr-token'))
9
+ poster.post(options)
10
+ end
11
+ end
12
+ 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.5
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