prreview 0.5.1 → 0.6.0

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
  SHA256:
3
- metadata.gz: 28b817e16bf9a5637315d36b0dd477f851a80a03c1aa61988fdb521de6458dae
4
- data.tar.gz: 44da1b71ce4de6cfe5ec280ee5eda07559ba28d2c5e9fcfda8a52fe30f9af899
3
+ metadata.gz: 0e70c1efe8d054fde07f26a2a4830ec6d267bfcf1c1476c1acefbfda3f1a98a5
4
+ data.tar.gz: 9e18b68ab00cfb79c464b03e6ccaa0e7381420d5e74cd332b6e6c35cd597d30c
5
5
  SHA512:
6
- metadata.gz: 30d0092f74f555b89c2bc43c3badc141219c66b7f95c36e7084994ad3ed979abd997935454b141feb5ee72b20a0a75949b0260d062f84a04669f088592529369
7
- data.tar.gz: cf0b141c62a2142417a784b42a9c9f323ec10406b378c5dfb998d53bc27a6245e0e8a4556a009e85510ca546a07462629d28d10a136da871f68dfa9336e53c70
6
+ metadata.gz: c0afeacc8f117863e7b92623d98c81e84bb765957b59f0bcffd2558dd8a978a594e4857e5ecae1172223f06554af1f8ed795bcbdfb96b2b8ec348eac1fbb24e6
7
+ data.tar.gz: bc8bbafaca87a04880f2eb4fda82c5493d3eda67d61cc22840c2ad1f7dc43688a993ae6327c9b94425f1f1fadd1c5876f1a1899c710065e0f2f0d40c1a135f51
data/.rubocop.yml CHANGED
@@ -26,5 +26,8 @@ Metrics/CyclomaticComplexity:
26
26
  Metrics/ParameterLists:
27
27
  Enabled: false
28
28
 
29
+ Metrics/PerceivedComplexity:
30
+ Enabled: false
31
+
29
32
  Naming/MethodParameterName:
30
33
  Enabled: false
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prreview
4
- VERSION = '0.5.1'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/prreview.rb CHANGED
@@ -10,7 +10,14 @@ require 'optparse'
10
10
 
11
11
  module Prreview
12
12
  class CLI
13
- DEFAULT_PROMPT = 'Your task is to review this pull request. Do you see any problems there?'
13
+ DEFAULT_PROMPT = <<~PROMPT
14
+ Your task is to review this pull request.
15
+ Patch lines starting with `-` are deleted.
16
+ Patch lines starting with `+` are added.
17
+ Focus on new problems, not ones that were already there.
18
+ Do you see any problems?
19
+ PROMPT
20
+
14
21
  DEFAULT_LINKED_ISSUES_LIMIT = 5
15
22
 
16
23
  # url or owner/repo#123 or #123
@@ -38,7 +45,7 @@ module Prreview
38
45
  def process
39
46
  load_optional_files
40
47
  begin
41
- fetch_pull_request
48
+ fetch_pr
42
49
  fetch_linked_issues
43
50
  rescue Octokit::Unauthorized
44
51
  abort 'Error: Invalid GITHUB_TOKEN.'
@@ -106,26 +113,21 @@ module Prreview
106
113
  @client = Octokit::Client.new(access_token:, auto_paginate: true)
107
114
  end
108
115
 
109
- def fetch_pull_request
116
+ def fetch_pr
110
117
  puts "Fetching PR ##{@pr_number} for #{@full_repo}"
111
118
 
