labclient 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/labclient.rb +23 -4
  3. data/lib/labclient/access_levels.rb +24 -30
  4. data/lib/labclient/branches/branch.rb +25 -0
  5. data/lib/labclient/branches/create.rb +33 -0
  6. data/lib/labclient/client.rb +48 -7
  7. data/lib/labclient/docs.rb +9 -5
  8. data/lib/labclient/epics/epic.rb +13 -0
  9. data/lib/labclient/error.rb +1 -0
  10. data/lib/labclient/files/create.rb +14 -8
  11. data/lib/labclient/generator/generator.rb +70 -0
  12. data/lib/labclient/generator/names.rb +68 -0
  13. data/lib/labclient/generator/template_helper.rb +81 -0
  14. data/lib/labclient/generator/templates/environments.rb +98 -0
  15. data/lib/labclient/generator/templates/pages.rb +67 -0
  16. data/lib/labclient/generator/templates/pipeline_trigger.rb +82 -0
  17. data/lib/labclient/generator/wizard.rb +142 -0
  18. data/lib/labclient/groups/group.rb +9 -1
  19. data/lib/labclient/http.rb +3 -2
  20. data/lib/labclient/issues/create.rb +2 -0
  21. data/lib/labclient/issues/issue.rb +31 -1
  22. data/lib/labclient/issues/update.rb +20 -2
  23. data/lib/labclient/jobs/delete.rb +1 -1
  24. data/lib/labclient/jobs/keep.rb +1 -1
  25. data/lib/labclient/jobs/play.rb +1 -1
  26. data/lib/labclient/jobs/trace.rb +2 -2
  27. data/lib/labclient/klass.rb +34 -4
  28. data/lib/labclient/lab_struct.rb +17 -0
  29. data/lib/labclient/license/list.rb +2 -2
  30. data/lib/labclient/members/member.rb +1 -0
  31. data/lib/labclient/merge_requests/accept.rb +15 -6
  32. data/lib/labclient/merge_requests/create.rb +12 -0
  33. data/lib/labclient/merge_requests/merge_request.rb +49 -4
  34. data/lib/labclient/notes/epics/create.rb +12 -4
  35. data/lib/labclient/notes/epics/delete.rb +3 -3
  36. data/lib/labclient/notes/epics/list.rb +21 -4
  37. data/lib/labclient/notes/epics/show.rb +4 -4
  38. data/lib/labclient/notes/epics/update.rb +4 -4
  39. data/lib/labclient/notes/issues/create.rb +11 -1
  40. data/lib/labclient/notes/issues/list.rb +18 -3
  41. data/lib/labclient/notes/issues/show.rb +1 -1
  42. data/lib/labclient/notes/merge_requests/create.rb +8 -0
  43. data/lib/labclient/notes/merge_requests/list.rb +20 -2
  44. data/lib/labclient/notes/snippets/create.rb +1 -1
  45. data/lib/labclient/notes/snippets/list.rb +20 -3
  46. data/lib/labclient/notes/snippets/show.rb +1 -1
  47. data/lib/labclient/notifications/update.rb +1 -1
  48. data/lib/labclient/overview.rb +110 -11
  49. data/lib/labclient/paginated_response.rb +8 -1
  50. data/lib/labclient/pipelines/pipeline.rb +41 -0
  51. data/lib/labclient/projects/methods.rb +71 -2
  52. data/lib/labclient/projects/reference.rb +14 -0
  53. data/lib/labclient/projects/snippets/project_snippet.rb +12 -0
  54. data/lib/labclient/protected_branches/protect.rb +6 -5
  55. data/lib/labclient/protected_environments/list.rb +29 -0
  56. data/lib/labclient/protected_environments/protect.rb +53 -0
  57. data/lib/labclient/protected_environments/protected_environment.rb +22 -0
  58. data/lib/labclient/protected_environments/show.rb +24 -0
  59. data/lib/labclient/protected_environments/unprotect.rb +31 -0
  60. data/lib/labclient/snippets/snippet.rb +2 -2
  61. data/lib/labclient/users/membership.rb +62 -0
  62. data/lib/labclient/users/memberships.rb +8 -3
  63. data/lib/labclient/users/user.rb +13 -1
  64. data/lib/labclient/version.rb +1 -1
  65. metadata +37 -9
  66. 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.dig(:projects).blank?
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
@@ -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'] == 'text/plain'
76
+ elsif headers['content-type']&.include? 'text/plain'
76
77
  body
77
78
  else
78
- Oj.load(body, mode: :compat, object_class: OpenStruct)
79
+ Oj.load(body, mode: :compat, object_class: LabClient::LabStruct)
79
80
  end
80
81
  end
81
82
 
@@ -33,6 +33,8 @@ module LabClient
33
33
 
34
34
  def create(project_id, query = {})
35
35
  project_id = format_id(project_id)
36
+ format_query_id(:assignee_id, query)
37
+
36
38
  client.request(:post, "projects/#{project_id}/issues", Issue, query)
37
39
  end
38
40
  end
@@ -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
- desc 'Close Ticket'
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.update(title: "Dew it!")
51
+ issue.reopen
34
52
  DOC
35
53
  end
36
54
 
@@ -3,7 +3,7 @@ module LabClient
3
3
  # Specifics
4
4
  class Jobs < Common
5
5
  doc 'Update' do
6
- title 'Retry'
6
+ title 'Delete'
7
7
  desc 'Delete artifacts of a job. [Project ID, Job ID]'
8
8
  example 'client.jobs.delete(264, 14)'
9
9
  end
@@ -3,7 +3,7 @@ module LabClient
3
3
  # Specifics
4
4
  class Jobs < Common
5
5
  doc 'Update' do
6
- title 'Retry'
6
+ title 'Keep'
7
7
  desc 'Prevents artifacts from being deleted when expiration is set. [Project ID, Job ID]'
8
8
  example 'client.jobs.keep(264, 14)'
9
9
  end
@@ -3,7 +3,7 @@ module LabClient
3
3
  # Specifics
4
4
  class Jobs < Common
5
5
  doc 'Update' do
6
- title 'Retry'
6
+ title 'Play'
7
7
  desc 'Triggers a manual action to start a job. [Project ID, Job ID]'
8
8
  example 'client.jobs.play(264, 14)'
9
9
  end
@@ -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
- puts client.request(:get, "projects/#{project_id}/jobs/#{job_id}/trace")
30
+ client.request(:get, "projects/#{project_id}/jobs/#{job_id}/trace")
31
31
  end
32
32
  end
33
33
  end
@@ -1,19 +1,21 @@
1
1
  # Top Namesapce
2
2
  module LabClient
3
3
  # Common Configuration for all Class Helpers
4
- class Klass < OpenStruct
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
- def help
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
- puts ' ' + opt[:name]
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