labclient 0.1.1 → 0.1.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: 0cfc44546096a710f5e2a8ed0b500b202825150b03a029738d8b870cf4258e94
4
- data.tar.gz: c965712946b26eef38ae7546a483688eae0ae20cc82480dad59262aa050ba18c
3
+ metadata.gz: 4ea1ef7fca86883f565358293520dd1b39484ca9c190e543408d91eba2d2e0e5
4
+ data.tar.gz: 4d963d0f5b7740d9e514ab3e5bc170576a628e7f8642d59cf6777463cd0c3141
5
5
  SHA512:
6
- metadata.gz: 77a79ac90bfa375a488633c9aa530581a8235c3b5c0d00fd24644ccb962fd39152facc298e77a016cffb200f65b301e6d2c7a1ed883f2dfd2ea0dc6d96ea185d
7
- data.tar.gz: cc4cb427458a49007775e063fc065df0623c76f4abe05f0b93279e3ca1638b9b0c024074cb8ac57e7ab732543c39da7cb9f436f2ca85263995c72bbf083d1df9
6
+ metadata.gz: b46b5af89a9b7beafd0b7287e7c6047200e748cfedcd72021231823d75885b1551158d4d80227b1a6ba6c09b6024c27a02f63cb0aaefa8ea399c13a669fcaa94
7
+ data.tar.gz: 5bf022a157f8f3cccdd0776a5e851bfe6a30ad189efcee4da7c3c43bc27cc5eb8ca185d857d165024f83edb17ec992657b4f33cc3a9065a19f2ab15655d9fc67
@@ -842,5 +842,14 @@ require 'labclient/resource_labels/merge_requests/show'
842
842
 
843
843
  require 'labclient/resource_labels/resource_label'
844
844
 
845
+ # Generators
846
+ require 'labclient/generator/names'
847
+ require 'labclient/generator/templates/template' # Helper
848
+ require 'labclient/generator/templates/pages'
849
+
850
+ # Wizard
851
+ require 'labclient/generator/generator'
852
+ require 'labclient/generator/wizard'
853
+
845
854
  # I am Very Last
846
855
  require 'labclient/client'
@@ -37,6 +37,7 @@ module LabClient
37
37
  epics: Epics,
38
38
  events: Events,
39
39
  files: Files,
40
+ wizard: Generator::Wizard,
40
41
  groups: Groups,
41
42
  impersonation_tokens: ImpersonationTokens,
42
43
  issues: Issues,
