github_changes 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6efe100e42e7b22b1a822f0c6ec5101d7302a12
4
- data.tar.gz: e884307d5dd06f4c5e6b4a8d55504b15093f709a
3
+ metadata.gz: c7eed4d44163ee873a8bd9f54545c684bf198e0f
4
+ data.tar.gz: 906288c0ad3c375f17600004a0ad4fa03beac063
5
5
  SHA512:
6
- metadata.gz: 80b94dc8517386aae094f0f22e1f0400ac48d0b90b1a7091bac2ad98e045eb479accadb8460700cb96254703b823618170d834676c823d0970f672e1e3691abb
7
- data.tar.gz: ef99918ed9f5e454780aaedc0bcb5d81809df2cde327257546967ac8265f033bf9674a4c89c7d99664920885979ba5f388d2fd92f92a1e9846985e8144da37b5
6
+ metadata.gz: 4f31590bde945802712fe14e6e6d9034bf2bfac72f0733bf371940f595ca222c437b12cfe9c65aaa97a324077a238cb66c36e2a4b4f7684c858b2ed94d9de7b9
7
+ data.tar.gz: 3d3d0c25c8b89f3bd800416c1448084af4459c0c1aed78a95b53d2f4376bd33a7563dd70af7e5b8dfb49545e6e65c8a4f2715fdaed8f3174ded879191b1a38f7
@@ -15,7 +15,7 @@ module ChangelogGenerator
15
15
  self.user = user
16
16
  self.repo_name = repo
17
17
  self.from_ref = from_ref
18
- self.to_ref = to_ref || "master"
18
+ self.to_ref = to_ref || "now"
19
19
  self.label_filter = label_filter
20
20
  end
21
21
 
@@ -33,92 +33,20 @@ module ChangelogGenerator
33
33
 
34
34
  private
35
35
 
36
- def run(cmd)
37
- # puts "Running: #{cmd}"
38
- `#{cmd}`
39
- end
40
-
41
- def clone_or_fetch_repo(user, repo, path)
42
- output = nil
43
-
44
- if Dir.exist? path
45
- output = run "cd #{path} && git fetch"
46
- else
47
- output = run "git clone --bare \"https://#{ENV['GITHUB_TOKEN']}@github.com/#{user}/#{repo}.git\" \"#{path}\""
48
- end
49
-
50
- unless $?.exitstatus == 0
36
+ def generate_changelog(user, repo, start_ref, end_ref, label_filter = nil)
37
+ unless check_github_response() { github.repos.get(user, repo) }
51
38
  abort "Unable to access repo `#{user}/#{repo}`. Please ensure correct spelling. If this repo is private you must ensure to configure me with a suitable GitHub oath token."
52
39
  end
53
40
 
