geet 0.27.2 → 0.27.3

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -0
  3. data/Gemfile +9 -9
  4. data/Rakefile +2 -2
  5. data/bin/geet +7 -7
  6. data/geet.gemspec +19 -19
  7. data/lib/geet/commandline/commands.rb +16 -15
  8. data/lib/geet/commandline/configuration.rb +96 -92
  9. data/lib/geet/commandline/editor.rb +13 -7
  10. data/lib/geet/git/repository.rb +75 -6
  11. data/lib/geet/github/abstract_issue.rb +4 -4
  12. data/lib/geet/github/api_interface.rb +23 -23
  13. data/lib/geet/github/gist.rb +8 -8
  14. data/lib/geet/github/issue.rb +5 -5
  15. data/lib/geet/github/label.rb +4 -4
  16. data/lib/geet/github/milestone.rb +8 -8
  17. data/lib/geet/github/pr.rb +20 -20
  18. data/lib/geet/github/remote_repository.rb +1 -1
  19. data/lib/geet/github/user.rb +5 -5
  20. data/lib/geet/gitlab/api_interface.rb +13 -13
  21. data/lib/geet/gitlab/issue.rb +3 -3
  22. data/lib/geet/gitlab/label.rb +3 -3
  23. data/lib/geet/gitlab/milestone.rb +4 -4
  24. data/lib/geet/gitlab/pr.rb +3 -3
  25. data/lib/geet/gitlab/user.rb +2 -2
  26. data/lib/geet/helpers/json_helper.rb +1 -1
  27. data/lib/geet/helpers/os_helper.rb +5 -5
  28. data/lib/geet/helpers/services_workflow_helper.rb +4 -4
  29. data/lib/geet/services/abstract_create_issue.rb +3 -3
  30. data/lib/geet/services/add_upstream_repo.rb +1 -1
  31. data/lib/geet/services/close_milestones.rb +9 -2
  32. data/lib/geet/services/comment_pr.rb +11 -0
  33. data/lib/geet/services/create_gist.rb +18 -4
  34. data/lib/geet/services/create_issue.rb +13 -7
  35. data/lib/geet/services/create_label.rb +22 -3
  36. data/lib/geet/services/create_milestone.rb +7 -1
  37. data/lib/geet/services/create_pr.rb +98 -23
  38. data/lib/geet/services/list_issues.rb +4 -3
  39. data/lib/geet/services/list_labels.rb +7 -0
  40. data/lib/geet/services/list_milestones.rb +35 -6
  41. data/lib/geet/services/list_prs.rb +7 -0
  42. data/lib/geet/services/merge_pr.rb +20 -2
  43. data/lib/geet/services/open_pr.rb +2 -2
  44. data/lib/geet/services/open_repo.rb +7 -1
  45. data/lib/geet/shared/repo_permissions.rb +4 -4
  46. data/lib/geet/shared/selection.rb +2 -2
  47. data/lib/geet/utils/attributes_selection_manager.rb +30 -10
  48. data/lib/geet/utils/git_client.rb +74 -33
  49. data/lib/geet/utils/manual_list_selection.rb +23 -11
  50. data/lib/geet/utils/string_matching_selection.rb +22 -6
  51. data/lib/geet/version.rb +2 -1
  52. data/lib/geet.rb +2 -2
  53. data/spec/integration/comment_pr_spec.rb +10 -10
  54. data/spec/integration/create_gist_spec.rb +12 -12
  55. data/spec/integration/create_issue_spec.rb +21 -21
  56. data/spec/integration/create_label_spec.rb +33 -33
  57. data/spec/integration/create_milestone_spec.rb +9 -9
  58. data/spec/integration/create_pr_spec.rb +120 -134
  59. data/spec/integration/list_issues_spec.rb +25 -25
  60. data/spec/integration/list_labels_spec.rb +15 -15
  61. data/spec/integration/list_milestones_spec.rb +15 -15
  62. data/spec/integration/list_prs_spec.rb +10 -10
  63. data/spec/integration/merge_pr_spec.rb +18 -18
  64. data/spec/integration/open_pr_spec.rb +18 -20
  65. data/spec/integration/open_repo_spec.rb +18 -18
  66. data/spec/spec_helper.rb +10 -10
  67. data/spec/unit/github/pr_spec.rb +73 -73
  68. metadata +3 -3
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
+ # typed: strict
2
3
 
