gh-pr-backport 0.1.0.alpha2 → 0.1.0.alpha3
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/Gemfile.lock +1 -1
- data/exe/gh-pr-backport-at-once +6 -0
- data/lib/gh_pr_backport.rb +2 -0
- data/lib/gh_pr_backport/at_once_backporter.rb +94 -0
- data/lib/gh_pr_backport/backporter.rb +2 -21
- data/lib/gh_pr_backport/common.rb +25 -0
- data/lib/gh_pr_backport/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fd9ac1d7f61467e3a140371a8ccf44623c929458e5e81653131ecbff31dc12d
|
4
|
+
data.tar.gz: f40d8da0820b9c29eb1e393c17a5a7a7f4ba00eb69fad170e16ffb3e633285f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c6feefcaedf0e35e70fc0995553342b980c6e3128c3c7140adc62eb824773e8c7e47d3bfb28d54b8c8ff19c3adeb2cf40caef663025da54558de161a76a5d7e
|
7
|
+
data.tar.gz: 5bbda3418e08593d87ee9c1d21106140f0158af05c182159233f26edf5c4e0aa94d4d1ade4a1d5b767a800c07078fd60f00a98b71cecbfc9d5059ae14f2f6642
|
data/Gemfile.lock
CHANGED
data/lib/gh_pr_backport.rb
CHANGED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
|
3
|
+
module GhPrBackport
|
4
|
+
class AtOnceBackporter
|
5
|
+
include GhPrBackport::Common
|
6
|
+
|
7
|
+
def run
|
8
|
+
raise GhPrBackport::DirectoryIsMessy unless clean?
|
9
|
+
create_todo_file
|
10
|
+
open_editor
|
11
|
+
run_todos_from_file
|
12
|
+
end
|
13
|
+
|
14
|
+
def open_editor
|
15
|
+
unless system("#{optional_str ENV['EDITOR'], 'vim'} #{todo_file}")
|
16
|
+
raise 'Editor returned non-zero exit status.'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_todos_from_file
|
21
|
+
todo_commits = read_todo_file
|
22
|
+
if todo_commits.empty?
|
23
|
+
puts 'Nothing to do.'
|
24
|
+
return
|
25
|
+
end
|
26
|
+
system("git cherry-pick -m 1 -x #{todo_commits.join(' ')}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def list_todo_prs
|
30
|
+
picked_pr_numbers = list_picked_prs.map { |commit| commit[:pr_number] }.to_set
|
31
|
+
list_merged_prs.select { |commit| !picked_pr_numbers.include?(commit[:pr_number]) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def list_merged_prs
|
35
|
+
parse_log_stream(`git log --merges #{log_format_option} HEAD..origin/HEAD`)
|
36
|
+
.select { |commit| commit[:pr_number] }
|
37
|
+
end
|
38
|
+
|
39
|
+
def list_picked_prs
|
40
|
+
parse_log_stream(`git log #{log_format_option} origin/HEAD..HEAD`)
|
41
|
+
.select { |commit| commit[:pr_number] }
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def git_dir
|
47
|
+
optional_str ENV['GIT_DIR'], '.git'
|
48
|
+
end
|
49
|
+
|
50
|
+
def todo_file
|
51
|
+
File.join(git_dir, '.git-pr-backport-todo')
|
52
|
+
end
|
53
|
+
|
54
|
+
def read_todo_file
|
55
|
+
File.readlines(todo_file)
|
56
|
+
.map(&:strip)
|
57
|
+
.reject { |line| line == '' || line.start_with?('#') }
|
58
|
+
.each_with_index { |line, i| raise "Parse error in line #{i + 1}: #{line}" unless line =~ /^[0-9A-Za-z]+(?:\s|\z)/ }
|
59
|
+
.map { |line| line.split(/\s+/, 2)[0] }
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_todo_file
|
63
|
+
File.write(todo_file, list_todo_prs.map do |commit|
|
64
|
+
"# #{commit[:hash][0..7]} ##{commit[:pr_number]} #{commit[:body].lines[0]} (#{pr_to_link(commit)})"
|
65
|
+
end.join("\n"))
|
66
|
+
end
|
67
|
+
|
68
|
+
def pr_to_link(commit)
|
69
|
+
"#{repo.url}/pull/#{commit[:pr_number]}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def log_format_option
|
73
|
+
# null terminated
|
74
|
+
'--format=format:%H%n%B%x00'
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse_log_stream(stream)
|
78
|
+
stream
|
79
|
+
.split("\0\n")
|
80
|
+
.map { |commit_data| parse_commit_data(commit_data) }
|
81
|
+
.reverse
|
82
|
+
end
|
83
|
+
|
84
|
+
def parse_commit_data(commit_data)
|
85
|
+
hash, subject, body = commit_data.split("\n", 3).map(&:strip)
|
86
|
+
pr_number = subject.match(/\AMerge pull request #([1-9][0-9]*) from/)&.tap { |m| break m[1].to_i }
|
87
|
+
{ hash: hash, pr_number: pr_number, subject: subject, body: body || '' }
|
88
|
+
end
|
89
|
+
|
90
|
+
def optional_str(str, default)
|
91
|
+
str == '' ? default : str || default
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
3
|
require 'hashie'
|
4
|
-
require 'octokit'
|
5
4
|
|
6
5
|
module GhPrBackport
|
7
6
|
class Backporter
|
7
|
+
include GhPrBackport::Common
|
8
|
+
|
8
9
|
def initialize(original_pr_number:, staging_branch: nil)
|
9
10
|
@client = client
|
10
11
|
@repo = repo
|
@@ -39,16 +40,6 @@ module GhPrBackport
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
|
-
def client
|
43
|
-
client = Octokit::Client.new(access_token: `git config backport.token`.chomp)
|
44
|
-
client.scopes # Validate token. If the token is invalid, then raise an error.
|
45
|
-
client
|
46
|
-
end
|
47
|
-
|
48
|
-
def clean?
|
49
|
-
`git status --porcelain`.chomp.empty?
|
50
|
-
end
|
51
|
-
|
52
43
|
def create_backport_pull_request
|
53
44
|
body = "##{@original.number} のバックポートです\r\n\r\n" +
|
54
45
|
@original.body.lines.map { |l| "> #{l}" }.join
|
@@ -87,16 +78,6 @@ module GhPrBackport
|
|
87
78
|
`git config -f #{path}/.git-pr-release pr-release.branch.staging`.chomp
|
88
79
|
end
|
89
80
|
|
90
|
-
def repo
|
91
|
-
remote = `git config remote.origin.url`.chomp
|
92
|
-
repo_name = if remote.start_with?('git@github.com:')
|
93
|
-
remote.split(':', 2)[1].sub(/.git$/, '')
|
94
|
-
else
|
95
|
-
URI.parse(remote).path.sub(%r{^\/}, '').sub(/.git$/, '')
|
96
|
-
end
|
97
|
-
Octokit::Repository.new(repo_name)
|
98
|
-
end
|
99
|
-
|
100
81
|
def system!(program, *args, error_class)
|
101
82
|
raise error_class unless system(program, *args)
|
102
83
|
true
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
|
3
|
+
module GhPrBackport
|
4
|
+
module Common
|
5
|
+
def client
|
6
|
+
client = Octokit::Client.new(access_token: `git config backport.token`.chomp)
|
7
|
+
client.scopes # Validate token. If the token is invalid, then raise an error.
|
8
|
+
client
|
9
|
+
end
|
10
|
+
|
11
|
+
def clean?
|
12
|
+
`git status --porcelain`.chomp.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def repo
|
16
|
+
remote = `git config remote.origin.url`.chomp
|
17
|
+
repo_name = if remote.start_with?('git@github.com:')
|
18
|
+
remote.split(':', 2)[1].sub(/.git$/, '')
|
19
|
+
else
|
20
|
+
URI.parse(remote).path.sub(%r{^\/}, '').sub(/.git$/, '')
|
21
|
+
end
|
22
|
+
Octokit::Repository.new(repo_name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gh-pr-backport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.alpha3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takeru Naito
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -111,6 +111,7 @@ email:
|
|
111
111
|
- takeru.naito@gmail.com
|
112
112
|
executables:
|
113
113
|
- gh-pr-backport
|
114
|
+
- gh-pr-backport-at-once
|
114
115
|
extensions: []
|
115
116
|
extra_rdoc_files: []
|
116
117
|
files:
|
@@ -127,9 +128,12 @@ files:
|
|
127
128
|
- bin/console
|
128
129
|
- bin/setup
|
129
130
|
- exe/gh-pr-backport
|
131
|
+
- exe/gh-pr-backport-at-once
|
130
132
|
- gh-pr-backport.gemspec
|
131
133
|
- lib/gh_pr_backport.rb
|
134
|
+
- lib/gh_pr_backport/at_once_backporter.rb
|
132
135
|
- lib/gh_pr_backport/backporter.rb
|
136
|
+
- lib/gh_pr_backport/common.rb
|
133
137
|
- lib/gh_pr_backport/version.rb
|
134
138
|
homepage: https://github.com/elim/gh-pr-backport
|
135
139
|
licenses:
|