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 +4 -4
- data/.rubocop.yml +3 -0
- data/lib/prreview/version.rb +1 -1
- data/lib/prreview.rb +107 -58
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e70c1efe8d054fde07f26a2a4830ec6d267bfcf1c1476c1acefbfda3f1a98a5
|
4
|
+
data.tar.gz: 9e18b68ab00cfb79c464b03e6ccaa0e7381420d5e74cd332b6e6c35cd597d30c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0afeacc8f117863e7b92623d98c81e84bb765957b59f0bcffd2558dd8a978a594e4857e5ecae1172223f06554af1f8ed795bcbdfb96b2b8ec348eac1fbb24e6
|
7
|
+
data.tar.gz: bc8bbafaca87a04880f2eb4fda82c5493d3eda67d61cc22840c2ad1f7dc43688a993ae6327c9b94425f1f1fadd1c5876f1a1899c710065e0f2f0d40c1a135f51
|
data/.rubocop.yml
CHANGED
data/lib/prreview/version.rb
CHANGED
data/lib/prreview.rb
CHANGED
@@ -10,7 +10,14 @@ require 'optparse'
|
|
10
10
|
|
11
11
|
module Prreview
|
12
12
|
class CLI
|
13
|
-
DEFAULT_PROMPT =
|
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
|
-
|
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
|
116
|
+
def fetch_pr
|
110
117
|
puts "Fetching PR ##{@pr_number} for #{@full_repo}"
|
111
118
|
|
112
|
-
@
|
113
|
-
@
|
114
|
-
@
|
115
|
-
@
|
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: @
|
128
|
-
decoded = Base64.decode64(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 = [@
|
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
|
-
|
149
|
-
next unless
|
150
|
+
linked_issue = fetch_linked_issue(ref)
|
151
|
+
next unless linked_issue
|
150
152
|
|
151
|
-
@linked_issues <<
|
153
|
+
@linked_issues << linked_issue
|
152
154
|
|
153
|
-
new_text = [
|
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
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
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
|
-
|
189
|
+
issue_path = "#{ref[:owner]}/#{ref[:repo]}"
|
188
190
|
number = ref[:number]
|
189
191
|
|
190
|
-
puts "Fetching linked issue ##{number} for #{
|
192
|
+
puts "Fetching linked issue ##{number} for #{issue_path}"
|
191
193
|
|
192
|
-
issue = @client.issue(full_repo, number)
|
193
194
|
{
|
194
|
-
|
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 #{
|
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.
|
206
|
+
x.your_task @prompt
|
209
207
|
x.current_date DateTime.now
|
210
208
|
|
211
209
|
x.pull_request do
|
212
|
-
x
|
213
|
-
|
214
|
-
x.
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
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
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
x.
|
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
|
-
|
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
|
-
|
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
|
307
|
+
return if skip_file?(file.filename)
|
259
308
|
|
260
|
-
file
|
309
|
+
file.patch
|
261
310
|
end
|
262
311
|
|
263
312
|
def skip_file?(filename)
|