@@ -0,0 +1,82 @@
1
+ # The glorious gitlab labclient of labs
2
+ module LabClient
3
+ # Generator Namespace
4
+ module Generator
5
+ # Docs for the wizard
6
+ class GeneratorDocs
7
+ @group_name = 'Wizard'
8
+ extend Docs
9
+
10
+ doc 'Wizard' do
11
+ markdown <<~DOC
12
+ <h6 style="color:red"><b>Experimental</b></h6>
13
+
14
+ This is experimental and will be likely changing frequently and dramatically. This will create (*potentially many*) and manipulate objects within GitLab. **This is not recommended for use in production environments**
15
+ DOC
16
+ end
17
+
18
+ doc 'Wizard' do
19
+ title 'About'
20
+ markdown <<~DOC
21
+ The Wizard is designed to help setup test instances, and provide easy mechanisms for populating and testing GitLab features.
22
+
23
+ Requires 'faker' to function, which will need to be manually/added installed, as it is not a depdenency of the gem.
24
+ DOC
25
+
26
+ example 'gem install faker'
27
+ end
28
+
29
+ doc 'Wizard' do
30
+ title 'Client'
31
+ desc <<-DOC
32
+ The wizard client will self-populate with defaults and parameters from the main client object. But each can be manually configured.
33
+ DOC
34
+
35
+ example <<~DOC
36
+ wizard = client.wizard
37
+ => #<Wizard count={:users=>20, :projects=>5, :groups=>5, :issues=>2}, random=true, domain=labclient>
38
+
39
+ # Disable Random
40
+ wizard.random = false
41
+ DOC
42
+ end
43
+
44
+ doc 'Wizard' do
45
+ markdown <<~DOC
46
+ | Setting | Type | Description |
47
+ | -------- | ------- | ------------------------------------------------------ |
48
+ | random | Boolean | Run Populate. Setup random Users, Projects, and Groups |
49
+ | count | Hash | Settings for random. User, Project, Group count |
50
+ | password | String | Default password for generated Users |
51
+ | domain | String | Defaults to client url. Default email domain for users |
52
+
53
+ DOC
54
+ end
55
+
56
+ doc 'Wizard' do
57
+ title 'Templates'
58
+ desc <<-DOC
59
+ Outside of the wizard at large, you can also select and manually run specific templates.
60
+ DOC
61
+
62
+ example <<~DOC
63
+ pages = client.wizard.pages
64
+ => #<LabClient::Template Pages>
65
+ pages.run! # Run pages template
66
+ DOC
67
+ end
68
+
69
+ doc 'Pages' do
70
+ markdown <<~DOC
71
+ Create GitLab Pages group and test projects. Projects imported from Gitlab's [demo pages projects](https://gitlab.com/pages)
72
+
73
+ | Setting | Default | Type | Description |
74
+ | ---------- | --------- | ------- | -------------------------------------- |
75
+ | group_name | Generated | String | Parent Group name for pages projects |
76
+ | group_path | Generated | String | Parent Group path |
77
+ | count | 5 | Integer | Number of projects to import (max: 28) |
78
+ DOC
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,54 @@
1
+ # Name Generator
2
+ module LabClient
3
+ # Helper to Generate Data / Populate GitLab
4
+ module Generator
5
+ # Name Helper
6
+ module Names
7
+ def gen_groups
8
+ [
9
+ Faker::Games::LeagueOfLegends.location,
10
+ Faker::Movies::LordOfTheRings.location,
11
+ Faker::TvShows::RickAndMorty.location,
12
+ Faker::TvShows::StarTrek.location,
13
+ Faker::Games::ElderScrolls.region
14
+ ].map { |x| x.gsub(/[^0-9A-Za-z]/, '') }
15
+ end
16
+
17
+ def gen_projects
18
+ [
19
+ Faker::Games::ElderScrolls.creature,
20
+ Faker::Games::LeagueOfLegends.summoner_spell,
21
+ Faker::Games::LeagueOfLegends.masteries,
22
+ Faker::Superhero.power
23
+ ].map { |x| x.gsub(/[^0-9A-Za-z]/, '') }
24
+ end
25
+
26
+ def gen_people
27
+ [
28
+ Faker::Movies::LordOfTheRings.character,
29
+ Faker::Games::WorldOfWarcraft.hero,
30
+ Faker::TvShows::StarTrek.character,
31
+ Faker::Games::LeagueOfLegends.champion,
32
+ Faker::Movies::PrincessBride.character
33
+ ]
34
+ end
35
+
36
+ def gen_description
37
+ [
38
+ Faker::Hacker.say_something_smart,
39
+ Faker::Games::LeagueOfLegends.quote,
40
+ Faker::Company.bs,
41
+ Faker::Movies::PrincessBride.quote
42
+ ].sample
43
+ end
44
+
45
+ # rubocop:disable Metrics/AbcSize
46
+ def generate_names
47
+ @user_names = Array.new(count[:users]) { gen_people }.flatten.uniq.sample(count[:users])
48
+ @group_names = Array.new(count[:groups]) { gen_groups }.flatten.uniq
49
+ @project_names = Array.new(rand(count[:projects])) { gen_projects.sample }.uniq
50
+ end
51
+ # rubocop:enable Metrics/AbcSize
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,73 @@
1
+ module LabClient
2
+ module Generator
3
+ # Page Import Creation
4
+ class Pages < TemplateHelper
5
+ include Names
6
+ attr_accessor :group_name, :group_path, :count
7
+
8
+ # All Available Pages Projects
9
+ def list
10
+ %w[
11
+ brunch doxygen emacs-reveal frozen-flask gatsby
12
+ gitbook hakyll harp hexo hugo hyde ikiwiki
13
+ jekyll jigsaw lektor metalsmith
14
+ middleman mkdocs nanoc nikola nuxt octopress
15
+ org-mode pelican plain-html sphinx vuepress zim
16
+ ]
17
+ end
18
+
19
+ def setup
20
+ self.group_name = opts[:group_name] || "#{gen_groups.sample} Pages"
21
+ self.group_path = opts[:group_path] || group_name.downcase.gsub(' ', '-')
22
+ self.count = opts[:count] || 5
23
+ end
24
+
25
+ def generate_group
26
+ @group = client.groups.create(name: group_name, path: group_path)
27
+ puts "#{@group.name} - #{@group.web_url}"
28
+ raise 'Unable to Create Group' unless @group.success?
29
+ end
30
+
31
+ def generate_projects
32
+ @projects = list.sample(count).map do |name|
33
+ generate_project(name)
34
+ end
35
+ end
36
+
37
+ def generate_project(name)
38
+ @group.project_create(
39
+ name: name,
40
+ description: "#{name} Pages",
41
+ import_url: "https://gitlab.com/pages/#{name}.git"
42
+ )
43
+ end
44
+
45
+ def generate_pipelines
46
+ @projects.each do |project|
47
+ project.pipeline_create(ref: :master)
48
+ end
49
+ end
50
+
51
+ def wait_for_import
52
+ @projects.each(&:wait_for_import)
53
+ end
54
+
55
+ # Execute Template
56
+ def run!
57
+ generate_group
58
+ generate_projects
59
+ wait_for_import
60
+ generate_pipelines
61
+
62
+ @projects.each do |project|
63
+ puts "#{project.name} - #{project.web_url}"
64
+ end
65
+
66
+ {
67
+ group: @group,
68
+ projects: @projects
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,23 @@
1
+ module LabClient
2
+ module Generator
3
+ # Common Helper Class
4
+ class TemplateHelper
5
+ attr_reader :client
6
+ attr_accessor :opts
7
+
8
+ def inspect
9
+ "#<LabClient::Template #{self.class.to_s.demodulize}>"
10
+ end
11
+
12
+ def initialize(client, opts = {})
13
+ @client = client
14
+ self.opts = opts
15
+ setup
16
+ end
17
+
18
+ def setup
19
+ # Blank Place Holder
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,122 @@
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
9
+
10
+ def inspect
11
+ "#<Wizard count=#{count}, random=#{random}, domain=#{domain}>"
12
+ end
13
+
14
+ def initialize(client)
15
+ require 'faker' # Ensure Faker is Available
16
+
17
+ @client = client
18
+ self.random = true # Populate Random or use only Templates
19
+ self.count = default_count
20
+ self.password = SecureRandom.uuid
21
+ self.domain = URI.parse(client.settings[:url]).hostname
22
+ end
23
+
24
+ def template(name, opts = {})
25
+ case name
26
+ when :pages then Pages.new(client, opts)
27
+ end
28
+ end
29
+
30
+ def pages(opts = {})
31
+ Pages.new(client, opts)
32
+ end
33
+
34
+ # Random Counters
35
+ def default_count
36
+ {
37
+ users: 20,
38
+ projects: 5,
39
+ groups: 5,
40
+ issues: 2
41
+ }
42
+ end
43
+
44
+ def generate_users
45
+ @users = @user_names.map do |name|
46
+ username = name.downcase.gsub(/[^0-9A-Za-z]/, '')
47
+ email = "#{username}@#{domain}"
48
+ puts "User -- Name: #{name}, UserName: #{username}, Email: #{email}"
49
+
50
+ client.users.create(
51
+ name: name,
52
+ email: email,
53
+ password: password,
54
+ username: username
55
+ )
56
+ end
57
+ end
58
+
59
+ def generate_groups
60
+ @groups = @group_names.map do |name|
61
+ path = name.downcase.gsub(/[^0-9A-Za-z]/, '')
62
+ puts "Group -- #{name}/#{path}"
63
+ client.groups.create(name: name, path: path)
64
+ end
65
+ end
66
+
67
+ def generate_group_membership
68
+ ## Group Access Level
69
+ @groups.each do |group|
70
+ @users.sample(rand(1..@users.count)).each do |user|
71
+ level = group.valid_group_project_levels.sample
72
+ puts "Group Add: #{group.name}: #{user.name} - #{level}"
73
+ group.member_add(user, access_level: level)
74
+ # :nocov:
75
+ rescue StandardError => e
76
+ puts e.message
77
+ next
78
+ # :nocov:
79
+ end
80
+ end
81
+ end
82
+
83
+ def generate_projects(group)
84
+ # Collect Group Members
85
+ members = group.members
86
+
87
+ # Loop through project names, create project add issues
88
+ @project_names.uniq.map do |project_name|
89
+ puts "Project: #{project_name}"
90
+ project = group.project_create(name: project_name, description: gen_description)
91
+
92
+ rand(count[:issues]).times do
93
+ project.issue_create(generate_issue_data(members.sample))
94
+ end
95
+ end
96
+ end
97
+
98
+ def generate_issue_data(member)
99
+ {
100
+ assignee_id: member.id,
101
+ description: Faker::Hacker.say_something_smart,
102
+ title: Faker::Company.catch_phrase
103
+ }
104
+ end
105
+
106
+ # Execute Generation
107
+ def run!
108
+ # Collect Names
109
+ generate_names
110
+ generate_users
111
+ generate_groups
112
+ generate_group_membership
113
+
114
+ @groups.map do |group|
115
+ generate_projects(group)
116
+ end
117
+
118
+ nil
119
+ end
120
+ end
121
+ end
122
+ end
@@ -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
@@ -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
@@ -87,6 +87,11 @@ module LabClient
87
87
  client.resource_labels.issues.show(project_id, iid, resource_event_id)
88
88
  end
89
89
 
90
+ # Reload Helper
91
+ def reload
92
+ update_self client.issues.show(project_id, iid)
93
+ end
94
+
90
95
  help do
91
96
  subtitle 'Issue'
92
97
  option 'update', 'Update issue (accepts hash).'
@@ -109,6 +114,9 @@ module LabClient
109
114
  # Resource Labels
110
115
  option 'resource_labels', 'List of all label events'
111
116
  option 'resource_label', 'Show single label event [Resource Event ID]'
117
+
118
+ # Reload Helper
119
+ option 'reload', 'Reload this object (New API Call)'
112
120
  end
113
121
  end
114
122
  end
@@ -13,7 +13,8 @@ module LabClient
13
13
 
14
14
  # API Methods here have to be explicitly documented / custom helpers
15
15
  # Assume no methods by default
16
- def help
16
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
17
+ def help(help_filter = nil)
17
18
  docs = LabClient::Docs.docs.dig(group_name, 'Reference')
18
19
  unless docs
19
20
  puts 'No Available Help'
@@ -25,6 +26,10 @@ module LabClient
25
26
  next unless doc[:options]
26
27
 
27
28
  doc[:options].each do |opt|
29
+ if help_filter
30
+ next unless (opt[:name] + opt[:text]).include? help_filter.to_s
31
+ end
32
+
28
33
  puts ' ' + opt[:name]
29
34
  puts " #{opt[:text]}\n"
30
35
  end
@@ -33,6 +38,23 @@ module LabClient
33
38
  # Ignore Output
34
39
  nil
35
40
  end
41
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
42
+
43
+ # Documented API Methods
44
+ def api_methods
45
+ docs = LabClient::Docs.docs.dig(group_name, 'Reference')
46
+
47
+ unless docs
48
+ puts 'No Available Help'
49
+ return false
50
+ end
51
+
52
+ LabClient::Docs.docs.dig(group_name, 'Reference').map do |doc|
53
+ doc[:options].map do |opt|
54
+ opt[:name]
55
+ end
56
+ end.flatten.sort
57
+ end
36
58
 
37
59
  def valid_group_project_levels
38
60
  %i[guest reporter developer maintainer owner]
@@ -85,6 +107,11 @@ module LabClient
85
107
  end
86
108
  end
87
109
 
110
+ # Forward response success
111
+ def success?
112
+ @response.success?
113
+ end
114
+
88
115
  # Formatting Time Helper
89
116
  def format_time?(time)
90
117
  time.respond_to?(:to_time)
@@ -143,6 +143,27 @@ module LabClient
143
143
  DOC
144
144
  end
145
145
 
146
+ doc 'Response' do
147
+ title 'Status'
148
+ desc 'Each object/call will return a "response" object or the instantiated class object. On each of these you can use "success?" to verify the response of a call.'
149
+
150
+ result <<~DOC
151
+ project = client.projects.show 123123
152
+ # => #<TyphoeusResponse code: 404>
153
+ project.success?
154
+ # => false
155
+
156
+ user = client.users.show 1
157
+ => #<User id: 1, username: root>
158
+ user.success?
159
+ => true
160
+ DOC
161
+
162
+ result <<~DOC
163
+ curl -k -H "Private-Token: super_secret_token" -H "Accept: application/json" "https://labclient/api/v4/users?"
164
+ DOC
165
+ end
166
+
146
167
  doc 'Other' do
147
168
  title 'Common Helpers'
148
169
  markdown <<~DOC
@@ -191,6 +212,20 @@ module LabClient
191
212
  DOC
192
213
  end
193
214
 
215
+ doc 'Other' do
216
+ desc 'Object Help'
217
+
218
+ result <<~DOC
219
+ project = client.projects.show(5)
220
+
221
+ # List Possible Methods
222
+ project.help
223
+
224
+ # Array result of methods
225
+ project.api_methods
226
+ DOC
227
+ end
228
+
194
229
  doc 'Other' do
195
230
  title 'Object IDs'
196
231
 
@@ -111,5 +111,10 @@ module LabClient
111
111
  process_entry(entry, @response)
112
112
  end
113
113
  end
114
+
115
+ # Forward response success
116
+ def success?
117
+ @response.success?
118
+ end
114
119
  end
115
120
  end
@@ -681,6 +681,30 @@ module LabClient
681
681
  def clusters
682
682
  client.projects.clusters.list(id)
683
683
  end
684
+
685
+ # Reload
686
+ def reload
687
+ update_self client.projects.show(id)
688
+ end
689
+
690
+ # Wait for Import / Set a Hard Limit
691
+ def wait_for_import(total_time = 300, sleep_time = 15)
692
+ # none
693
+ # scheduled
694
+ # failed
695
+ # started
696
+ # finished
697
+
698
+ Timeout.timeout(total_time) do
699
+ loop do
700
+ reload
701
+ break if %w[none finished].include? import_status
702
+ raise "Import Failed: #{import_error}" if import_status == 'failed'
703
+
704
+ sleep sleep_time
705
+ end
706
+ end
707
+ end
684
708
  end
685
709
  # rubocop:enable Metrics/ModuleLength
686
710
  end
@@ -8,6 +8,9 @@ module LabClient
8
8
  option 'archive', 'Archive this project'
9
9
  option 'delete', 'Schedule/Delete this project'
10
10
  option 'events', "List this project's events"
11
+ option 'reload', 'Reload this project object (New API Call)'
12
+ option 'wait_for_import', 'Looping, wait for project import [Timeout, Interval]'
13
+
11
14
  option 'fork_existing', 'Create Fork Relationship [Target/Source Project]'
12
15
  option 'fork_remove', 'Remove Fork Relationshgip'
13
16
  option 'fork', 'Fork this project, accepts hash, [namespace, path, name]'
@@ -105,6 +105,11 @@ module LabClient
105
105
  client.users.memberships(id, type)
106
106
  end
107
107
 
108
+ # Reload Helper
109
+ def reload
110
+ update_self client.users.show(id)
111
+ end
112
+
108
113
  help do
109
114
  # @group_name = 'Users'
110
115
  subtitle 'User'
@@ -133,6 +138,7 @@ module LabClient
133
138
  option 'impersonation_token_revoke', 'Revoke impersonation tokesn [Token ID]'
134
139
  option 'impersonation_token', 'Show impersonation tokesn [Token ID]'
135
140
  option 'memberships', 'Lists all projects and groups a user is a member of [String/Type]'
141
+ option 'reload', 'Reload this object (New API Call)'
136
142
  end
137
143
  end
138
144
  end
@@ -1,3 +1,3 @@
1
1
  module LabClient
2
- VERSION = '0.1.1'.freeze
2
+ VERSION = '0.1.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: labclient
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davin Walker
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-04 00:00:00.000000000 Z
11
+ date: 2020-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.16'
111
+ - !ruby/object:Gem::Dependency
112
+ name: faker
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.12'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.12'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: minitest
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -387,6 +401,11 @@ files:
387
401
  - lib/labclient/files/delete.rb
388
402
  - lib/labclient/files/show.rb
389
403
  - lib/labclient/files/update.rb
404
+ - lib/labclient/generator/generator.rb
405
+ - lib/labclient/generator/names.rb
406
+ - lib/labclient/generator/templates/pages.rb
407
+ - lib/labclient/generator/templates/template.rb
408
+ - lib/labclient/generator/wizard.rb
390
409
  - lib/labclient/groups/access_requests/access_request.rb
391
410
  - lib/labclient/groups/access_requests/approve.rb
392
411
  - lib/labclient/groups/access_requests/client.rb
@@ -859,7 +878,7 @@ homepage: https://gitlab.com/labclient/labclient
859
878
  licenses:
860
879
  - MIT
861
880
  metadata: {}
862
- post_install_message:
881
+ post_install_message:
863
882
  rdoc_options: []
864
883
  require_paths:
865
884
  - lib
@@ -875,7 +894,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
875
894
  version: '0'
876
895
  requirements: []
877
896
  rubygems_version: 3.0.3
878
- signing_key:
897
+ signing_key:
879
898
  specification_version: 4
880
899
  summary: Gitlab API Client
881
900
  test_files: []