54
- output
55
- end
56
-
57
- def is_ref?(ref)
58
- return false unless ref !~ /^\s*$/
59
- run "git show \"#{ref}\""
60
- $?.exitstatus == 0
61
- end
62
-
63
- def ref_before(date_string)
64
- output = run("git rev-list -1 --all --before=\"#{date_string}\"").chomp
65
- $?.exitstatus == 0 ? output : nil
66
- end
67
-
68
- def ref_after(date_string)
69
- output = run("git rev-list --all --after=\"#{date_string}\" | tail -1").chomp
70
- $?.exitstatus == 0 ? output : nil
71
- end
72
-
73
- def find_ref(string)
74
- return string if is_ref? string
75
- string = yield(string)
76
- is_ref?(string) ? string : nil
77
- end
78
-
79
- def find_shas_or_abort(start_ref, end_ref)
80
- start_sha = find_ref(start_ref) { |s| ref_after(s) }
81
- end_sha = find_ref(end_ref) { |s| ref_before(s) }
82
-
83
- unless start_sha
84
- abort "Unable to parse `#{start_ref}` as a reference or date. Please specify a git tag, branch, or SHA. You can also specify a date like `last week` or `5 days ago`"
85
- end
86
- unless end_sha
87
- abort "Unable to parse `#{end_ref}` as a reference or date. Please specify a git tag, branch, or SHA. You can also specify a date like `last week` or `5 days ago` or `January 1, 1999`"
88
- end
89
-
90
- return start_sha, end_sha
91
- end
92
-
93
- def pull_request_numbers(start_sha, end_sha)
94
- log_command = "git log #{start_sha}..#{end_sha}"
95
- log = `#{log_command} --grep "Merge pull" --reverse | grep "Merge pull request #"`
96
- pull_nums = log.split("\n").map { |p| p.match(/.*#(\d+) .*/)[1].to_i }
97
- end
98
-
99
- def filter_prs_by_label(github, user, repo, pull_nums, label_filter)
100
- pull_nums.select do |n|
101
- issue = github.issues.get user, repo, n
102
- label_names = issue.labels.map { |l| l.name }
103
- label_names.include?(label_filter)
104
- end
105
- end
106
-
107
- def generate_changelog(user, repo, start_ref, end_ref, label_filter = nil)
108
- path = "clones/#{user}/#{repo}.git"
109
-
110
- clone_or_fetch_repo(user, repo, path)
111
- FileUtils.cd(path) # Below methods assuming we are in git repo
112
- start_sha, end_sha = find_shas_or_abort(start_ref, end_ref)
113
- pull_nums = pull_request_numbers(start_sha, end_sha)
114
- pull_nums = filter_prs_by_label(github, user, repo, pull_nums, label_filter) if label_filter
41
+ start_sha, start_time, end_sha = parse_references(start_ref, end_ref)
42
+ pull_nums = pull_request_numbers(start_sha, start_time, end_sha)
43
+ pull_nums = filter_prs_by_label(pull_nums)
115
44
  abort "No PRs found matching criteria" if pull_nums.empty?
116
45
 
117
46
  pulls = pull_nums.map { |p| github.pull_requests.get(user, repo, p) }
118
47
  pulls = pulls.map { |p| PullRequest.from_github_pr(p) }
119
48
  # puts JSON.pretty_generate(pulls.first.body.to_hash)
120
49
 
121
- # puts "Finding connected issues:"
122
50
  pulls.each do |pull|
123
51
  issue_nums = connected_issues_from_pr(pull)
124
52
  github_issues = issue_nums.map { |n| github.issues.get(user, repo, n) }
@@ -163,6 +91,87 @@ module ChangelogGenerator
163
91
  value
164
92
  end
165
93
 
94
+ def run(cmd)
95
+ # puts "Running: #{cmd}"
96
+ `#{cmd}`
97
+ end
98
+
99
+ def find_ref_for_string(string)
100
+ ref = check_github_response() { github.git_data.references.get user, repo_name, URI::encode("heads/#{string}") }
101
+ ref ||= check_github_response() { github.git_data.references.get user, repo_name, URI::encode("tags/#{string}") }
102
+ return ref
103
+ end
104
+
105
+ def find_commit_sha_for_ref_string(string)
106
+ ref = find_ref_for_string string
107
+ return nil unless ref && ref.object && ref.object.type && ref.object.sha
108
+
109
+ case ref.object.type
110
+ when "commit"
111
+ ref.object.sha
112
+ when "tag"
113
+ tag = check_github_response() { github.git_data.tags.get user, repo_name, URI::encode(ref.object.sha) }
114
+ tag ? tag.object.sha : nil
115
+ end
116
+ end
117
+
118
+ def find_commit_sha_for_string(string)
119
+ return nil unless string && string.strip.length > 0
120
+
121
+ # Search references first becomes branches/tags seem more likely than commit SHA
122
+ sha = find_commit_sha_for_ref_string string
123
+ return sha if sha
124
+
125
+ # Maybe it is a commit SHA?
126
+ commit = check_github_response() { github.repos.commits.get user, repo_name, URI::encode(string) }
127
+ return commit.sha if commit
128
+ end
129
+
130
+ def parse_string_as_time(string)
131
+ Chronic.parse(string)
132
+ end
133
+
134
+ def commit_before(date)
135
+ response = check_github_response() { github.repos.commits.list user, repo_name, until: date.iso8601, :per_page => 1 }
136
+ return nil unless response
137
+ return response.first.sha
138
+ end
139
+
140
+ def end_sha(end_string)
141
+ ref = find_commit_sha_for_string(end_string)
142
+ return ref if ref
143
+
144
+ time = parse_string_as_time(end_string)
145
+ return nil unless time
146
+
147
+ commit_before(time)
148
+ end
149
+
150
+ def parse_references(start_ref, end_ref)
151
+ end_sha = end_sha(end_ref)
152
+ # We can start on a SHA or Time
153
+ start_sha = find_commit_sha_for_string(start_ref)
154
+ start_time = parse_string_as_time(start_ref)
155
+
156
+ unless start_sha || start_time
157
+ abort "Unable to parse `#{start_ref}` as a reference or date. Please specify a git tag, branch, or SHA. You can also specify a date like `last week` or `5 days ago`"
158
+ end
159
+ unless end_sha
160
+ abort "Unable to parse `#{end_ref}` as a reference or date. Please specify a git tag, branch, or SHA. You can also specify a date like `last week` or `5 days ago` or `January 1, 1999`"
161
+ end
162
+
163
+ return start_sha, start_time, end_sha
164
+ end
165
+
166
+ def filter_prs_by_label(pull_nums)
167
+ return pull_nums unless label_filter && label_filter.strip.length > 0
168
+ pull_nums.select do |n|
169
+ issue = github.issues.get user, repo_name, n
170
+ label_names = issue.labels.map { |l| l.name }
171
+ label_names.include?(label_filter)
172
+ end
173
+ end
174
+
166
175
  def changelog_from_pr(pr)
167
176
  default = "- #{pr['title']}"
168
177
 
@@ -175,11 +184,66 @@ module ChangelogGenerator
175
184
  matcher['changes'].strip
176
185
  end
177
186
 
187
+ def pull_num_from_commit(commit)
188
+ message = commit.commit.message
189
+ match = message.match(/merge pull request #(\d+)/i)
190
+ return nil unless match
191
+ match[1]
192
+ end
193
+
178
194
  def connected_issues_from_pr(pr)
179
195
  body = pr.body
180
196
  return [] unless body
181
197
 
182
198
  body.scan(/((connect|connects|fix|fixes|address|addresses):?\s*(to)?:?\s*#(?<number>\d+))/im).reject(&:nil?).map(&:last).flatten
183
199
  end
200
+
201
+ # Page through all commits in the range collecting PR numbers
202
+ def pull_request_numbers(start_sha, start_time, end_sha)
203
+ pull_nums = []
204
+
205
+ if start_sha
206
+ # First we do a compare
207
+ response = check_github_response() { github.repos.commits.compare user, repo_name, start_sha, end_sha }
208
+ abort "Unable to compare from #{from_ref} to #{to_ref}. Tried `#{start_sha}..#{end_sha}`" unless response
209
+ if response
210
+ commits = response.commits
211
+ if response.total_commits < 250 # This API won't return more than 250 - we have to go pagination mode below for that
212
+ return commits.reduce([]) do |memo, commit|
213
+ pull_num = pull_num_from_commit(commit)
214
+ memo << pull_num if pull_num
215
+ memo
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ response = check_github_response() { github.repos.commits.list user, repo_name, sha: end_sha, :per_page => 100 }
222
+ abort "Something went wrong fetching commit information" unless response
223
+ pull_nums = []
224
+ loop do
225
+ done = false
226
+ commits = response.body
227
+ commits.each do |commit|
228
+ if (!start_sha && start_time) && start_time > Chronic.parse(commit.commit.committer.date)
229
+ done = true
230
+ break
231
+ end
232
+
233
+ pull_num = pull_num_from_commit(commit)
234
+ pull_nums << pull_num if pull_num
235
+
236
+ if start_sha && commit.sha == start_sha
237
+ done = true
238
+ break
239
+ end
240
+ end
241
+ break if done
242
+ break unless response.has_next_page?
243
+ response = response.next_page
244
+ end
245
+
246
+ pull_nums
247
+ end
184
248
  end
185
249
  end
@@ -1,3 +1,3 @@
1
1
  module ChangelogGenerator
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github_changes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Rayment
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-30 00:00:00.000000000 Z
11
+ date: 2016-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor