pronto-github_resolver 0.0.1 → 0.0.2

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: 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