3
4
  module Geet
4
5
  module Git
5
6
  # This class represents, for convenience, both the local and the remote repository, but the
6
7
  # remote code is separated in each provider module.
7
8
  class Repository
9
+ extend T::Sig
10
+
8
11
  LOCAL_ACTION_ON_UPSTREAM_REPOSITORY_MESSAGE = <<~STR
9
12
  The action will be performed on a fork, but an upstream repository has been found!
10
13
  STR
@@ -15,28 +18,42 @@ module Geet
15
18
 
16
19
  DEFAULT_GIT_CLIENT = Geet::Utils::GitClient.new
17
20
 
18
- # warnings: disable all the warnings.
19
- # protected_repositories: warn when creating an issue/pr on this repositories (entry format:
20
- # `owner/repo`).
21
- #
21
+ sig {
22
+ params(
23
+ upstream: T::Boolean,
24
+ git_client: Utils::GitClient,
25
+ warnings: T::Boolean, # disable all the warnings
26
+ protected_repositories: T::Array[String] # warn when creating an issue/pr on these repos (format: `owner/repo`)
27
+ )
28
+ .void
29
+ }
22
30
  def initialize(upstream: false, git_client: DEFAULT_GIT_CLIENT, warnings: true, protected_repositories: [])
23
31
  @upstream = upstream
24
32
  @git_client = git_client
25
- @api_token = extract_env_api_token
33
+ @api_token = T.let(extract_env_api_token, String)
26
34
  @warnings = warnings
27
35
  @protected_repositories = protected_repositories
28
36
  end
29
37
 
30
38
  # REMOTE FUNCTIONALITIES (REPOSITORY)
31
39
 
40
+ sig { returns(T.any(T::Array[Github::User], T::Array[Gitlab::User])) }
32
41
  def collaborators
33
42
  attempt_provider_call(:User, :list_collaborators, api_interface)
34
43
  end
35
44
 
45
+ sig { returns(T.any(T::Array[Github::Label], T::Array[Gitlab::Label])) }
36
46
  def labels
37
47
  attempt_provider_call(:Label, :list, api_interface)
38
48
  end
39
49
 
50
+ sig {
51
+ params(
52
+ title: String,
53
+ description: String
54
+ )
55
+ .returns(T.any(Github::Issue, Gitlab::Issue))
56
+ }
40
57
  def create_issue(title, description)
41
58
  confirm(LOCAL_ACTION_ON_UPSTREAM_REPOSITORY_MESSAGE) if local_action_on_upstream_repository? && @warnings
42
59
  confirm(ACTION_ON_PROTECTED_REPOSITORY_MESSAGE) if action_on_protected_repository? && @warnings
@@ -44,30 +61,63 @@ module Geet
44
61
  attempt_provider_call(:Issue, :create, title, description, api_interface)
45
62
  end
46
63
 
64
+ sig {
65
+ params(
66
+ name: String,
67
+ color: String
68
+ )
69
+ .returns(T.any(Github::Label, Gitlab::Label))
70
+ }
47
71
  def create_label(name, color)
48
72
  attempt_provider_call(:Label, :create, name, color, api_interface)
49
73
  end
50
74
 
75
+ sig { params(name: String).void }
51
76
  def delete_branch(name)
52
77
  attempt_provider_call(:Branch, :delete, name, api_interface)
53
78
  end
54
79
 
80
+ sig {
81
+ params(
82
+ assignee: T.nilable(T.any(Github::User, Gitlab::User)),
83
+ milestone: T.nilable(T.any(Github::Milestone, Gitlab::Milestone))
84
+ )
85
+ .returns(T.any(T::Array[Github::AbstractIssue], T::Array[Gitlab::Issue]))
86
+ }
55
87
  def issues(assignee: nil, milestone: nil)
56
88
  attempt_provider_call(:Issue, :list, api_interface, assignee:, milestone:)
57
89
  end
58
90
 