112
- @pull_request = @client.pull_request(@full_repo, @pr_number)
113
- @comments = @client.issue_comments(@full_repo, @pr_number).map(&:body)
114
- @commits = @client.pull_request_commits(@full_repo, @pr_number).map { |c| c.commit.message }
115
- @files = @client.pull_request_files(@full_repo, @pr_number).map do |file|
116
- {
117
- filename: file.filename,
118
- patch: file.patch || '(no patch data)',
119
- content: @include_content && !skip_file?(file.filename) ? fetch_file_content(file.filename) : '(no content)'
120
- }
121
- end
119
+ @pr = @client.pull_request(@full_repo, @pr_number)
120
+ @pr_comments = @client.issue_comments(@full_repo, @pr_number)
121
+ @pr_code_comments = @client.pull_request_comments(@full_repo, @pr_number)
122
+ @pr_commits = @client.pull_request_commits(@full_repo, @pr_number)
123
+ @pr_files = @client.pull_request_files(@full_repo, @pr_number)
122
124
  end
123
125
 
124
126
  def fetch_file_content(path)
125
127
  puts "Fetching #{path}"
126
128
 
127
- content = @client.contents(@full_repo, path:, ref: @pull_request.head.sha)
128
- decoded = Base64.decode64(content[:content])
129
+ content = @client.contents(@full_repo, path:, ref: @pr.head.sha)
130
+ decoded = Base64.decode64(content.content)
129
131
  binary?(decoded) ? '(binary file)' : decoded
130
132
  rescue Octokit::NotFound
131
133
  '(file content not found)'
@@ -134,7 +136,7 @@ module Prreview
134
136
  def fetch_linked_issues
135
137
  @linked_issues = []
136
138
 
137
- text = [@pull_request.body, *@comments].join("\n")
139
+ text = [@pr.body, *@pr_comments.map(&:body), *@pr_code_comments.map(&:body)].join("\n")
138
140
  queue = extract_refs(text, URL_REGEX)
139
141
  seen = Set.new
140
142
 
@@ -145,12 +147,12 @@ module Prreview
145
147
 
146
148
  seen << key
147
149
 
148
- issue = fetch_linked_issue(ref)
149
- next unless issue
150
+ linked_issue = fetch_linked_issue(ref)
151
+ next unless linked_issue
150
152
 
151
- @linked_issues << issue
153
+ @linked_issues << linked_issue
152
154
 
153
- new_text = [issue[:description], *issue[:comments]].join("\n")
155
+ new_text = [linked_issue[:issue].body, *linked_issue[:comments].map(&:body)].join("\n")
154
156
  new_refs = extract_refs(new_text, URL_REGEX).reject { |nref| seen.include?(nref[:key]) }
155
157
  queue.concat(new_refs)
156
158
  end
@@ -174,65 +176,97 @@ module Prreview
174
176
  m = Regexp.last_match
175
177
  next unless m[:number]
176
178
 
177
- {
178
- owner: m[:owner] || @owner,
179
- repo: m[:repo] || @repo,
180
- number: m[:number].to_i,
181
- key: "#{m[:owner]}/#{m[:repo]}##{m[:number]}"
182
- }
179
+ owner = m[:owner] || @owner
180
+ repo = m[:repo] || @repo
181
+ number = m[:number].to_i
182
+ key = "#{owner}/#{repo}##{number}"
183
+
184
+ { owner:, repo:, number:, key: }
183
185
  end
184
186
  end
185
187
 
186
188
  def fetch_linked_issue(ref)
187
- full_repo = "#{ref[:owner]}/#{ref[:repo]}"
189
+ issue_path = "#{ref[:owner]}/#{ref[:repo]}"
188
190
  number = ref[:number]
189
191
 
190
- puts "Fetching linked issue ##{number} for #{full_repo}"
192
+ puts "Fetching linked issue ##{number} for #{issue_path}"
191
193
 
192
- issue = @client.issue(full_repo, number)
193
194
  {
194
- full_repo:,
195
- number:,
196
- title: issue.title,
197
- description: issue.body,
198
- comments: @client.issue_comments(full_repo, number).map(&:body)
195
+ issue: @client.issue(issue_path, number),
196
+ comments: @client.issue_comments(issue_path, number)
199
197
  }
200
198
  rescue Octokit::NotFound
