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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8853fcc6e38eef6f5fbaac5dc815cabd7e3e81e18136675a9cddfbc203f538d7
4
- data.tar.gz: ab3620bd675754fc045ff7619f3053f27829786f4076a19f0cbd317ed3f84d56
3
+ metadata.gz: 152e4319e389105c14b8c208f8b668c17a25eafbab0f1270b00c071994f9320c
4
+ data.tar.gz: b7a1b40e35543a93e7924e82a7b3596e35ac9e416df34855939112e5222db953
5
5
  SHA512:
6
- metadata.gz: f7097355369c367d5d6232204fcc623cfb6755a494e4b81467904d97d671b46aa70c7d9339ebb92bc5a8a8e9ed4d56642cba344a73a31ecc56904959132d456a
7
- data.tar.gz: cf0f065244dea041390ceabafb2cb76dcf71e46ea4d512666106b5ff9f1cc62f071bb5eb87945cb642cb08298d5873d9559db404ccd8f3cc5f64791248fa70db
6
+ metadata.gz: 46e7f768e794754c2e2d1159779332f980408d77f5fe4c88f825ed63c27c85dad49318c66da9236ca05d133532de5c6d20a3d39df9c8bd68eef7141bf1763368
7
+ data.tar.gz: '0758a279f57ba8c0a153528f0b2b06ab3baee909e396e92c86845b86672f18d312ec41f9efbc574f45cf5aa1ec093f988ae728fd987a72e3d571b31f074d5201'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pronto-github_resolver (0.0.1)
4
+ pronto-github_resolver (0.0.2)
5
5
  pronto (~> 0.11)
6
6
 
7
7
  GEM
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Pronto
4
4
  module GithubResolver
5
- VERSION = "0.0.1"
5
+ VERSION = "0.0.2"
6
6
  end
7
7
  end
@@ -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
- client.user.id
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pronto-github_resolver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasily Fedoseyev