91
+ sig {
92
+ params(
93
+ title: String
94
+ )
95
+ .returns(T.any(Github::Milestone, Gitlab::Milestone))
96
+ }
59
97
  def create_milestone(title)
60
98
  attempt_provider_call(:Milestone, :create, title, api_interface)
61
99
  end
62
100
 
101
+ sig { returns(T.any(T::Array[Github::Milestone], T::Array[Gitlab::Milestone])) }
63
102
  def milestones
64
103
  attempt_provider_call(:Milestone, :list, api_interface)
65
104
  end
66
105
 
106
+ sig { params(number: Integer).void }
67
107
  def close_milestone(number)
68
108
  attempt_provider_call(:Milestone, :close, number, api_interface)
69
109
  end
70
110
 
111
+ sig {
112
+ params(
113
+ title: String,
114
+ description: String,
115
+ head: String, # source branch
116
+ base: String, # target branch
117
+ draft: T::Boolean
118
+ )
119
+ .returns(T.any(Github::PR, Gitlab::PR))
120
+ }
71
121
  def create_pr(title, description, head, base, draft)
72
122
  confirm(LOCAL_ACTION_ON_UPSTREAM_REPOSITORY_MESSAGE) if local_action_on_upstream_repository? && @warnings
73
123
  confirm(ACTION_ON_PROTECTED_REPOSITORY_MESSAGE) if action_on_protected_repository? && @warnings
@@ -75,30 +125,42 @@ module Geet
75
125
  attempt_provider_call(:PR, :create, title, description, head, api_interface, base, draft: draft)
76
126
  end
77
127
 
128
+ sig {
129
+ params(
130
+ owner: T.nilable(String), # filter by repository owner
131
+ head: T.nilable(String), # filter by source branch
132
+ milestone: T.nilable(T.any(Github::Milestone, Gitlab::Milestone))
133
+ )
134
+ .returns(T.any(T::Array[Github::PR], T::Array[Gitlab::PR]))
135
+ }
78
136
  def prs(owner: nil, head: nil, milestone: nil)
79
137
  attempt_provider_call(:PR, :list, api_interface, owner:, head:, milestone:)
80
138
  end
81
139
 
82
140
  # Returns the RemoteRepository instance.
83
141
  #
142
+ sig { returns(Github::RemoteRepository) }
84
143
  def remote
85
144
  attempt_provider_call(:RemoteRepository, :find, api_interface)
86
145
  end
87
146
 
88
147
  # REMOTE FUNCTIONALITIES (ACCOUNT)
89
148
 
149
+ sig { returns(Github::User) }
90
150
  def authenticated_user
91
151
  attempt_provider_call(:User, :authenticated, api_interface)
92
152
  end
93
153
 
94
154
  # OTHER/CONVENIENCE FUNCTIONALITIES
95
155
 
156
+ sig { returns(T::Boolean) }
96
157
  def upstream?
97
158
  @upstream
98
159
  end
99
160
 
100
161
  # For cases where it's necessary to work on the downstream repo.
101
162
  #
163
+ sig { returns(Git::Repository) }
102
164
  def downstream
103
165
  raise "downstream() is not available on not-upstream repositories!" if !upstream?
104
166
 
@@ -109,6 +171,7 @@ module Geet
109
171
 
110
172
  # PROVIDER
111
173
 
174
+ sig { returns(String) }
112
175
  def extract_env_api_token
113
176
  env_variable_name = "#{provider_name.upcase}_API_TOKEN"
114
177
 
@@ -117,6 +180,7 @@ module Geet
117
180
 
118
181
  # Attempt to find the provider class and send the specified method, returning a friendly
119
182
  # error (functionality X [Y] is missing) when a class/method is missing.
183
+ sig { params(class_name: Symbol, meth: Symbol, args: T.untyped).returns(T.untyped) }
120
184
  def attempt_provider_call(class_name, meth, *args)
121
185
  module_name = provider_name.capitalize
122
186
 
@@ -142,23 +206,27 @@ module Geet
142
206
 
143
207
  # WARNINGS
144
208
 
209
+ sig { params(message: String).void }
145
210
  def confirm(message)