201
- warn "Linked issue #{number} for #{full_repo} not found, skipping"
199
+ warn "Linked issue #{number} for #{issue_path} not found, skipping"
202
200
  nil
203
201
  end
204
202
 
205
203
  def build_xml
206
204
  builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |x|
207
205
  x.prompt do
208
- x.task @prompt
206
+ x.your_task @prompt
209
207
  x.current_date DateTime.now
210
208
 
211
209
  x.pull_request do
212
- x.number @pr_number
213
- x.title @pull_request.title
214
- x.description @pull_request.body
215
-
216
- @comments.each { |c| x.comment_ c }
217
- @commits.each { |m| x.commit m }
218
-
219
- @files.each do |file|
220
- x.file do
221
- x.filename file[:filename]
222
- x.content file[:content]
223
- x.patch extract_patch(file)
210
+ build_issue(x, @pr)
211
+
212
+ x.commits do
213
+ @pr_commits.each do |c|
214
+ x.commit do
215
+ x.commiter c.committer&.login
216
+ x.message c.commit.message
217
+ x.date c.commit.committer&.date
218
+ end
219
+ end
220
+ end
221
+
222
+ x.comments do
223
+ @pr_comments.each do |c|
224
+ x.comment_ do
225
+ build_comment(x, c)
226
+ end
227
+ end
228
+ end
229
+
230
+ x.code_comments do
231
+ @pr_code_comments.each do |c|
232
+ x.code_comment do
233
+ build_comment(x, c)
234
+ x.path c.path
235
+ x.line c.line
236
+ end
237
+ end
238
+ end
239
+
240
+ x.pull_request_files do
241
+ @pr_files.each do |f|
242
+ content = fetch_file_content(f.filename) if @include_content && !skip_file?(f.filename)
243
+ patch = extract_patch(f) || '(no patch data)'
244
+
245
+ x.file do
246
+ x.filename f.filename
247
+ x.content(content) if content
248
+ x.patch patch
249
+ end
224
250
  end
225
251
  end
226
252
  end
227
253
 
228
- @linked_issues.each do |issue|
229
- x.linked_issue do
230
- x.repo issue[:full_repo]
231
- x.number issue[:number]
232
- x.title issue[:title]
233
- x.description issue[:description]
254
+ x.linked_issues do
255
+ @linked_issues.each do |linked_issue|
256
+ issue = linked_issue[:issue]
257
+ comments = linked_issue[:comments]
258
+
259
+ x.linked_issue do
260
+ build_issue(x, issue)
234
261
 
235
- issue[:comments].each { |c| x.comment_ c }
262
+ x.comments do
263
+ comments.each do |c|
264
+ x.comment_ do
265
+ build_comment(x, c)
266
+ end
267
+ end
268
+ end
269
+ end
236
270
  end
237
271
  end
238
272
 
@@ -247,17 +281,32 @@ module Prreview
247
281
  end
248
282
  end
249
283
 
250
- x.task @prompt
284
+ # Intentionally duplicate the prompt to remind LLM about the task
285
+ x.your_task @prompt
251
286
  end
252
287
  end
253
288
 
254
289
  @xml = builder.doc.root.to_xml
255
290
  end
256
291
 
292
+ def build_issue(xml, issue)
293
+ xml.url issue.html_url
294
+ xml.user issue.user.login
295
+ xml.title issue.title
296
+ xml.body issue.body
297
+ xml.created_at issue.created_at
298
+ end
299
+
300
+ def build_comment(xml, comment)
301
+ xml.user comment.user.login
302
+ xml.body comment.body
303
+ xml.created_at comment.created_at
304
+ end
305
+
257
306
  def extract_patch(file)
258
- return if skip_file?(file[:filename])
307
+ return if skip_file?(file.filename)
259
308
 
260
- file[:patch]
309
+ file.patch
261
310
  end
262
311
 
263
312
  def skip_file?(filename)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prreview
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgenii Morozov