labclient 0.1.1 → 0.2.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/lib/labclient.rb +23 -4
- data/lib/labclient/access_levels.rb +24 -30
- data/lib/labclient/branches/branch.rb +25 -0
- data/lib/labclient/branches/create.rb +33 -0
- data/lib/labclient/client.rb +48 -7
- data/lib/labclient/docs.rb +9 -5
- data/lib/labclient/epics/epic.rb +13 -0
- data/lib/labclient/error.rb +1 -0
- data/lib/labclient/files/create.rb +14 -8
- data/lib/labclient/generator/generator.rb +70 -0
- data/lib/labclient/generator/names.rb +68 -0
- data/lib/labclient/generator/template_helper.rb +81 -0
- data/lib/labclient/generator/templates/environments.rb +98 -0
- data/lib/labclient/generator/templates/pages.rb +67 -0
- data/lib/labclient/generator/templates/pipeline_trigger.rb +82 -0
- data/lib/labclient/generator/wizard.rb +142 -0
- data/lib/labclient/groups/group.rb +9 -1
- data/lib/labclient/http.rb +3 -2
- data/lib/labclient/issues/create.rb +2 -0
- data/lib/labclient/issues/issue.rb +31 -1
- data/lib/labclient/issues/update.rb +20 -2
- data/lib/labclient/jobs/delete.rb +1 -1
- data/lib/labclient/jobs/keep.rb +1 -1
- data/lib/labclient/jobs/play.rb +1 -1
- data/lib/labclient/jobs/trace.rb +2 -2
- data/lib/labclient/klass.rb +34 -4
- data/lib/labclient/lab_struct.rb +17 -0
- data/lib/labclient/license/list.rb +2 -2
- data/lib/labclient/members/member.rb +1 -0
- data/lib/labclient/merge_requests/accept.rb +15 -6
- data/lib/labclient/merge_requests/create.rb +12 -0
- data/lib/labclient/merge_requests/merge_request.rb +49 -4
- data/lib/labclient/notes/epics/create.rb +12 -4
- data/lib/labclient/notes/epics/delete.rb +3 -3
- data/lib/labclient/notes/epics/list.rb +21 -4
- data/lib/labclient/notes/epics/show.rb +4 -4
- data/lib/labclient/notes/epics/update.rb +4 -4
- data/lib/labclient/notes/issues/create.rb +11 -1
- data/lib/labclient/notes/issues/list.rb +18 -3
- data/lib/labclient/notes/issues/show.rb +1 -1
- data/lib/labclient/notes/merge_requests/create.rb +8 -0
- data/lib/labclient/notes/merge_requests/list.rb +20 -2
- data/lib/labclient/notes/snippets/create.rb +1 -1
- data/lib/labclient/notes/snippets/list.rb +20 -3
- data/lib/labclient/notes/snippets/show.rb +1 -1
- data/lib/labclient/notifications/update.rb +1 -1
- data/lib/labclient/overview.rb +110 -11
- data/lib/labclient/paginated_response.rb +8 -1
- data/lib/labclient/pipelines/pipeline.rb +41 -0
- data/lib/labclient/projects/methods.rb +71 -2
- data/lib/labclient/projects/reference.rb +14 -0
- data/lib/labclient/projects/snippets/project_snippet.rb +12 -0
- data/lib/labclient/protected_branches/protect.rb +6 -5
- data/lib/labclient/protected_environments/list.rb +29 -0
- data/lib/labclient/protected_environments/protect.rb +53 -0
- data/lib/labclient/protected_environments/protected_environment.rb +22 -0
- data/lib/labclient/protected_environments/show.rb +24 -0
- data/lib/labclient/protected_environments/unprotect.rb +31 -0
- data/lib/labclient/snippets/snippet.rb +2 -2
- data/lib/labclient/users/membership.rb +62 -0
- data/lib/labclient/users/memberships.rb +8 -3
- data/lib/labclient/users/user.rb +13 -1
- data/lib/labclient/version.rb +1 -1
- metadata +37 -9
- data/lib/labclient/open_struct.rb +0 -14
@@ -0,0 +1,142 @@
|
|
1
|
+
module LabClient
|
2
|
+
# Generator Namespace
|
3
|
+
module Generator
|
4
|
+
# Helper to Generate Data / Populate GitLab
|
5
|
+
class Wizard
|
6
|
+
include Generator::Names # Name Generator
|
7
|
+
attr_reader :client
|
8
|
+
attr_accessor :count, :random, :password, :templates, :domain, :skip_confirmation
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"#<Wizard count=#{count}, random=#{random}, domain=#{domain}> templates=#{templates}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def templates_default
|
15
|
+
%i[pages pipeline_trigger environments]
|
16
|
+
end
|
17
|
+
|
18
|
+
def templates_all
|
19
|
+
LabClient::Generator::TemplateHelper.descendants
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(client)
|
23
|
+
require 'faker' # Ensure Faker is Available
|
24
|
+
|
25
|
+
@client = client
|
26
|
+
self.random = true # Populate Random or use only Templates
|
27
|
+
self.count = default_count
|
28
|
+
self.password = SecureRandom.uuid
|
29
|
+
puts "Default Password: #{password}"
|
30
|
+
|
31
|
+
self.skip_confirmation = true
|
32
|
+
self.domain = URI.parse(client.settings[:url]).hostname
|
33
|
+
|
34
|
+
# Default Templates
|
35
|
+
self.templates ||= templates_default
|
36
|
+
end
|
37
|
+
|
38
|
+
def template(name, opts = {})
|
39
|
+
template_klass = templates_all.find { |x| x.template_name == name.to_sym }
|
40
|
+
|
41
|
+
raise "Invalid Template! Available Templates: #{templates_all.map(&:template_name).join(', ')}" unless template_klass
|
42
|
+
|
43
|
+
template_klass.new(client, opts)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Random Counters
|
47
|
+
def default_count
|
48
|
+
{
|
49
|
+
users: 20,
|
50
|
+
projects: 5,
|
51
|
+
groups: 5,
|
52
|
+
issues: 2
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_users
|
57
|
+
puts 'Generating Users'
|
58
|
+
@users = @user_names.map do |name|
|
59
|
+
username = name.downcase.gsub(/[^0-9A-Za-z]/, '')
|
60
|
+
email = "#{username}@#{domain}"
|
61
|
+
puts "User -- Name: #{name}, UserName: #{username}, Email: #{email}"
|
62
|
+
|
63
|
+
client.users.create(
|
64
|
+
name: name,
|
65
|
+
email: email,
|
66
|
+
password: password,
|
67
|
+
username: username,
|
68
|
+
skip_confirmation: skip_confirmation
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def generate_groups
|
74
|
+
puts 'Generating Groups'
|
75
|
+
@groups = @group_names.map do |name|
|
76
|
+
path = name.downcase.gsub(/[^0-9A-Za-z]/, '')
|
77
|
+
puts "Group -- #{name}/#{path}"
|
78
|
+
client.groups.create(name: name, path: path)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def generate_group_membership
|
83
|
+
puts 'Adding Group members'
|
84
|
+
## Group Access Level
|
85
|
+
@groups.each do |group|
|
86
|
+
@users.sample(rand(1..@users.count)).each do |user|
|
87
|
+
level = group.valid_group_project_levels.sample
|
88
|
+
puts "Group Add: #{group.name}: #{user.name} - #{level}"
|
89
|
+
group.member_add(user, access_level: level)
|
90
|
+
# :nocov:
|
91
|
+
rescue StandardError => e
|
92
|
+
puts e.message
|
93
|
+
next
|
94
|
+
# :nocov:
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def generate_projects(group)
|
100
|
+
puts 'Generating Projects'
|
101
|
+
# Collect Group Members
|
102
|
+
members = group.members
|
103
|
+
|
104
|
+
# Loop through project names, create project add issues
|
105
|
+
@project_names.uniq.map do |project_name|
|
106
|
+
puts "Project: #{project_name}"
|
107
|
+
project = group.project_create(name: project_name, description: gen_description)
|
108
|
+
|
109
|
+
rand(count[:issues]).times do
|
110
|
+
project.issue_create(generate_issue_data(members.sample))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def generate_issue_data(member)
|
116
|
+
{
|
117
|
+
assignee_id: member.id,
|
118
|
+
description: Faker::Hacker.say_something_smart,
|
119
|
+
title: Faker::Company.catch_phrase
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
# Execute Generation
|
124
|
+
def run!
|
125
|
+
# Collect Names
|
126
|
+
generate_names
|
127
|
+
generate_users
|
128
|
+
generate_groups
|
129
|
+
generate_group_membership
|
130
|
+
|
131
|
+
@groups.map do |group|
|
132
|
+
generate_projects(group)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Run Templates
|
136
|
+
templates.each { |template_klass| template(template_klass).run! }
|
137
|
+
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -42,7 +42,7 @@ module LabClient
|
|
42
42
|
|
43
43
|
def projects(query = {})
|
44
44
|
# Details Query Includes Projects
|
45
|
-
if query.empty? && !@table
|
45
|
+
if query.empty? && !@table[:projects].blank?
|
46
46
|
@table[:projects].map { |project| LabClient::Project.new(project, response, client) }
|
47
47
|
else
|
48
48
|
client.groups.projects(id, query)
|
@@ -246,6 +246,11 @@ module LabClient
|
|
246
246
|
client.groups.milestones.list(id, query)
|
247
247
|
end
|
248
248
|
|
249
|
+
# Reload Helper
|
250
|
+
def reload
|
251
|
+
update_self client.groups.show(id)
|
252
|
+
end
|
253
|
+
|
249
254
|
# rubocop:disable Metrics/BlockLength
|
250
255
|
help do
|
251
256
|
subtitle 'Group'
|
@@ -319,6 +324,9 @@ module LabClient
|
|
319
324
|
|
320
325
|
# Registry
|
321
326
|
option 'registry_repositories', 'Get a list of registry repositories [Hash]'
|
327
|
+
|
328
|
+
# Reload Helper
|
329
|
+
option 'reload', 'Reload this object (New API Call)'
|
322
330
|
end
|
323
331
|
# rubocop:enable Metrics/BlockLength
|
324
332
|
end
|
data/lib/labclient/http.rb
CHANGED
@@ -3,6 +3,7 @@ module LabClient
|
|
3
3
|
# Request Helper
|
4
4
|
class HTTP
|
5
5
|
attr_accessor :settings
|
6
|
+
|
6
7
|
def initialize(settings)
|
7
8
|
self.settings = settings
|
8
9
|
end
|
@@ -72,10 +73,10 @@ module Typhoeus
|
|
72
73
|
def process_body
|
73
74
|
if body.empty?
|
74
75
|
nil
|
75
|
-
elsif headers['content-type']
|
76
|
+
elsif headers['content-type']&.include? 'text/plain'
|
76
77
|
body
|
77
78
|
else
|
78
|
-
Oj.load(body, mode: :compat, object_class:
|
79
|
+
Oj.load(body, mode: :compat, object_class: LabClient::LabStruct)
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -14,6 +14,16 @@ module LabClient
|
|
14
14
|
# User Fields
|
15
15
|
user_attrs %i[closed_by author assignee]
|
16
16
|
|
17
|
+
# Via State Events
|
18
|
+
def close
|
19
|
+
client.issues.update(project_id, iid, state_event: :close)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Via State Events
|
23
|
+
def reopen
|
24
|
+
client.issues.update(project_id, iid, state_event: :reopen)
|
25
|
+
end
|
26
|
+
|
17
27
|
def update(query)
|
18
28
|
client.issues.update(project_id, iid, query)
|
19
29
|
end
|
@@ -66,6 +76,10 @@ module LabClient
|
|
66
76
|
client.notes.issues.list(project_id, iid)
|
67
77
|
end
|
68
78
|
|
79
|
+
def note_create(query)
|
80
|
+
client.notes.issues.create(project_id, iid, query)
|
81
|
+
end
|
82
|
+
|
69
83
|
def agent_detail
|
70
84
|
client.issues.agent_detail(project_id, iid)
|
71
85
|
end
|
@@ -87,6 +101,18 @@ module LabClient
|
|
87
101
|
client.resource_labels.issues.show(project_id, iid, resource_event_id)
|
88
102
|
end
|
89
103
|
|
104
|
+
# Reload Helper
|
105
|
+
def reload
|
106
|
+
update_self client.issues.show(project_id, iid)
|
107
|
+
end
|
108
|
+
|
109
|
+
def project
|
110
|
+
# If from List Project ID isn't stored
|
111
|
+
project_id = collect_project_id if project_id.nil?
|
112
|
+
|
113
|
+
client.projects.show(project_id)
|
114
|
+
end
|
115
|
+
|
90
116
|
help do
|
91
117
|
subtitle 'Issue'
|
92
118
|
option 'update', 'Update issue (accepts hash).'
|
@@ -95,7 +121,8 @@ module LabClient
|
|
95
121
|
option 'subscribe', 'Subscribe to notifications'
|
96
122
|
option 'unsubscribe', 'Unsubscribe to notifications'
|
97
123
|
option 'participants', 'List participants in this issue.'
|
98
|
-
option 'notes', 'List notes/comments.'
|
124
|
+
option 'notes', 'List notes/comments. [Hash]'
|
125
|
+
option 'note_create', 'Creates a new note for issue. [Hash]'
|
99
126
|
option 'agent_detail', 'Get user agent details.'
|
100
127
|
option 'related_merge_requests', 'Get all related Merge Requests.'
|
101
128
|
option 'closed_by', 'Get all Merge Requests that will close this issue.'
|
@@ -109,6 +136,9 @@ module LabClient
|
|
109
136
|
# Resource Labels
|
110
137
|
option 'resource_labels', 'List of all label events'
|
111
138
|
option 'resource_label', 'Show single label event [Resource Event ID]'
|
139
|
+
|
140
|
+
# Reload Helper
|
141
|
+
option 'reload', 'Reload this object (New API Call)'
|
112
142
|
end
|
113
143
|
end
|
114
144
|
end
|
@@ -18,19 +18,37 @@ module LabClient
|
|
18
18
|
|-------------------------------------------|----------------|----------|--------------|
|
19
19
|
| title | string | no | The title of an issue |
|
20
20
|
| description | string | no | The description of an issue. Limited to 1,048,576 characters. |
|
21
|
+
|
22
|
+
|
21
23
|
DOC
|
22
24
|
end
|
23
25
|
|
24
26
|
doc 'Update' do
|
25
|
-
|
27
|
+
title 'Close / Reopen'
|
28
|
+
markdown <<~DOC
|
29
|
+
Closing/Reopening of issues is handled via state_events. Either :close, or :reopen. The issue objects themselves also have helpers `reopen` `close`.
|
30
|
+
DOC
|
31
|
+
|
26
32
|
example 'client.issues.update(5, 1, state_event: :close)'
|
27
33
|
end
|
28
34
|
|
35
|
+
doc 'Update' do
|
36
|
+
example 'client.issues.update(5, 1, state_event: :reopen)'
|
37
|
+
end
|
38
|
+
|
39
|
+
doc 'Update' do
|
40
|
+
desc 'Through Issue Object'
|
41
|
+
example <<~DOC
|
42
|
+
issue = client.issues.show(5,1)
|
43
|
+
issue.close
|
44
|
+
DOC
|
45
|
+
end
|
46
|
+
|
29
47
|
doc 'Update' do
|
30
48
|
desc 'Through Issue Object'
|
31
49
|
example <<~DOC
|
32
50
|
issue = client.issues.show(5,1)
|
33
|
-
issue.
|
51
|
+
issue.reopen
|
34
52
|
DOC
|
35
53
|
end
|
36
54
|
|
data/lib/labclient/jobs/keep.rb
CHANGED
data/lib/labclient/jobs/play.rb
CHANGED
data/lib/labclient/jobs/trace.rb
CHANGED
@@ -20,14 +20,14 @@ module LabClient
|
|
20
20
|
desc 'via Job'
|
21
21
|
example <<~DOC
|
22
22
|
job = client.jobs.show(264,1)
|
23
|
-
job.trace
|
23
|
+
job.trace #=> String
|
24
24
|
DOC
|
25
25
|
end
|
26
26
|
|
27
27
|
def trace(project_id, job_id)
|
28
28
|
job_id = format_id(job_id)
|
29
29
|
project_id = format_id(project_id)
|
30
|
-
|
30
|
+
client.request(:get, "projects/#{project_id}/jobs/#{job_id}/trace")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
data/lib/labclient/klass.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
# Top Namesapce
|
2
2
|
module LabClient
|
3
3
|
# Common Configuration for all Class Helpers
|
4
|
-
class Klass <
|
4
|
+
class Klass < LabStruct
|
5
5
|
include CurlHelper
|
6
6
|
|
7
7
|
attr_reader :client, :response
|
8
|
+
|
8
9
|
extend Docs
|
9
10
|
|
10
11
|
def verbose
|
11
|
-
ap self
|
12
|
+
ap self, ruby19_syntax: true
|
12
13
|
end
|
13
14
|
|
14
15
|
# API Methods here have to be explicitly documented / custom helpers
|
15
16
|
# Assume no methods by default
|
16
|
-
|
17
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
18
|
+
def help(help_filter = nil)
|
17
19
|
docs = LabClient::Docs.docs.dig(group_name, 'Reference')
|
18
20
|
unless docs
|
19
21
|
puts 'No Available Help'
|
@@ -25,7 +27,11 @@ module LabClient
|
|
25
27
|
next unless doc[:options]
|
26
28
|
|
27
29
|
doc[:options].each do |opt|
|
28
|
-
|
30
|
+
if help_filter
|
31
|
+
next unless (opt[:name] + opt[:text]).include? help_filter.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
puts " #{opt[:name]}"
|
29
35
|
puts " #{opt[:text]}\n"
|
30
36
|
end
|
31
37
|
end
|
@@ -33,6 +39,23 @@ module LabClient
|
|
33
39
|
# Ignore Output
|
34
40
|
nil
|
35
41
|
end
|
42
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
43
|
+
|
44
|
+
# Documented API Methods
|
45
|
+
def api_methods
|
46
|
+
docs = LabClient::Docs.docs.dig(group_name, 'Reference')
|
47
|
+
|
48
|
+
unless docs
|
49
|
+
puts 'No Available Help'
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
|
53
|
+
LabClient::Docs.docs.dig(group_name, 'Reference').map do |doc|
|
54
|
+
doc[:options].map do |opt|
|
55
|
+
opt[:name]
|
56
|
+
end
|
57
|
+
end.flatten.sort
|
58
|
+
end
|
36
59
|
|
37
60
|
def valid_group_project_levels
|
38
61
|
%i[guest reporter developer maintainer owner]
|
@@ -74,6 +97,7 @@ module LabClient
|
|
74
97
|
self
|
75
98
|
end
|
76
99
|
|
100
|
+
# rubocop:disable Lint/MissingSuper
|
77
101
|
def initialize(hash = nil, response = nil, client = nil)
|
78
102
|
@client = client
|
79
103
|
@response = response
|
@@ -84,6 +108,12 @@ module LabClient
|
|
84
108
|
@table[k] = v
|
85
109
|
end
|
86
110
|
end
|
111
|
+
# rubocop:enable Lint/MissingSuper
|
112
|
+
|
113
|
+
# Forward response success
|
114
|
+
def success?
|
115
|
+
@response.success?
|
116
|
+
end
|
87
117
|
|
88
118
|
# Formatting Time Helper
|
89
119
|
def format_time?(time)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Extensions for OpenStruct specific to LabClient
|
2
|
+
module LabClient
|
3
|
+
# Unique inherited class to not override top level openstruct
|
4
|
+
class LabStruct < OpenStruct
|
5
|
+
def keys
|
6
|
+
to_h.keys.sort
|
7
|
+
end
|
8
|
+
|
9
|
+
def inspect
|
10
|
+
to_h.inspect
|
11
|
+
end
|
12
|
+
|
13
|
+
def as_json(*args)
|
14
|
+
super.as_json['table']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|