146
211
  full_message = "WARNING! #{message.strip}\nPress Enter to continue, or Ctrl+C to exit now."
147
212
  print full_message
148
213
  gets
149
214
  end
150
215
 
216
+ sig { returns(T::Boolean) }
151
217
  def action_on_protected_repository?
152
218
  path = @git_client.path(upstream: @upstream)
153
219
  @protected_repositories.include?(path)
154
220
  end
155
221
 
222
+ sig { returns(T::Boolean) }
156
223
  def local_action_on_upstream_repository?
157
224
  @git_client.remote_defined?(Utils::GitClient::UPSTREAM_NAME) && !@upstream
158
225
  end
159
226
 
160
227
  # OTHER HELPERS
161
228
 
229
+ sig { returns(T.any(Github::ApiInterface, Gitlab::ApiInterface)) }
162
230
  def api_interface
163
231
  path = @git_client.path(upstream: @upstream)
164
232
  attempt_provider_call(:ApiInterface, :new, @api_token, repo_path: path, upstream: @upstream)
@@ -166,8 +234,9 @@ module Geet
166
234
 
167
235
  # Bare downcase provider name, eg. `github`
168
236
  #
237
+ sig { returns(String) }
169
238
  def provider_name
170
- @git_client.provider_domain[/(.*)\.\w+/, 1]
239
+ T.must(@git_client.provider_domain[/(.*)\.\w+/, 1])
171
240
  end
172
241
  end
173
242
  end
@@ -48,7 +48,7 @@ module Geet
48
48
  )
49
49
  ).returns(T::Array[Geet::Github::AbstractIssue]) }
50
50
  def self.list(api_interface, milestone: nil, assignee: nil, &type_filter)
51
- api_path = 'issues'
51
+ api_path = "issues"
52
52
 
53
53
  request_params = {}
54
54
  request_params[:milestone] = milestone.number if milestone
@@ -57,9 +57,9 @@ module Geet
57
57
  response = T.cast(api_interface.send_request(api_path, params: request_params, multipage: true), T::Array[T::Hash[String, T.untyped]])
58
58
 
59
59
  abstract_issues_list = response.map do |issue_data|
60
- number = T.cast(issue_data.fetch('number'), Integer)
61
- title = T.cast(issue_data.fetch('title'), String)
62
- link = T.cast(issue_data.fetch('html_url'), String)
60
+ number = T.cast(issue_data.fetch("number"), Integer)
61
+ title = T.cast(issue_data.fetch("title"), String)
62
+ link = T.cast(issue_data.fetch("html_url"), String)
63
63
 
64
64
  new(number, api_interface, title, link) if type_filter.nil? || type_filter.call(issue_data)
65
65
  end
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
  # typed: strict
3
3
 
4
- require 'uri'
5
- require 'net/http'
6
- require 'json'
4
+ require "uri"
5
+ require "net/http"
6
+ require "json"
7
7
 
8
8
  module Geet
9
9
  module Github
10
10
  class ApiInterface
11
11
  extend T::Sig
12
12
 
13
- API_AUTH_USER = T.let('', String) # We don't need the login, as the API key uniquely identifies the user
14
- API_BASE_URL = T.let('https://api.github.com', String)
15
- GRAPHQL_API_URL = T.let('https://api.github.com/graphql', String)
13
+ API_AUTH_USER = T.let("", String) # We don't need the login, as the API key uniquely identifies the user
14
+ API_BASE_URL = T.let("https://api.github.com", String)
15
+ GRAPHQL_API_URL = T.let("https://api.github.com/graphql", String)
16
16
 
17
17
  sig { returns(T.nilable(String)) }
18
18
  attr_reader :repository_path
@@ -111,7 +111,7 @@ module Geet
111
111
  Net::HTTP.start(uri.host, use_ssl: true) do |http|
112
112
  request = Net::HTTP::Post.new(uri).tap do
113
113
  it.basic_auth API_AUTH_USER, @api_token
114
- it['Accept'] = 'application/vnd.github.v3+json'
114
+ it["Accept"] = "application/vnd.github.v3+json"
115
115
  it.body = {query:, variables:}.to_json
