geet 0.26.0 → 0.27.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/Gemfile +1 -0
- data/geet.gemspec +1 -1
- data/lib/geet/git/repository.rb +2 -2
- data/lib/geet/github/abstract_issue.rb +38 -12
- data/lib/geet/github/api_interface.rb +86 -16
- data/lib/geet/github/branch.rb +5 -1
- data/lib/geet/github/gist.rb +26 -2
- data/lib/geet/github/issue.rb +31 -5
- data/lib/geet/github/label.rb +32 -8
- data/lib/geet/github/milestone.rb +56 -11
- data/lib/geet/github/pr.rb +105 -21
- data/lib/geet/github/remote_repository.rb +19 -3
- data/lib/geet/github/user.rb +47 -11
- data/lib/geet/gitlab/api_interface.rb +85 -22
- data/lib/geet/gitlab/issue.rb +32 -5
- data/lib/geet/gitlab/label.rb +37 -8
- data/lib/geet/gitlab/milestone.rb +41 -6
- data/lib/geet/gitlab/pr.rb +60 -8
- data/lib/geet/gitlab/user.rb +27 -5
- data/lib/geet/helpers/services_workflow_helper.rb +1 -1
- data/lib/geet/services/comment_pr.rb +1 -1
- data/lib/geet/services/create_gist.rb +1 -1
- data/lib/geet/services/create_issue.rb +70 -8
- data/lib/geet/services/create_pr.rb +14 -5
- data/lib/geet/services/list_issues.rb +20 -1
- data/lib/geet/services/merge_pr.rb +1 -1
- data/lib/geet/services/open_pr.rb +16 -1
- data/lib/geet/version.rb +1 -1
- data/spec/integration/create_issue_spec.rb +1 -2
- data/spec/integration/create_pr_spec.rb +10 -10
- data/spec/spec_helper.rb +3 -0
- data/spec/unit/github/pr_spec.rb +165 -0
- metadata +3 -2
data/lib/geet/gitlab/label.rb
CHANGED
|
@@ -1,32 +1,61 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Gitlab
|
|
5
6
|
class Label
|
|
6
|
-
|
|
7
|
+
extend T::Sig
|
|
7
8
|
|
|
9
|
+
sig { returns(String) }
|
|
10
|
+
attr_reader :name
|
|
11
|
+
|
|
12
|
+
sig { returns(String) }
|
|
13
|
+
attr_reader :color
|
|
14
|
+
|
|
15
|
+
sig {
|
|
16
|
+
params(
|
|
17
|
+
name: String,
|
|
18
|
+
color: String
|
|
19
|
+
).void
|
|
20
|
+
}
|
|
8
21
|
def initialize(name, color)
|
|
9
22
|
@name = name
|
|
10
23
|
@color = color
|
|
11
24
|
end
|
|
12
25
|
|
|
13
|
-
|
|
14
|
-
|
|
26
|
+
sig {
|
|
27
|
+
params(
|
|
28
|
+
api_interface: ApiInterface
|
|
29
|
+
).returns(T::Array[Label])
|
|
30
|
+
}
|
|
31
|
+
def self.list(api_interface)
|
|
15
32
|
api_path = "projects/#{api_interface.path_with_namespace(encoded: true)}/labels"
|
|
16
|
-
response =
|
|
33
|
+
response = T.cast(
|
|
34
|
+
api_interface.send_request(api_path, multipage: true),
|
|
35
|
+
T::Array[T::Hash[String, T.untyped]]
|
|
36
|
+
)
|
|
17
37
|
|
|
18
38
|
response.map do |label_entry|
|
|
19
|
-
name = label_entry.fetch('name')
|
|
20
|
-
color = label_entry.fetch('color')
|
|
39
|
+
name = T.cast(label_entry.fetch('name'), String)
|
|
40
|
+
color = T.cast(label_entry.fetch('color'), String)
|
|
41
|
+
|
|
42
|
+
color = color.sub('#', '') # normalize
|
|
21
43
|
|
|
22
44
|
new(name, color)
|
|
23
45
|
end
|
|
24
46
|
end
|
|
25
47
|
|
|
26
48
|
# See https://docs.gitlab.com/ee/api/labels.html#create-a-new-label
|
|
27
|
-
|
|
49
|
+
sig {
|
|
50
|
+
params(
|
|
51
|
+
name: String,
|
|
52
|
+
color: String,
|
|
53
|
+
api_interface: ApiInterface
|
|
54
|
+
).returns(Label)
|
|
55
|
+
}
|
|
56
|
+
def self.create(name, color, api_interface)
|
|
28
57
|
api_path = "projects/#{api_interface.path_with_namespace(encoded: true)}/labels"
|
|
29
|
-
request_data = { name
|
|
58
|
+
request_data = { name:, color: "##{color}" }
|
|
30
59
|
|
|
31
60
|
api_interface.send_request(api_path, data: request_data)
|
|
32
61
|
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
require 'date'
|
|
4
5
|
|
|
5
6
|
module Geet
|
|
6
7
|
module Gitlab
|
|
7
8
|
class Milestone
|
|
8
|
-
|
|
9
|
+
extend T::Sig
|
|
9
10
|
|
|
11
|
+
sig { returns(Integer) }
|
|
12
|
+
attr_reader :number
|
|
13
|
+
|
|
14
|
+
sig { returns(String) }
|
|
15
|
+
attr_reader :title
|
|
16
|
+
|
|
17
|
+
sig { returns(T.nilable(Date)) }
|
|
18
|
+
attr_reader :due_on
|
|
19
|
+
|
|
20
|
+
sig {
|
|
21
|
+
params(
|
|
22
|
+
number: Integer,
|
|
23
|
+
title: String,
|
|
24
|
+
due_on: T.nilable(Date),
|
|
25
|
+
api_interface: ApiInterface
|
|
26
|
+
).void
|
|
27
|
+
}
|
|
10
28
|
def initialize(number, title, due_on, api_interface)
|
|
11
29
|
@number = number
|
|
12
30
|
@title = title
|
|
@@ -17,23 +35,40 @@ module Geet
|
|
|
17
35
|
|
|
18
36
|
# See https://docs.gitlab.com/ee/api/milestones.html#list-project-milestones
|
|
19
37
|
#
|
|
20
|
-
|
|
38
|
+
sig {
|
|
39
|
+
params(
|
|
40
|
+
api_interface: ApiInterface
|
|
41
|
+
).returns(T::Array[Milestone])
|
|
42
|
+
}
|
|
43
|
+
def self.list(api_interface)
|
|
21
44
|
api_path = "projects/#{api_interface.path_with_namespace(encoded: true)}/milestones"
|
|
22
45
|
|
|
23
|
-
response =
|
|
46
|
+
response = T.cast(
|
|
47
|
+
api_interface.send_request(api_path, multipage: true),
|
|
48
|
+
T::Array[T::Hash[String, T.untyped]]
|
|
49
|
+
)
|
|
24
50
|
|
|
25
51
|
response.map do |milestone_data|
|
|
26
|
-
number = milestone_data.fetch('iid')
|
|
27
|
-
title = milestone_data.fetch('title')
|
|
28
|
-
due_on = parse_due_date(
|
|
52
|
+
number = T.cast(milestone_data.fetch('iid'), Integer)
|
|
53
|
+
title = T.cast(milestone_data.fetch('title'), String)
|
|
54
|
+
due_on = parse_due_date(
|
|
55
|
+
T.cast(milestone_data.fetch('due_date'), T.nilable(String))
|
|
56
|
+
)
|
|
29
57
|
|
|
30
58
|
new(number, title, due_on, api_interface)
|
|
31
59
|
end
|
|
32
60
|
end
|
|
33
61
|
|
|
34
62
|
class << self
|
|
63
|
+
extend T::Sig
|
|
64
|
+
|
|
35
65
|
private
|
|
36
66
|
|
|
67
|
+
sig {
|
|
68
|
+
params(
|
|
69
|
+
raw_due_date: T.nilable(String)
|
|
70
|
+
).returns(T.nilable(Date))
|
|
71
|
+
}
|
|
37
72
|
def parse_due_date(raw_due_date)
|
|
38
73
|
Date.parse(raw_due_date) if raw_due_date
|
|
39
74
|
end
|
data/lib/geet/gitlab/pr.rb
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Gitlab
|
|
5
6
|
class PR
|
|
6
|
-
|
|
7
|
+
extend T::Sig
|
|
7
8
|
|
|
9
|
+
sig { returns(Integer) }
|
|
10
|
+
attr_reader :number
|
|
11
|
+
|
|
12
|
+
sig { returns(String) }
|
|
13
|
+
attr_reader :title
|
|
14
|
+
|
|
15
|
+
sig { returns(String) }
|
|
16
|
+
attr_reader :link
|
|
17
|
+
|
|
18
|
+
sig {
|
|
19
|
+
params(
|
|
20
|
+
number: Integer,
|
|
21
|
+
api_interface: ApiInterface,
|
|
22
|
+
title: String,
|
|
23
|
+
link: String
|
|
24
|
+
).void
|
|
25
|
+
}
|
|
8
26
|
def initialize(number, api_interface, title, link)
|
|
9
27
|
@number = number
|
|
10
28
|
@api_interface = api_interface
|
|
@@ -12,11 +30,19 @@ module Geet
|
|
|
12
30
|
@link = link
|
|
13
31
|
end
|
|
14
32
|
|
|
15
|
-
# owner: required only for API compatibility. it's not required; if passed, it's only checked
|
|
16
|
-
# against the API path to make sure it's correct.
|
|
17
|
-
#
|
|
18
33
|
# See https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-requests
|
|
19
34
|
#
|
|
35
|
+
sig {
|
|
36
|
+
params(
|
|
37
|
+
api_interface: ApiInterface,
|
|
38
|
+
milestone: T.nilable(Milestone),
|
|
39
|
+
assignee: T.nilable(User),
|
|
40
|
+
# Required only for API compatibility. it's not required; if passed, it's only checked
|
|
41
|
+
# against the API path to make sure it's correct.
|
|
42
|
+
owner: T.nilable(String),
|
|
43
|
+
head: T.nilable(String)
|
|
44
|
+
).returns(T::Array[PR])
|
|
45
|
+
}
|
|
20
46
|
def self.list(api_interface, milestone: nil, assignee: nil, owner: nil, head: nil)
|
|
21
47
|
api_path = "projects/#{api_interface.path_with_namespace(encoded: true)}/merge_requests"
|
|
22
48
|
|
|
@@ -27,19 +53,37 @@ module Geet
|
|
|
27
53
|
request_params[:milestone] = milestone.title if milestone
|
|
28
54
|
request_params[:source_branch] = head if head
|
|
29
55
|
|
|
30
|
-
response =
|
|
56
|
+
response = T.cast(
|
|
57
|
+
api_interface.send_request(api_path, params: request_params, multipage: true),
|
|
58
|
+
T::Array[T::Hash[String, T.untyped]]
|
|
59
|
+
)
|
|
31
60
|
|
|
32
61
|
response.map do |issue_data, result|
|
|
33
|
-
number = issue_data.fetch('iid')
|
|
34
|
-
title = issue_data.fetch('title')
|
|
35
|
-
link = issue_data.fetch('web_url')
|
|
62
|
+
number = T.cast(issue_data.fetch('iid'), Integer)
|
|
63
|
+
title = T.cast(issue_data.fetch('title'), String)
|
|
64
|
+
link = T.cast(issue_data.fetch('web_url'), String)
|
|
36
65
|
|
|
37
66
|
new(number, api_interface, title, link)
|
|
38
67
|
end
|
|
39
68
|
end
|
|
40
69
|
|
|
70
|
+
# See https://docs.gitlab.com/ee/api/notes.html#create-new-merge-request-note
|
|
71
|
+
#
|
|
72
|
+
sig { params(comment: String).void }
|
|
73
|
+
def comment(comment)
|
|
74
|
+
api_path = "projects/#{@api_interface.path_with_namespace(encoded: true)}/merge_requests/#{number}/notes"
|
|
75
|
+
request_data = { body: comment }
|
|
76
|
+
|
|
77
|
+
@api_interface.send_request(api_path, data: request_data)
|
|
78
|
+
end
|
|
79
|
+
|
|
41
80
|
# See https://docs.gitlab.com/ee/api/merge_requests.html#accept-mr
|
|
42
81
|
#
|
|
82
|
+
sig {
|
|
83
|
+
params(
|
|
84
|
+
merge_method: T.nilable(String)
|
|
85
|
+
).void
|
|
86
|
+
}
|
|
43
87
|
def merge(merge_method: nil)
|
|
44
88
|
raise ArgumentError, "GitLab does not support the merge_method parameter" if merge_method
|
|
45
89
|
|
|
@@ -49,8 +93,16 @@ module Geet
|
|
|
49
93
|
end
|
|
50
94
|
|
|
51
95
|
class << self
|
|
96
|
+
extend T::Sig
|
|
97
|
+
|
|
52
98
|
private
|
|
53
99
|
|
|
100
|
+
sig {
|
|
101
|
+
params(
|
|
102
|
+
api_interface: ApiInterface,
|
|
103
|
+
owner: String
|
|
104
|
+
).void
|
|
105
|
+
}
|
|
54
106
|
def check_list_owner!(api_interface, owner)
|
|
55
107
|
if !api_interface.path_with_namespace.start_with?("#{owner}/")
|
|
56
108
|
raise "Mismatch owner/API path!: #{owner}<>#{api_interface.path_with_namespace}"
|
data/lib/geet/gitlab/user.rb
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Gitlab
|
|
5
6
|
class User
|
|
6
|
-
|
|
7
|
+
extend T::Sig
|
|
7
8
|
|
|
9
|
+
sig { returns(Integer) }
|
|
10
|
+
attr_reader :id
|
|
11
|
+
|
|
12
|
+
sig { returns(String) }
|
|
13
|
+
attr_reader :username
|
|
14
|
+
|
|
15
|
+
sig {
|
|
16
|
+
params(
|
|
17
|
+
id: Integer,
|
|
18
|
+
username: String,
|
|
19
|
+
api_interface: ApiInterface
|
|
20
|
+
).void
|
|
21
|
+
}
|
|
8
22
|
def initialize(id, username, api_interface)
|
|
9
23
|
@id = id
|
|
10
24
|
@username = username
|
|
@@ -13,14 +27,22 @@ module Geet
|
|
|
13
27
|
|
|
14
28
|
# Returns an array of User instances
|
|
15
29
|
#
|
|
16
|
-
|
|
30
|
+
sig {
|
|
31
|
+
params(
|
|
32
|
+
api_interface: ApiInterface
|
|
33
|
+
).returns(T::Array[User])
|
|
34
|
+
}
|
|
35
|
+
def self.list_collaborators(api_interface)
|
|
17
36
|
api_path = "projects/#{api_interface.path_with_namespace(encoded: true)}/members"
|
|
18
37
|
|
|
19
|
-
response =
|
|
38
|
+
response = T.cast(
|
|
39
|
+
api_interface.send_request(api_path, multipage: true),
|
|
40
|
+
T::Array[T::Hash[String, T.untyped]]
|
|
41
|
+
)
|
|
20
42
|
|
|
21
43
|
response.map do |user_entry|
|
|
22
|
-
id = user_entry.fetch('id')
|
|
23
|
-
username = user_entry.fetch('username')
|
|
44
|
+
id = T.cast(user_entry.fetch('id'), Integer)
|
|
45
|
+
username = T.cast(user_entry.fetch('username'), String)
|
|
24
46
|
|
|
25
47
|
new(id, username, api_interface)
|
|
26
48
|
end
|
|
@@ -36,7 +36,7 @@ module Geet
|
|
|
36
36
|
|
|
37
37
|
@out.puts "Finding PR with head (#{owner}:#{head})..."
|
|
38
38
|
|
|
39
|
-
prs = @repository.prs(owner
|
|
39
|
+
prs = @repository.prs(owner:, head:)
|
|
40
40
|
|
|
41
41
|
raise "Expected to find only one PR for the current branch; found: #{prs.size}" if prs.size != 1
|
|
42
42
|
|
|
@@ -16,7 +16,7 @@ module Geet
|
|
|
16
16
|
@git_client = git_client
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def execute(comment, open_browser: false
|
|
19
|
+
def execute(comment, open_browser: false)
|
|
20
20
|
pr = checked_find_branch_pr
|
|
21
21
|
pr.comment(comment)
|
|
22
22
|
open_file_with_default_application(pr.link) if open_browser
|
|
@@ -27,7 +27,7 @@ module Geet
|
|
|
27
27
|
@out.puts "Creating a #{gist_access} gist..."
|
|
28
28
|
|
|
29
29
|
filename = File.basename(full_filename)
|
|
30
|
-
gist = Geet::Github::Gist.create(filename, content, @api_interface, description
|
|
30
|
+
gist = Geet::Github::Gist.create(filename, content, @api_interface, description:, publik:)
|
|
31
31
|
|
|
32
32
|
if open_browser
|
|
33
33
|
open_file_with_default_application(gist.link)
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
5
6
|
class CreateIssue < AbstractCreateIssue
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
6
9
|
include Geet::Shared::RepoPermissions
|
|
7
10
|
include Geet::Shared::Selection
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
sig {
|
|
13
|
+
params(
|
|
14
|
+
title: String,
|
|
15
|
+
description: String,
|
|
16
|
+
labels: T.nilable(String),
|
|
17
|
+
milestone: T.nilable(String), # Number or description pattern
|
|
18
|
+
assignees: T.nilable(String),
|
|
19
|
+
open_browser: T::Boolean
|
|
20
|
+
).returns(T.any(Github::Issue, Gitlab::Issue))
|
|
21
|
+
}
|
|
15
22
|
def execute(
|
|
16
23
|
title, description,
|
|
17
|
-
labels: nil, milestone: nil, assignees: nil, open_browser: false
|
|
18
|
-
**
|
|
24
|
+
labels: nil, milestone: nil, assignees: nil, open_browser: false
|
|
19
25
|
)
|
|
20
26
|
# Inefficient (in worst case, triples the pre issue creation waiting time: #is_collaborator?,
|
|
21
27
|
# #has_permissions?, and the attributes batch), but not trivial to speed up. Not difficult
|
|
@@ -48,6 +54,17 @@ module Geet
|
|
|
48
54
|
|
|
49
55
|
# Internal actions
|
|
50
56
|
|
|
57
|
+
sig {
|
|
58
|
+
params(
|
|
59
|
+
labels: T.nilable(String),
|
|
60
|
+
milestone: T.nilable(String),
|
|
61
|
+
assignees: T.nilable(String)
|
|
62
|
+
).returns([
|
|
63
|
+
T.nilable(T::Array[T.any(Github::Label, Gitlab::Label)]),
|
|
64
|
+
T.nilable(T.any(Github::Milestone, Gitlab::Milestone)),
|
|
65
|
+
T.nilable(T::Array[T.any(Github::User, Gitlab::User)])
|
|
66
|
+
])
|
|
67
|
+
}
|
|
51
68
|
def find_and_select_attributes(labels, milestone, assignees)
|
|
52
69
|
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
|
53
70
|
|
|
@@ -58,12 +75,26 @@ module Geet
|
|
|
58
75
|
selection_manager.select_attributes
|
|
59
76
|
end
|
|
60
77
|
|
|
78
|
+
sig {
|
|
79
|
+
params(
|
|
80
|
+
title: String,
|
|
81
|
+
description: String
|
|
82
|
+
).returns(T.any(Github::Issue, Gitlab::Issue))
|
|
83
|
+
}
|
|
61
84
|
def create_issue(title, description)
|
|
62
85
|
@out.puts 'Creating the issue...'
|
|
63
86
|
|
|
64
87
|
issue = @repository.create_issue(title, description)
|
|
65
88
|
end
|
|
66
89
|
|
|
90
|
+
sig {
|
|
91
|
+
params(
|
|
92
|
+
issue: T.any(Github::Issue, Gitlab::Issue),
|
|
93
|
+
labels: T.nilable(T::Array[T.any(Github::Label, Gitlab::Label)]),
|
|
94
|
+
milestone: T.nilable(T.any(Github::Milestone, Gitlab::Milestone)),
|
|
95
|
+
assignees: T.nilable(T::Array[T.any(Github::User, Gitlab::User)])
|
|
96
|
+
).void
|
|
97
|
+
}
|
|
67
98
|
def edit_issue(issue, labels, milestone, assignees)
|
|
68
99
|
# labels can be nil (parameter not passed) or empty array (parameter passed, but nothing
|
|
69
100
|
# selected)
|
|
@@ -82,7 +113,15 @@ module Geet
|
|
|
82
113
|
assign_users_thread&.join
|
|
83
114
|
end
|
|
84
115
|
|
|
116
|
+
sig {
|
|
117
|
+
params(
|
|
118
|
+
issue: T.any(Github::Issue, Gitlab::Issue),
|
|
119
|
+
selected_labels: T::Array[T.any(Github::Label, Gitlab::Label)]
|
|
120
|
+
).returns(Thread)
|
|
121
|
+
}
|
|
85
122
|
def add_labels(issue, selected_labels)
|
|
123
|
+
raise "Functionality unsupported on GitLab!" if issue.is_a?(Gitlab::Issue)
|
|
124
|
+
|
|
86
125
|
labels_list = selected_labels.map(&:name).join(', ')
|
|
87
126
|
|
|
88
127
|
@out.puts "Adding labels #{labels_list}..."
|
|
@@ -92,7 +131,15 @@ module Geet
|
|
|
92
131
|
end
|
|
93
132
|
end
|
|
94
133
|
|
|
134
|
+
sig {
|
|
135
|
+
params(
|
|
136
|
+
issue: T.any(Github::Issue, Gitlab::Issue),
|
|
137
|
+
milestone: T.any(Github::Milestone, Gitlab::Milestone)
|
|
138
|
+
).returns(Thread)
|
|
139
|
+
}
|
|
95
140
|
def set_milestone(issue, milestone)
|
|
141
|
+
raise "Functionality unsupported on GitLab!" if issue.is_a?(Gitlab::Issue)
|
|
142
|
+
|
|
96
143
|
@out.puts "Setting milestone #{milestone.title}..."
|
|
97
144
|
|
|
98
145
|
Thread.new do
|
|
@@ -100,7 +147,15 @@ module Geet
|
|
|
100
147
|
end
|
|
101
148
|
end
|
|
102
149
|
|
|
150
|
+
sig {
|
|
151
|
+
params(
|
|
152
|
+
issue: T.any(Github::Issue, Gitlab::Issue),
|
|
153
|
+
users: T::Array[T.any(Github::User, Gitlab::User)]
|
|
154
|
+
).returns(Thread)
|
|
155
|
+
}
|
|
103
156
|
def assign_users(issue, users)
|
|
157
|
+
raise "Functionality unsupported on GitLab!" if issue.is_a?(Gitlab::Issue)
|
|
158
|
+
|
|
104
159
|
usernames = users.map(&:username)
|
|
105
160
|
|
|
106
161
|
@out.puts "Assigning users #{usernames.join(', ')}..."
|
|
@@ -110,7 +165,14 @@ module Geet
|
|
|
110
165
|
end
|
|
111
166
|
end
|
|
112
167
|
|
|
168
|
+
sig {
|
|
169
|
+
params(
|
|
170
|
+
issue: T.any(Github::Issue, Gitlab::Issue)
|
|
171
|
+
).returns(Thread)
|
|
172
|
+
}
|
|
113
173
|
def assign_authenticated_user(issue)
|
|
174
|
+
raise "Functionality unsupported on GitLab!" if issue.is_a?(Gitlab::Issue)
|
|
175
|
+
|
|
114
176
|
@out.puts 'Assigning authenticated user...'
|
|
115
177
|
|
|
116
178
|
Thread.new do
|
|
@@ -25,7 +25,7 @@ module Geet
|
|
|
25
25
|
#
|
|
26
26
|
def execute(
|
|
27
27
|
title, description, labels: nil, milestone: nil, reviewers: nil,
|
|
28
|
-
base: nil, draft: false, open_browser: false, automerge: false
|
|
28
|
+
base: nil, draft: false, open_browser: false, automerge: false
|
|
29
29
|
)
|
|
30
30
|
ensure_clean_tree
|
|
31
31
|
|
|
@@ -45,7 +45,7 @@ module Geet
|
|
|
45
45
|
|
|
46
46
|
sync_with_remote_branch
|
|
47
47
|
|
|
48
|
-
pr = create_pr(title, description, base
|
|
48
|
+
pr = create_pr(title, description, base:, draft:)
|
|
49
49
|
|
|
50
50
|
if user_has_write_permissions
|
|
51
51
|
edit_pr(pr, selected_labels, selected_milestone, selected_reviewers)
|
|
@@ -164,6 +164,8 @@ module Geet
|
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
def add_labels(pr, selected_labels)
|
|
167
|
+
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
168
|
+
|
|
167
169
|
labels_list = selected_labels.map(&:name).join(', ')
|
|
168
170
|
|
|
169
171
|
@out.puts "Adding labels #{labels_list}..."
|
|
@@ -174,6 +176,8 @@ module Geet
|
|
|
174
176
|
end
|
|
175
177
|
|
|
176
178
|
def set_milestone(pr, milestone)
|
|
179
|
+
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
180
|
+
|
|
177
181
|
@out.puts "Setting milestone #{milestone.title}..."
|
|
178
182
|
|
|
179
183
|
Thread.new do
|
|
@@ -182,6 +186,8 @@ module Geet
|
|
|
182
186
|
end
|
|
183
187
|
|
|
184
188
|
def request_review(pr, reviewers)
|
|
189
|
+
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
190
|
+
|
|
185
191
|
reviewer_usernames = reviewers.map(&:username)
|
|
186
192
|
|
|
187
193
|
@out.puts "Requesting review from #{reviewer_usernames.join(', ')}..."
|
|
@@ -192,18 +198,21 @@ module Geet
|
|
|
192
198
|
end
|
|
193
199
|
|
|
194
200
|
def enable_automerge(pr)
|
|
201
|
+
raise "Functionality unsupported on GitLab!" if pr.is_a?(Gitlab::PR)
|
|
202
|
+
|
|
195
203
|
if !pr.respond_to?(:enable_automerge)
|
|
196
204
|
raise "Automerge is not supported for this repository provider"
|
|
197
205
|
elsif !pr.respond_to?(:node_id) || pr.node_id.nil?
|
|
198
206
|
raise "Automerge requires node_id from the API (not available in the response)"
|
|
199
207
|
end
|
|
200
208
|
|
|
201
|
-
@out.
|
|
209
|
+
@out.print "Enabling automerge... "
|
|
202
210
|
|
|
203
211
|
begin
|
|
204
|
-
pr.enable_automerge
|
|
212
|
+
merge_method = pr.enable_automerge
|
|
213
|
+
@out.puts merge_method
|
|
205
214
|
rescue Geet::Shared::HttpError => e
|
|
206
|
-
@out.puts "
|
|
215
|
+
@out.puts "", "WARNING: Could not enable automerge: #{e.message}"
|
|
207
216
|
end
|
|
208
217
|
end
|
|
209
218
|
end
|
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
5
6
|
class ListIssues
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
6
9
|
include Geet::Shared::Selection
|
|
7
10
|
|
|
11
|
+
sig {
|
|
12
|
+
params(
|
|
13
|
+
repository: Git::Repository,
|
|
14
|
+
out: StringIO
|
|
15
|
+
).void
|
|
16
|
+
}
|
|
8
17
|
def initialize(repository, out: $stdout)
|
|
9
18
|
@repository = repository
|
|
10
19
|
@out = out
|
|
11
20
|
end
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
sig {
|
|
23
|
+
params(
|
|
24
|
+
assignee: T.nilable(String)
|
|
25
|
+
).returns(T::Array[T.any(Github::Issue, Gitlab::Issue)])
|
|
26
|
+
}
|
|
27
|
+
def execute(assignee: nil)
|
|
14
28
|
selected_assignee = find_and_select_attributes(assignee) if assignee
|
|
15
29
|
|
|
16
30
|
issues = @repository.issues(assignee: selected_assignee)
|
|
@@ -22,6 +36,11 @@ module Geet
|
|
|
22
36
|
|
|
23
37
|
private
|
|
24
38
|
|
|
39
|
+
sig {
|
|
40
|
+
params(
|
|
41
|
+
assignee: String
|
|
42
|
+
).returns(T.any(Github::User, Gitlab::User))
|
|
43
|
+
}
|
|
25
44
|
def find_and_select_attributes(assignee)
|
|
26
45
|
selection_manager = Geet::Utils::AttributesSelectionManager.new(@repository, out: @out)
|
|
27
46
|
|
|
@@ -1,22 +1,37 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Services
|
|
5
6
|
# Open in the browser the PR for the current branch.
|
|
6
7
|
#
|
|
7
8
|
class OpenPr
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
8
11
|
include Geet::Helpers::OsHelper
|
|
9
12
|
include Geet::Helpers::ServicesWorkflowHelper
|
|
10
13
|
|
|
11
14
|
DEFAULT_GIT_CLIENT = Geet::Utils::GitClient.new
|
|
12
15
|
|
|
16
|
+
sig {
|
|
17
|
+
params(
|
|
18
|
+
repository: Git::Repository,
|
|
19
|
+
out: StringIO,
|
|
20
|
+
git_client: Utils::GitClient
|
|
21
|
+
).void
|
|
22
|
+
}
|
|
13
23
|
def initialize(repository, out: $stdout, git_client: DEFAULT_GIT_CLIENT)
|
|
14
24
|
@repository = repository
|
|
15
25
|
@out = out
|
|
16
26
|
@git_client = git_client
|
|
17
27
|
end
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
sig {
|
|
30
|
+
params(
|
|
31
|
+
delete_branch: T::Boolean
|
|
32
|
+
).returns(T.any(Github::PR, Gitlab::PR))
|
|
33
|
+
}
|
|
34
|
+
def execute(delete_branch: false)
|
|
20
35
|
pr = checked_find_branch_pr
|
|
21
36
|
open_file_with_default_application(pr.link)
|
|
22
37
|
pr
|
data/lib/geet/version.rb
CHANGED
|
@@ -57,8 +57,7 @@ describe Geet::Services::CreateIssue do
|
|
|
57
57
|
actual_output = StringIO.new
|
|
58
58
|
|
|
59
59
|
actual_created_issue = VCR.use_cassette('create_issue_upstream') do
|
|
60
|
-
|
|
61
|
-
described_class.new(upstream_repository, out: actual_output).execute('Title', 'Description', **create_options)
|
|
60
|
+
described_class.new(upstream_repository, out: actual_output).execute('Title', 'Description')
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
expect(actual_output.string).to eql(expected_output)
|