github_changes 0.1.5 → 0.1.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: 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