116
116
  end
117
117
 
@@ -127,12 +127,12 @@ module Geet
127
127
  raise Geet::Shared::HttpError.new(error_message, response.code)
128
128
  end
129
129
 
130
- if parsed_response&.key?('errors')
131
- error_messages = T.cast(parsed_response['errors'], T::Array[T::Hash[String, T.untyped]]).map { |err| T.cast(err['message'], String) }.join(', ')
130
+ if parsed_response&.key?("errors")
131
+ error_messages = T.cast(parsed_response["errors"], T::Array[T::Hash[String, T.untyped]]).map { |err| T.cast(err["message"], String) }.join(", ")
132
132
  raise Geet::Shared::HttpError.new("GraphQL errors: #{error_messages}", response.code)
133
133
  end
134
134
 
135
- T.cast(T.must(parsed_response).fetch('data'), T::Hash[String, T.untyped])
135
+ T.cast(T.must(parsed_response).fetch("data"), T::Hash[String, T.untyped])
136
136
  end
137
137
  end
138
138
 
@@ -146,8 +146,8 @@ module Geet
146
146
  def api_url(api_path)
147
147
  url = API_BASE_URL
148
148
 
149
- if !api_path.start_with?('/')
150
- raise 'Missing repo path!' if @repository_path.nil?
149
+ if !api_path.start_with?("/")
150
+ raise "Missing repo path!" if @repository_path.nil?
151
151
  url += "/repos/#{@repository_path}/"
152
152
  end
153
153
 
@@ -171,7 +171,7 @@ module Geet
171
171
 
172
172
  request.basic_auth API_AUTH_USER, @api_token
173
173
  request.body = data.to_json if data
174
- request['Accept'] = 'application/vnd.github.v3+json'
174
+ request["Accept"] = "application/vnd.github.v3+json"
175
175
 
176
176
  http.request(request)
177
177
  end
@@ -184,7 +184,7 @@ module Geet
184
184
  ).returns(URI::Generic)
185
185
  }
186
186
  def encode_uri(address, params)
187
- address += '?' + URI.encode_www_form(params) if params
187
+ address += "?" + URI.encode_www_form(params) if params
188
188
 
189
189
  URI(address)
190
190
  end
@@ -195,7 +195,7 @@ module Geet
195
195
  ).returns(T::Boolean)
196
196
  }
197
197
  def error?(response)
198
- !response.code.start_with?('2')
198
+ !response.code.start_with?("2")
199
199
  end
200
200
 
201
201
  sig {
@@ -204,22 +204,22 @@ module Geet
204
204
  ).returns(String)
205
205
  }
206
206
  def decode_and_format_error(parsed_response)
207
- message = parsed_response['message']
207
+ message = parsed_response["message"]
208
208
 
209
- if parsed_response.key?('errors')
210
- message += ':'
209
+ if parsed_response.key?("errors")
210
+ message += ":"
211
211
 
212
- error_details = parsed_response['errors'].map do |error_data|
213
- error_code = error_data.fetch('code')
212
+ error_details = parsed_response["errors"].map do |error_data|
213
+ error_code = error_data.fetch("code")
214
214
 
215
- if error_code == 'custom'
215
+ if error_code == "custom"
216
216
  " #{error_data.fetch('message')}"
217
217
  else
218
218
  " #{error_code} (#{error_data.fetch('field')})"
219
219
  end
220
220
  end
221
221
 
222
- message += error_details.join(', ')
222
+ message += error_details.join(", ")
223
223
  end
224
224
 
225
225
  message
@@ -232,7 +232,7 @@ module Geet
232
232
  }
233
233
  def link_next_page(response_headers)
234
234
  # An array (or nil) is returned.
235
- link_header = Array(response_headers['link'])
235
+ link_header = Array(response_headers["link"])
236
236
 
237
237
  return nil if link_header.empty?
238
238
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  # typed: strict
3
3
 
4
- require_relative 'abstract_issue'
5
- require_relative '../github/gist'
4
+ require_relative "abstract_issue"
5
+ require_relative "../github/gist"
6
6
 
7
7
  module Geet
8
8
  module Github
