github_flow_cli 0.1.3 → 0.1.4
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/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/exe/hubflow +3 -1
- data/lib/github_flow_cli/api.rb +68 -69
- data/lib/github_flow_cli/config.rb +39 -40
- data/lib/github_flow_cli/local.rb +23 -24
- data/lib/github_flow_cli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5abdfc79058f475a76efa21e46941c246aa7bd2
|
4
|
+
data.tar.gz: 9f3cea48ab06b373bba56641c2ebd8d6bce3c660
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20b9e79a527f2aa9b712837f55b646a481c724d1c36b7f548e01b3a24b199a695bac49954a124452e28cf1c3a5a91072a2d82225d611b7463bbeb02e8ee6e115
|
7
|
+
data.tar.gz: 202531dc42b3b330b17459995ddbf93d4bc35d8b6cd8e7608836be5be0008cc05c192e2009e6f0c108a5644ce005c03308eebb5def86a530380f6f67f3504d3f
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/exe/hubflow
CHANGED
data/lib/github_flow_cli/api.rb
CHANGED
@@ -2,87 +2,86 @@ require 'octokit'
|
|
2
2
|
require_relative 'local'
|
3
3
|
|
4
4
|
module GithubFlowCli
|
5
|
-
class API
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
client.create_authorization(auth_config).token
|
18
|
-
rescue Octokit::UnprocessableEntity => ex
|
19
|
-
if ex.message =~ /already_exists/
|
20
|
-
id = client.authorizations.find { |auth| auth[:note] == app_name }.id
|
21
|
-
client.delete_authorization(id)
|
22
|
-
retry
|
23
|
-
else
|
24
|
-
raise
|
25
|
-
end
|
5
|
+
class API; end
|
6
|
+
class << API
|
7
|
+
# @return [String] OAuth token
|
8
|
+
def authorize(username, password, two_factor_token: nil)
|
9
|
+
client = Octokit::Client.new(login: username, password: password)
|
10
|
+
auth_config = {
|
11
|
+
scopes: ['user', 'repo', 'admin:repo_hook'],
|
12
|
+
note: app_name,
|
13
|
+
}
|
14
|
+
if two_factor_token
|
15
|
+
auth_config.merge!(:headers => { "X-GitHub-OTP" => two_factor_token })
|
26
16
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
17
|
+
client.create_authorization(auth_config).token
|
18
|
+
rescue Octokit::UnprocessableEntity => ex
|
19
|
+
if ex.message =~ /already_exists/
|
20
|
+
id = client.authorizations.find { |auth| auth[:note] == app_name }.id
|
21
|
+
client.delete_authorization(id)
|
22
|
+
retry
|
23
|
+
else
|
24
|
+
raise
|
30
25
|
end
|
26
|
+
end
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
def use_oauth_token(token)
|
29
|
+
@client = Octokit::Client.new(access_token: token)
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid?
|
33
|
+
!user[:login].nil?
|
34
|
+
rescue Octokit::Unauthorized
|
35
|
+
false
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
return send(method, *args, &block)
|
38
|
+
# delegate API calls to Octokit::Client
|
39
|
+
def method_missing(method, *args, &block)
|
40
|
+
if @client.respond_to?(method)
|
41
|
+
define_singleton_method(method) do |*args, &block|
|
42
|
+
@client.send(method, *args, &block)
|
45
43
|
end
|
46
|
-
|
44
|
+
return send(method, *args, &block)
|
47
45
|
end
|
46
|
+
super
|
47
|
+
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
# TODO: explicify options
|
50
|
+
# :assignee (String) — User login.
|
51
|
+
# :milestone (Integer) — Milestone number.
|
52
|
+
# :labels
|
53
|
+
# TODO: keywordify parameters
|
54
|
+
def create_issue(title, body = nil, options = {})
|
55
|
+
@client.create_issue(Local.repo, title, body, options)
|
56
|
+
end
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# TODO: custom default remote
|
69
|
-
puts "no remote branch found, creating remote branch..."
|
70
|
-
Local.git.config("branch.#{branch_name}.remote", 'origin')
|
71
|
-
Local.git.config("branch.#{branch_name}.merge", "refs/heads/#{branch_name}")
|
72
|
-
end
|
58
|
+
# TODO: other options
|
59
|
+
def create_pr(base: "master", title: nil, body: nil)
|
60
|
+
branch_name = Local.git.current_branch
|
61
|
+
issue_number = Config.branch_issue_map[branch_name]
|
62
|
+
if issue_number
|
63
|
+
issue = API.issue(Local.repo, issue_number)
|
64
|
+
title ||= issue.title
|
65
|
+
body ||= issue.body
|
66
|
+
end
|
67
|
+
unless Local.git.branches.remote.find { |b| b.name == branch_name }
|
73
68
|
# TODO: custom default remote
|
74
|
-
puts "
|
75
|
-
Local.git.
|
76
|
-
|
77
|
-
|
78
|
-
|
69
|
+
puts "no remote branch found, creating remote branch..."
|
70
|
+
Local.git.config("branch.#{branch_name}.remote", 'origin')
|
71
|
+
Local.git.config("branch.#{branch_name}.merge", "refs/heads/#{branch_name}")
|
72
|
+
end
|
73
|
+
# TODO: custom default remote
|
74
|
+
puts "git push..."
|
75
|
+
Local.git.push('origin', branch_name)
|
76
|
+
@client.create_pull_request(Local.repo, base, branch_name, title, body).tap do |pr|
|
77
|
+
Config.link_pr_to_branch(pr, branch_name)
|
79
78
|
end
|
79
|
+
end
|
80
80
|
|
81
|
-
|
81
|
+
private
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
end
|
83
|
+
def app_name
|
84
|
+
"hubflow for #{`whoami`.strip}@#{`hostname`.strip}"
|
86
85
|
end
|
87
86
|
end
|
88
87
|
end
|
@@ -4,59 +4,58 @@ require_relative 'api'
|
|
4
4
|
require_relative 'local'
|
5
5
|
|
6
6
|
module GithubFlowCli
|
7
|
-
class Config
|
7
|
+
class Config; end
|
8
|
+
class << Config
|
8
9
|
CONFIG_DIR = File.expand_path('~/.config')
|
9
10
|
CONFIG_FILE = 'hubflow'
|
10
11
|
KEYS = %w[username oauth_token branch_issue_map pr_branch_map]
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
exit(1)
|
23
|
-
end
|
24
|
-
else
|
25
|
-
puts "please login first."
|
26
|
-
exit(2)
|
13
|
+
attr_accessor *KEYS
|
14
|
+
|
15
|
+
def setup
|
16
|
+
if File.file?(config_path)
|
17
|
+
load
|
18
|
+
API.use_oauth_token(oauth_token)
|
19
|
+
unless API.valid?
|
20
|
+
puts "WARN: authentication failed, please retry login."
|
21
|
+
File.delete(config_path)
|
22
|
+
exit(1)
|
27
23
|
end
|
24
|
+
else
|
25
|
+
puts "please login first."
|
26
|
+
exit(2)
|
28
27
|
end
|
28
|
+
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
def link_branch_to_issue(branch_name, issue)
|
31
|
+
self.branch_issue_map[branch_name] = issue.number
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
def link_pr_to_branch(pr, branch_name)
|
35
|
+
self.pr_branch_map[pr.number] = branch_name
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def load
|
39
|
+
YAML::load_file(config_path).each { |k, v| send("#{k}=", v) }
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
def save!
|
43
|
+
self.branch_issue_map ||= {}
|
44
|
+
self.pr_branch_map ||= {}
|
45
|
+
File.open(config_path, 'w') { |f| f.write(to_h.to_yaml) }
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def to_h
|
49
|
+
KEYS.map{ |k| [k, send(k)] }.to_h
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
def valid?
|
53
|
+
KEYS.all? { |c| send(c) }
|
54
|
+
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
56
|
+
def config_path
|
57
|
+
FileUtils.mkdir_p(CONFIG_DIR) unless File.directory?(CONFIG_DIR)
|
58
|
+
File.join(CONFIG_DIR, CONFIG_FILE)
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
@@ -1,34 +1,33 @@
|
|
1
1
|
require 'git'
|
2
2
|
|
3
3
|
module GithubFlowCli
|
4
|
-
class Local
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
4
|
+
class Local; end
|
5
|
+
class << Local
|
6
|
+
def repo
|
7
|
+
return @repo if @repo
|
8
|
+
url = git.remote.url
|
9
|
+
match = url&.match(%r{.*[:/](?<owner>.*?)/(?<name>.*?)(\.git)?$})
|
10
|
+
return nil unless match && match[:owner] && match[:name]
|
11
|
+
@repo = Octokit::Repository.from_url("/#{match[:owner]}/#{match[:name]}")
|
12
|
+
rescue ArgumentError => ex
|
13
|
+
if ex.message =~ /path does not exist/
|
14
|
+
nil
|
15
|
+
else
|
16
|
+
raise
|
18
17
|
end
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def git
|
21
|
+
@git ||= Git.open(git_dir)
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
current
|
24
|
+
def git_dir
|
25
|
+
current = File.expand_path('.')
|
26
|
+
while !File.directory?(File.join(current, '.git'))
|
27
|
+
current = File.dirname(current)
|
28
|
+
break if current == '/'
|
31
29
|
end
|
30
|
+
current
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github_flow_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yang Liu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: facets
|