pronto-github_resolver 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/pronto/github_resolver/version.rb +1 -1
- data/lib/pronto/github_resolver.rb +98 -1
- 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: 152e4319e389105c14b8c208f8b668c17a25eafbab0f1270b00c071994f9320c
|
4
|
+
data.tar.gz: b7a1b40e35543a93e7924e82a7b3596e35ac9e416df34855939112e5222db953
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46e7f768e794754c2e2d1159779332f980408d77f5fe4c88f825ed63c27c85dad49318c66da9236ca05d133532de5c6d20a3d39df9c8bd68eef7141bf1763368
|
7
|
+
data.tar.gz: '0758a279f57ba8c0a153528f0b2b06ab3baee909e396e92c86845b86672f18d312ec41f9efbc574f45cf5aa1ec093f988ae728fd987a72e3d571b31f074d5201'
|
data/Gemfile.lock
CHANGED
@@ -6,6 +6,20 @@ require 'pronto'
|
|
6
6
|
module Pronto
|
7
7
|
|
8
8
|
class Github < Client
|
9
|
+
# pronto messes up relative paths and does not have tests for this, patch to add repo.path.join
|
10
|
+
def pull_comments(sha)
|
11
|
+
@comment_cache["#{pull_id}/#{sha}"] ||= begin
|
12
|
+
client.pull_comments(slug, pull_id).map do |comment|
|
13
|
+
Comment.new(sha, comment.body, @repo.path.join(comment.path),
|
14
|
+
comment.position || comment.original_position)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
rescue Octokit::NotFound => e
|
18
|
+
@config.logger.log("Error raised and rescued: #{e}")
|
19
|
+
msg = "Pull request for sha #{sha} with id #{pull_id} was not found."
|
20
|
+
raise Pronto::Error, msg
|
21
|
+
end
|
22
|
+
|
9
23
|
def publish_pull_request_comments(comments, event: nil)
|
10
24
|
comments_left = comments.clone
|
11
25
|
while comments_left.any?
|
@@ -40,7 +54,72 @@ module Pronto
|
|
40
54
|
end
|
41
55
|
|
42
56
|
def bot_user_id
|
43
|
-
|
57
|
+
bot_user.id
|
58
|
+
end
|
59
|
+
|
60
|
+
def bot_user
|
61
|
+
@bot_user ||= client.user
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_review_threads
|
65
|
+
owner, repo_name = (slug || "").split('/')
|
66
|
+
res = client.post :graphql, { query: <<~GQL }.to_json
|
67
|
+
query getUserId {
|
68
|
+
repository(owner: "#{owner}", name: "#{repo_name}") {
|
69
|
+
pullRequest: issueOrPullRequest(number: #{pull_id}) {
|
70
|
+
... on PullRequest {
|
71
|
+
reviewThreads(last:100) {
|
72
|
+
totalCount
|
73
|
+
nodes {
|
74
|
+
id
|
75
|
+
comments(last: 10) {
|
76
|
+
nodes {
|
77
|
+
author { ... on Node { id } }
|
78
|
+
viewerDidAuthor
|
79
|
+
path position body
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
GQL
|
89
|
+
|
90
|
+
if res.errors || !res.data
|
91
|
+
# ex: [{:message=>"Parse error on \"11\" (INT) at [1, 22]", :locations=>[{:line=>1, :column=>22}]}]
|
92
|
+
# TODO: handle errors
|
93
|
+
return []
|
94
|
+
end
|
95
|
+
|
96
|
+
res.data.repository.pullRequest.reviewThreads.nodes.to_h { |node|
|
97
|
+
[
|
98
|
+
node.id,
|
99
|
+
node.comments.nodes.map{ |comment|
|
100
|
+
{
|
101
|
+
author_id: comment.author.id,
|
102
|
+
path: comment.path, position: comment.position, body: comment.body
|
103
|
+
}
|
104
|
+
}
|
105
|
+
]
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def resolve_review_threads(node_ids)
|
110
|
+
return unless node_ids.any?
|
111
|
+
|
112
|
+
owner, repo_name = (slug || "").split('/')
|
113
|
+
query = <<~GQL
|
114
|
+
mutation {
|
115
|
+
#{
|
116
|
+
node_ids.each_with_index.map {|id, index|
|
117
|
+
"q#{index}: resolveReviewThread(input: { threadId: \"#{id}\" }){ thread { id } } "
|
118
|
+
}.join("\n")
|
119
|
+
}
|
120
|
+
}
|
121
|
+
GQL
|
122
|
+
client.post :graphql, { query: query }.to_json
|
44
123
|
end
|
45
124
|
end
|
46
125
|
|
@@ -52,6 +131,9 @@ module Pronto
|
|
52
131
|
comments = new_comments(messages, patches)
|
53
132
|
additions = remove_duplicate_comments(existing, comments)
|
54
133
|
|
134
|
+
# TODO: we can reuse some threads from graphql for existing messages detection (but there's no pagination)
|
135
|
+
resolve_old_messages(client, repo, comments)
|
136
|
+
|
55
137
|
if comments.none?
|
56
138
|
bot_reviews = client.existing_pull_request_reviews.select { |review| review.user.type == 'Bot' }
|
57
139
|
if bot_reviews.any?
|
@@ -84,6 +166,21 @@ module Pronto
|
|
84
166
|
rescue Octokit::UnprocessableEntity, HTTParty::Error => e
|
85
167
|
$stderr.puts "Failed to post: #{e.message}"
|
86
168
|
end
|
169
|
+
|
170
|
+
def resolve_old_messages(client, repo, actual_comments)
|
171
|
+
thread_ids_to_resolve = []
|
172
|
+
bot_node_id = client.bot_user.node_id
|
173
|
+
client.get_review_threads.each_pair do |thread_id, thread_comments|
|
174
|
+
next unless thread_comments.all? do |comment|
|
175
|
+
comment[:author_id] == bot_node_id &&
|
176
|
+
(actual_comments[[repo.path.join(comment[:path]), comment[:position]]] || []).none? { |actual_comment|
|
177
|
+
comment[:body].include?(actual_comment.body)
|
178
|
+
}
|
179
|
+
end
|
180
|
+
thread_ids_to_resolve << thread_id
|
181
|
+
end
|
182
|
+
client.resolve_review_threads(thread_ids_to_resolve)
|
183
|
+
end
|
87
184
|
end
|
88
185
|
|
89
186
|
class GithubPullRequestResolvingReviewFormatter < PullRequestFormatter
|