@@ -19,13 +19,13 @@ module Geet
19
19
  ).returns(Geet::Github::Gist)
20
20
  }
21
21
  def self.create(filename, content, api_interface, description: nil, publik: false)
22
- api_path = '/gists'
22
+ api_path = "/gists"
23
23
 
24
24
  request_data = prepare_request_data(filename, content, description, publik)
25
25
 
26
26
  response = T.cast(api_interface.send_request(api_path, data: T.unsafe(request_data)), T::Hash[String, T.untyped])
27
27
 
28
- id = T.cast(response.fetch('id'), String)
28
+ id = T.cast(response.fetch("id"), String)
29
29
 
30
30
  new(id)
31
31
  end
@@ -55,15 +55,15 @@ module Geet
55
55
  }
56
56
  def prepare_request_data(filename, content, description, publik)
57
57
  request_data = {
58
- 'public' => publik,
59
- 'files' => {
58
+ "public" => publik,
59
+ "files" => {
60
60
  filename => {
61
- 'content' => content,
61
+ "content" => content,
62
62
  },
63
63
  },
64
64
  }
65
65
 
66
- request_data['description'] = description if description
66
+ request_data["description"] = description if description
67
67
 
68
68
  request_data
69
69
  end
@@ -14,7 +14,7 @@ module Geet
14
14
  ).returns(Geet::Github::Issue)
15
15
  }
16
16
  def self.create(title, description, api_interface)
17
- api_path = 'issues'
17
+ api_path = "issues"
18
18
  request_data = {title:, body: description}
19
19
 
20
20
  response = T.cast(
@@ -22,9 +22,9 @@ module Geet
22
22
  T::Hash[String, T.untyped]
23
23
  )
24
24
 
25
- issue_number = T.cast(response.fetch('number'), Integer)
26
- title = T.cast(response.fetch('title'), String)
27
- link = T.cast(response.fetch('html_url'), String)
25
+ issue_number = T.cast(response.fetch("number"), Integer)
26
+ title = T.cast(response.fetch("title"), String)
27
+ link = T.cast(response.fetch("html_url"), String)
28
28
 
29
29
  new(issue_number, api_interface, title, link)
30
30
  end
@@ -42,7 +42,7 @@ module Geet
42
42
  }
43
43
  def self.list(api_interface, assignee: nil, milestone: nil, &type_filter)
44
44
  super do |issue_data|
45
- !issue_data.key?('pull_request')
45
+ !issue_data.key?("pull_request")
46
46
  end
47
47
  end
48
48
  end
@@ -29,12 +29,12 @@ module Geet
29
29
  ).returns(T::Array[Geet::Github::Label])
30
30
  }
31
31
  def self.list(api_interface)
32
- api_path = 'labels'
32
+ api_path = "labels"
33
33
  response = T.cast(api_interface.send_request(api_path, multipage: true), T::Array[T::Hash[String, T.untyped]])
34
34
 
35
35
  response.map do |label_entry|
36
- name = T.cast(label_entry.fetch('name'), String)
37
- color = T.cast(label_entry.fetch('color'), String)
36
+ name = T.cast(label_entry.fetch("name"), String)
37
+ color = T.cast(label_entry.fetch("color"), String)
38
38
 
39
39
  new(name, color)
40
40
  end
@@ -49,7 +49,7 @@ module Geet
49
49
  ).returns(Geet::Github::Label)
50
50
  }
51
51
  def self.create(name, color, api_interface)
52
- api_path = 'labels'
52
+ api_path = "labels"
53
53
  request_data = {name:, color:}
54
54
 
55
55
  api_interface.send_request(api_path, data: request_data)
@@ -15,7 +15,7 @@ module Geet
15
15
  sig { returns(T.nilable(Date)) }
16
16
  attr_reader :due_on
17
17
 
18
- STATE_CLOSED = 'closed'
18
+ STATE_CLOSED = "closed"
19
19
 
20
20
  class << self
21
21
  extend T::Sig
@@ -49,7 +49,7 @@ module Geet
49
49
  ).returns(Geet::Github::Milestone)
50
50
  }
51
51
  def self.create(title, api_interface)
52
- api_path = 'milestones'
52
+ api_path = "milestones"
53
53
  request_data = {title: title}
54
54
 
55
55
  response = T.cast(
@@ -57,8 +57,8 @@ module Geet
57
57
  T::Hash[String, T.untyped]
58
58
  )
59
59
 
60
- number = T.cast(response.fetch('number'), Integer)
61
- title = T.cast(response.fetch('title'), String)
60
+ number = T.cast(response.fetch("number"), Integer)
61
+ title = T.cast(response.fetch("title"), String)
62
62
  due_on = nil
63
63
 
64
64
  new(number, title, due_on, api_interface)
@@ -72,7 +72,7 @@ module Geet
72
72
  ).returns(T::Array[Geet::Github::Milestone])
73
73
  }
74
74
  def self.list(api_interface)
75
- api_path = 'milestones'
75
+ api_path = "milestones"
76
76
 
77
77
  response = T.cast(
78
78
  api_interface.send_request(api_path, multipage: true),
@@ -80,10 +80,10 @@ module Geet
80
80
  )
81
81
 
82
82
  response.map do |milestone_data|
83
- number = T.cast(milestone_data.fetch('number'), Integer)
84
- title = T.cast(milestone_data.fetch('title'), String)
83
+ number = T.cast(milestone_data.fetch("number"), Integer)
84
+ title = T.cast(milestone_data.fetch("title"), String)
85
85
  due_on = parse_iso_8601_timestamp(
86
- T.cast(milestone_data.fetch('due_on'), T.nilable(String))
86
+ T.cast(milestone_data.fetch("due_on"), T.nilable(String))
87
87
  )
88
88
 
89
89
  new(number, title, due_on, api_interface)
@@ -36,7 +36,7 @@ module Geet
36
36
  ).returns(Geet::Github::PR)
37
37
  }
38
38
  def self.create(title, description, head, api_interface, base, draft: false)
39
- api_path = 'pulls'
39
+ api_path = "pulls"
40
40
 
41
41
  if api_interface.upstream?
42
42
  authenticated_user = Geet::Github::User.authenticated(api_interface).username
@@ -47,10 +47,10 @@ module Geet
47
47
 
48
48
  response = T.cast(api_interface.send_request(api_path, data: request_data), T::Hash[String, T.untyped])
49
49
 
50
- number = T.cast(response.fetch('number'), Integer)
51
- title = T.cast(response.fetch('title'), String)
52
- link = T.cast(response.fetch('html_url'), String)
53
- node_id = T.cast(response['node_id'], T.nilable(String))
50
+ number = T.cast(response.fetch("number"), Integer)
51
+ title = T.cast(response.fetch("title"), String)
52
+ link = T.cast(response.fetch("html_url"), String)
53
+ node_id = T.cast(response["node_id"], T.nilable(String))
54
54
 
55
55
  new(number, api_interface, title, link, node_id:)
56
56
  end
@@ -74,7 +74,7 @@ module Geet
74
74
  check_list_params!(milestone, assignee, head)
75
75
 
76
76
  if head
77
- api_path = 'pulls'
77
+ api_path = "pulls"
78
78
 
79
79
  # Technically, the upstream approach could be used for both, but it's actually good to have
80
80
  # both of them as reference.
@@ -96,8 +96,8 @@ module Geet
96
96
  # For this reason, we can't use that param, and have to filter manually.
97
97
  #
98
98
  unfiltered_response.select do |pr_data|
99
- pr_head = T.cast(pr_data.fetch('head'), T::Hash[String, T.untyped])
100
- label = T.cast(pr_head.fetch('label'), String)
99
+ pr_head = T.cast(pr_data.fetch("head"), T::Hash[String, T.untyped])
100
+ label = T.cast(pr_head.fetch("label"), String)
101
101
 
102
102
  label == "#{owner}:#{head}"
103
103
  end
@@ -111,15 +111,15 @@ module Geet
111
111
  end
112
112
 
113
113
  response.map do |pr_data|
114
- number = T.cast(pr_data.fetch('number'), Integer)
115
- title = T.cast(pr_data.fetch('title'), String)
116
- link = T.cast(pr_data.fetch('html_url'), String)
114
+ number = T.cast(pr_data.fetch("number"), Integer)
115
+ title = T.cast(pr_data.fetch("title"), String)
116
+ link = T.cast(pr_data.fetch("html_url"), String)
117
117
 
118
118
  new(number, api_interface, title, link)
119
119
  end
120
120
  else
121
121
  result = super(api_interface, milestone:, assignee:) do |issue_data|
122
- issue_data.key?('pull_request')
122
+ issue_data.key?("pull_request")
123
123
  end
124
124
 
125
125
  T.cast(result, T::Array[Geet::Github::PR])
@@ -207,22 +207,22 @@ module Geet
207
207
  }
208
208
  GRAPHQL
209
209
 
210
- owner, name = T.must(@api_interface.repository_path).split('/')
210
+ owner, name = T.must(@api_interface.repository_path).split("/")
211
211
 
212
212
  response = @api_interface.send_graphql_request(query, variables: {owner:, name:, number:})
213
- repo_data = response['repository'].transform_keys(&:to_sym)
214
- commit_count = repo_data[:pullRequest]['commits']['totalCount']
213
+ repo_data = response["repository"].transform_keys(&:to_sym)
214
+ commit_count = repo_data[:pullRequest]["commits"]["totalCount"]
215
215
 
216
216
  if commit_count == 1 && repo_data[:squashMergeAllowed]
217
- 'SQUASH'
217
+ "SQUASH"
218
218
  elsif repo_data[:mergeCommitAllowed]
219
- 'MERGE'
219
+ "MERGE"
220
220
  elsif repo_data[:squashMergeAllowed]
221
- 'SQUASH'
221
+ "SQUASH"
222
222
  elsif repo_data[:rebaseMergeAllowed]
223
- 'REBASE'
223
+ "REBASE"
224
224
  else
225
- raise 'No merge methods are allowed on this repository'
225
+ raise "No merge methods are allowed on this repository"
226
226
  end
227
227
  end
228
228
 
@@ -43,7 +43,7 @@ module Geet
43
43
 
44
44
  response = T.cast(api_interface.send_request(api_path), T::Hash[String, T.untyped])
45
45
 
46
- parent_hash = T.cast(response['parent'], T.nilable(T::Hash[String, T.untyped]))
46
+ parent_hash = T.cast(response["parent"], T.nilable(T::Hash[String, T.untyped]))
47
47
  parent_path = T.cast(parent_hash&.fetch("full_name)"), T.nilable(String))
48
48
 
49
49
  new(api_interface, parent_path:)
@@ -63,11 +63,11 @@ module Geet
63
63
  ).returns(Geet::Github::User)
64
64
  }
65
65
  def self.authenticated(api_interface)
66
- api_path = '/user'
66
+ api_path = "/user"
67
67
 
68
68
  response = T.cast(api_interface.send_request(api_path), T::Hash[String, T.untyped])
69
69
 
70
- login = T.cast(response.fetch('login'), String)
70
+ login = T.cast(response.fetch("login"), String)
71
71
 
72
72
  new(login, api_interface)
73
73
  end
@@ -78,11 +78,11 @@ module Geet
78
78
  ).returns(T::Array[Geet::Github::User])
79
79
  }
80
80
  def self.list_collaborators(api_interface)
81
- api_path = 'collaborators'
81
+ api_path = "collaborators"
82
82
  response = T.cast(api_interface.send_request(api_path, multipage: true), T::Array[T::Hash[String, T.untyped]])
83
83
 
84
84
  response.map do |user_entry|
85
- login = T.cast(user_entry.fetch('login'), String)
85
+ login = T.cast(user_entry.fetch("login"), String)
86
86
  new(login, api_interface)
87
87
  end
88
88
  end
@@ -100,7 +100,7 @@ module Geet
100
100
 
101
101
  response = T.cast(api_interface.send_request(api_path), T::Hash[String, T.untyped])
102
102
 
103
- permission = T.cast(response.fetch('permission'), String)
103
+ permission = T.cast(response.fetch("permission"), String)
104
104
 
105
105
  check_permission!(permission)
106
106