gitlab 4.13.1 → 4.16.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2504adea709074810ff6508709ad14415fe1084dee353f3bd2ca53757220ba8
4
- data.tar.gz: 2783c2afff1b5aa5898d1be19e29124ea1cddcf79fedbaae003c9066cb97116e
3
+ metadata.gz: 797a89bf7bdc146d8381fcf6a6bada7909b70d694f5b9b5c4a7781c69396a6d7
4
+ data.tar.gz: d564a8c8d0840f7ed4517f39d17b8a9a8138079b1fbbc7b9576de4b7159626e0
5
5
  SHA512:
6
- metadata.gz: 415a2de181363d3a0612c78a94dfa7c13f3c812f6a1a214ab910cfc92927ba414eabeba07b52bb7469c67cd91f03bc42422a676c7026bbfd414c250377d04ce0
7
- data.tar.gz: abe3f75d8d8bd649a10004de7ba09179b0e135c4b604bf32c237d53a60516566778e95e4ee7f2368f5fe8bbf077df15cc93426b7a77582985fa243d039dd1d1a
6
+ metadata.gz: abb59a55e8a113155818e1531bb4c22578b27a520ac1bea7d9f932a49c8d7be8c0ee4d3e3f42cc5ee870a143553aae3192dc693c7ad8c74b2d7079c6c85cb94e
7
+ data.tar.gz: c48dc657cf576f747c8a1153114b72681a4c6a5285259a7ef0534a8afdd85c67907dca98c63c1d6450d7766c9692879365b0411985574a570ce209b533a90a91
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2019 Nihad Abbasov <nihad@42na.in>
1
+ Copyright (c) 2012-2020 Nihad Abbasov <nihad@42na.in>
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Gitlab
2
2
 
3
- [![Build Status](https://img.shields.io/travis/NARKOZ/gitlab.svg)](https://travis-ci.org/NARKOZ/gitlab)
4
- [![Maintainability](https://api.codeclimate.com/v1/badges/2e310b334b1b5db4a7e1/maintainability)](https://codeclimate.com/github/NARKOZ/gitlab)
3
+ [![Build Status](https://img.shields.io/github/workflow/status/NARKOZ/gitlab/CI/master)](https://github.com/NARKOZ/gitlab/actions?query=workflow%3ARuby)
5
4
  [![Inline docs](https://inch-ci.org/github/NARKOZ/gitlab.svg)](https://inch-ci.org/github/NARKOZ/gitlab)
6
5
  [![Gem version](https://img.shields.io/gem/v/gitlab.svg)](https://rubygems.org/gems/gitlab)
7
6
  [![License](https://img.shields.io/badge/license-BSD-red.svg)](https://github.com/NARKOZ/gitlab/blob/master/LICENSE.txt)
@@ -42,7 +42,8 @@ module Gitlab
42
42
  #
43
43
  # @return [Array<Symbol>]
44
44
  def self.actions
45
- hidden = /endpoint|private_token|auth_token|user_agent|sudo|get|post|put|\Adelete\z|validate|request_defaults|httparty/
45
+ hidden =
46
+ /endpoint|private_token|auth_token|user_agent|sudo|get|post|put|\Adelete\z|validate\z|request_defaults|httparty/
46
47
  (Gitlab::Client.instance_methods - Object.methods).reject { |e| e[hidden] }
47
48
  end
48
49
  end
@@ -206,14 +206,10 @@ class Gitlab::CLI
206
206
 
207
207
  # Helper function to call Gitlab commands with args.
208
208
  def gitlab_helper(cmd, args = [])
209
- begin
210
- data = args.any? ? Gitlab.send(cmd, *args) : Gitlab.send(cmd)
211
- rescue StandardError => e
212
- puts e.message
213
- yield if block_given?
214
- end
215
-
216
- data
209
+ args.any? ? Gitlab.send(cmd, *args) : Gitlab.send(cmd)
210
+ rescue StandardError => e
211
+ puts e.message
212
+ yield if block_given?
217
213
  end
218
214
 
219
215
  # Convert a hash (recursively) to use symbol hash keys
@@ -221,11 +217,9 @@ class Gitlab::CLI
221
217
  def symbolize_keys(hash)
222
218
  if hash.is_a?(Hash)
223
219
  hash = hash.each_with_object({}) do |(key, value), new_hash|
224
- begin
225
- new_hash[key.to_sym] = symbolize_keys(value)
226
- rescue NoMethodError
227
- raise "Error: cannot convert hash key to symbol: #{key}"
228
- end
220
+ new_hash[key.to_sym] = symbolize_keys(value)
221
+ rescue NoMethodError
222
+ raise "Error: cannot convert hash key to symbol: #{key}"
229
223
  end
230
224
  end
231
225
 
@@ -19,6 +19,7 @@ module Gitlab
19
19
  include ContainerRegistry
20
20
  include Deployments
21
21
  include Environments
22
+ include EpicIssues
22
23
  include Epics
23
24
  include Events
24
25
  include Features
@@ -61,6 +62,7 @@ module Gitlab
61
62
  include Templates
62
63
  include Todos
63
64
  include Users
65
+ include UserSnippets
64
66
  include Versions
65
67
  include Wikis
66
68
 
@@ -73,8 +75,12 @@ module Gitlab
73
75
  inspected
74
76
  end
75
77
 
78
+ # Utility method for URL encoding of a string.
79
+ # Copied from https://ruby-doc.org/stdlib-2.7.0/libdoc/erb/rdoc/ERB/Util.html
80
+ #
81
+ # @return [String]
76
82
  def url_encode(url)
77
- URI.encode(url.to_s, /\W/)
83
+ url.to_s.b.gsub(/[^a-zA-Z0-9_\-.~]/n) { |m| sprintf('%%%02X', m.unpack1('C')) } # rubocop:disable Style/FormatString, Style/FormatStringToken
78
84
  end
79
85
 
80
86
  private
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Gitlab::Client
4
+ # Defines methods related to issues.
5
+ # @see https://docs.gitlab.com/ee/api/epic_issues.html
6
+ module EpicIssues
7
+ # List issues for an epic.
8
+ # Gets all issues that are assigned to an epic and the authenticated user has access to..
9
+ # @example
10
+ # Gitlab.epic_issues(5, 7)
11
+ # Gitlab.epic_issues(5, 7, { per_page: 40 })
12
+ #
13
+ # @param [Integer, String] group The ID or name of a group.
14
+ # @param [Integer] epic The iid of an epic.
15
+ # @param [Hash] options A customizable set of options.
16
+ # @option options [Integer] :page The page number.
17
+ # @option options [Integer] :per_page The number of results per page.
18
+ # @return [Array<Gitlab::ObjectifiedHash>]
19
+ def epic_issues(group, epic, options = {})
20
+ get("/groups/#{url_encode group}/epics/#{epic}/issues", query: options)
21
+ end
22
+ end
23
+ end
@@ -181,7 +181,7 @@ class Gitlab::Client
181
181
  # @param [Integer] id The ID of an issue.
182
182
  # @param [String] duration The time spent in human format. e.g: 3h30m
183
183
  def add_time_spent_on_issue(project, id, duration)
184
- post("/projects/#{url_encode project}/issues/#{id}/add_spent_time", body: { duration: url_encode(duration) })
184
+ post("/projects/#{url_encode project}/issues/#{id}/add_spent_time", body: { duration: duration })
185
185
  end
186
186
 
187
187
  # Resets the total spent time for this issue to 0 seconds.
@@ -163,5 +163,19 @@ class Gitlab::Client
163
163
  def job_artifacts_keep(project_id, job_id)
164
164
  post("/projects/#{url_encode project_id}/jobs/#{job_id}/artifacts/keep")
165
165
  end
166
+
167
+ # Delete Artifacts
168
+ # Deletes the artifacts associated with a job.
169
+ #
170
+ # @example
171
+ # Gitlab.job_artifacts_delete(1,1)
172
+ # Gitlab.job_artifacts_delete("project", 1)
173
+ #
174
+ # @param [Integer, String] The ID or name of a project.
175
+ # @param [Integer] the id of the job
176
+ # @return [Array<Gitlab::ObjectifiedHash>]
177
+ def job_artifacts_delete(project_id, job_id)
178
+ delete("/projects/#{url_encode project_id}/jobs/#{job_id}/artifacts")
179
+ end
166
180
  end
167
181
  end
@@ -31,6 +31,62 @@ class Gitlab::Client
31
31
  post("/projects/#{url_encode project}/approvals", body: options)
32
32
  end
33
33
 
34
+ # Gets MR Approval Rules for a project
35
+ #
36
+ # @example
37
+ # Gitlab.project_merge_request_approval_rules(1)
38
+ #
39
+ # @param [Integer] project The ID of a project.
40
+ # @return [Gitlab::ObjectifiedHash] MR approval rules for the project
41
+ def project_merge_request_approval_rules(project)
42
+ get("/projects/#{url_encode project}/approval_rules")
43
+ end
44
+
45
+ # Create MR Approval Rule for a project
46
+ #
47
+ # @example
48
+ # Gitlab.create_project_merge_request_approval_rule(1, {name: "security", approvals_required: 1})
49
+ #
50
+ # @param [Integer] project(required) The ID of a project.
51
+ # @option options [String] :name(required) The name of the approval rule
52
+ # @option options [Integer] :approvals_required(required) The number of required approvals for this rule
53
+ # @option options [Array] :user_ids(optional) The ids of users as approvers
54
+ # @option options [Array] :group_ids(optional) The ids of groups as approvers
55
+ # @option options [Array] :protected_branch_ids(optional) The ids of protected branches to scope the rule by
56
+ # @return [Gitlab::ObjectifiedHash] New MR approval rule
57
+ def create_project_merge_request_approval_rule(project, options = {})
58
+ post("/projects/#{url_encode project}/approval_rules", body: options)
59
+ end
60
+
61
+ # Update MR Approval Rule for a project
62
+ #
63
+ # @example
64
+ # Gitlab.update_project_merge_request_approval_rule(1, {name: "security", approvals_required: 2})
65
+ #
66
+ # @param [Integer] project(required) The ID of a project.
67
+ # @param [Integer] approval_rule_id(required) The ID of a project Approval Rule
68
+ # @option options [String] :name(required) The name of the approval rule
69
+ # @option options [Integer] :approvals_required(required) The number of required approvals for this rule
70
+ # @option options [Array] :user_ids(optional) The ids of users as approvers
71
+ # @option options [Array] :group_ids(optional) The ids of groups as approvers
72
+ # @option options [Array] :protected_branch_ids(optional) The ids of protected branches to scope the rule by
73
+ # @return [Gitlab::ObjectifiedHash] Updated MR approval rule
74
+ def update_project_merge_request_approval_rule(project, approval_rule_id, options = {})
75
+ put("/projects/#{url_encode project}/approval_rules/#{approval_rule_id}", body: options)
76
+ end
77
+
78
+ # Delete MR Approval Rule for a project
79
+ #
80
+ # @example
81
+ # Gitlab.delete_project_merge_request_approval_rule(1, 1)
82
+ #
83
+ # @param [Integer] project(required) The ID of a project.
84
+ # @param [Integer] approval_rule_id(required) The ID of a approval rule
85
+ # @return [void] This API call returns an empty response body
86
+ def delete_project_merge_request_approval_rule(project, approval_rule_id)
87
+ delete("/projects/#{url_encode project}/approval_rules/#{approval_rule_id}")
88
+ end
89
+
34
90
  # Change allowed approvers and approver groups for a project
35
91
  #
36
92
  # @example
@@ -109,5 +165,17 @@ class Gitlab::Client
109
165
  def unapprove_merge_request(project, merge_request, options = {})
110
166
  post("/projects/#{url_encode project}/merge_requests/#{merge_request}/unapprove", body: options)
111
167
  end
168
+
169
+ # Get the approval state of merge requests
170
+ #
171
+ # @example
172
+ # Gitlab.merge_request_approval_state(5, 36)
173
+ #
174
+ # @param [Integer, String] project The ID or name of a project.
175
+ # @param [Integer] id The ID of a merge request.
176
+ # @return [Array<Gitlab::ObjectifiedHash>]
177
+ def merge_request_approval_state(project, id)
178
+ get("/projects/#{url_encode project}/merge_requests/#{id}/approval_state")
179
+ end
112
180
  end
113
181
  end
@@ -35,12 +35,16 @@ class Gitlab::Client
35
35
  #
36
36
  # @example
37
37
  # Gitlab.merge_request(5, 36)
38
+ # Gitlab.merge_request(5, 36, { include_diverged_commits_count: true })
38
39
  #
39
40
  # @param [Integer, String] project The ID or name of a project.
40
41
  # @param [Integer] id The ID of a merge request.
42
+ # @option options [Boolean] :render_html If true response includes rendered HTML for title and description.
43
+ # @option options [Boolean] :include_diverged_commits_count If true response includes the commits behind the target branch.
44
+ # @option options [Boolean] :include_rebase_in_progress If true response includes whether a rebase operation is in progress.
41
45
  # @return <Gitlab::ObjectifiedHash]
42
- def merge_request(project, id)
43
- get("/projects/#{url_encode project}/merge_requests/#{id}")
46
+ def merge_request(project, id, options = {})
47
+ get("/projects/#{url_encode project}/merge_requests/#{id}", query: options)
44
48
  end
45
49
 
46
50
  # Gets a list of merge request pipelines.
@@ -81,8 +85,14 @@ class Gitlab::Client
81
85
  # @option options [String] :source_branch (required) The source branch name.
82
86
  # @option options [String] :target_branch (required) The target branch name.
83
87
  # @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request.
88
+ # @option options [Array<Integer>] :assignee_ids (optional) The ID of the user(s) to assign the MR to. Set to 0 or provide an empty value to unassign all assignees.
89
+ # @option options [String] :description (optional) Description of MR. Limited to 1,048,576 characters.
84
90
  # @option options [Integer] :target_project_id (optional) The target project ID.
85
91
  # @option options [String] :labels (optional) Labels as a comma-separated list.
92
+ # @option options [Integer] :milestone_id (optional) The global ID of a milestone
93
+ # @option options [Boolean] :remove_source_branch (optional) Flag indicating if a merge request should remove the source branch when merging
94
+ # @option options [Boolean] :allow_collaboration (optional) Allow commits from members who can merge to the target branch
95
+ # @option options [Boolean] :squash (optional) Squash commits into a single commit when merging
86
96
  # @return [Gitlab::ObjectifiedHash] Information about created merge request.
87
97
  def create_merge_request(project, title, options = {})
88
98
  body = { title: title }.merge(options)
@@ -115,7 +125,12 @@ class Gitlab::Client
115
125
  # @param [Integer, String] project The ID or name of a project.
116
126
  # @param [Integer] id The ID of a merge request.
117
127
  # @param [Hash] options A customizable set of options.
118
- # @option options [String] :merge_commit_message Custom merge commit message
128
+ # @option options [String] :merge_commit_message(optional) Custom merge commit message
129
+ # @option options [String] :squash_commit_message(optional) Custom squash commit message
130
+ # @option options [Boolean] :squash(optional) if true the commits will be squashed into a single commit on merge
131
+ # @option options [Boolean] :should_remove_source_branch(optional) if true removes the source branch
132
+ # @option options [Boolean] :merge_when_pipeline_succeeds(optional) if true the MR is merged when the pipeline succeeds
133
+ # @option options [String] :sha(optional) if present, then this SHA must match the HEAD of the source branch, otherwise the merge will fail
119
134
  # @return [Gitlab::ObjectifiedHash] Information about updated merge request.
120
135
  def accept_merge_request(project, id, options = {})
121
136
  put("/projects/#{url_encode project}/merge_requests/#{id}/merge", body: options)
@@ -60,6 +60,20 @@ class Gitlab::Client
60
60
  end
61
61
  alias merge_request_comments merge_request_notes
62
62
 
63
+ # Gets a list of notes for an epic.
64
+ #
65
+ # @example
66
+ # Gitlab.epic_notes(5, 10)
67
+ #
68
+ # @param [Integer] project The ID of a group.
69
+ # @param [Integer] epic The ID of an epic.
70
+ # @option options [Integer] :page The page number.
71
+ # @option options [Integer] :per_page The number of results per page.
72
+ # @return [Array<Gitlab::ObjectifiedHash>]
73
+ def epic_notes(group, epic, options = {})
74
+ get("/groups/#{url_encode group}/epics/#{epic}/notes", query: options)
75
+ end
76
+
63
77
  # Gets a single wall note.
64
78
  #
65
79
  # @example
@@ -162,6 +176,19 @@ class Gitlab::Client
162
176
  end
163
177
  alias create_merge_request_comment create_merge_request_note
164
178
 
179
+ # Creates a new epic note.
180
+ #
181
+ # @example
182
+ # Gitlab.create_epic_note(6, 1, 'Adding a note to my epic.')
183
+ #
184
+ # @param [Integer, String] group The ID or name of a group.
185
+ # @param [Integer] epic The ID of an epic.
186
+ # @param [String] body The body of a note.
187
+ # @return [Gitlab::ObjectifiedHash] Information about created note.
188
+ def create_epic_note(group, epic, body)
189
+ post("/groups/#{url_encode group}/epics/#{epic}/notes", body: { body: body })
190
+ end
191
+
165
192
  # Deletes a wall note.
166
193
  #
167
194
  # @example
@@ -380,6 +380,20 @@ class Gitlab::Client
380
380
  post("/projects/#{url_encode project}/deploy_keys/#{key}/disable", body: { id: project, key_id: key })
381
381
  end
382
382
 
383
+ # Updates an existing deploy key.
384
+ #
385
+ # @example
386
+ # Gitlab.edit_deploy_key(42, 66, 'New key name', can_push: false)
387
+ #
388
+ # @param [Integer, String] project The ID or path of a project.
389
+ # @param [Integer] id The ID of a deploy key.
390
+ # @param [String] title The title of a deploy key.
391
+ # @param [Hash] options A customizable set of options.
392
+ # @return [Gitlab::ObjectifiedHash] Information about created deploy key.
393
+ def edit_deploy_key(project, id, title, options = {})
394
+ put("/projects/#{url_encode project}/deploy_keys/#{id}", body: { title: title }.merge(options))
395
+ end
396
+
383
397
  # Deletes a deploy key from project.
384
398
  #
385
399
  # @example
@@ -72,5 +72,21 @@ class Gitlab::Client
72
72
  def merge_base(project, refs)
73
73
  get("/projects/#{url_encode project}/repository/merge_base", query: { refs: refs })
74
74
  end
75
+
76
+ # Get project repository contributors.
77
+ #
78
+ # @example
79
+ # Gitlab.contributors(42)
80
+ # Gitlab.contributors(42, { order: 'name' })
81
+ #
82
+ # @param [Integer, String] project The ID or name of a project.
83
+ # @param [Hash] options A customizable set of options.
84
+ # @option options [String] :order_by Order by name, email or commits (default = commits).
85
+ # @option options [String] :sort Sort order asc or desc (default = asc).
86
+ # @return [Array<Gitlab::ObjectifiedHash>]
87
+ def contributors(project, options = {})
88
+ get("/projects/#{url_encode project}/repository/contributors", query: options)
89
+ end
90
+ alias repo_contributors contributors
75
91
  end
76
92
  end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Gitlab::Client
4
+ # Defines methods related to user snippets.
5
+ # @see https://docs.gitlab.com/ce/api/snippets.html
6
+ module UserSnippets
7
+ # Get a list of the snippets of the current user.
8
+ #
9
+ # @example
10
+ # Gitlab.user_snippets
11
+ #
12
+ # @return [Array<Gitlab::ObjectifiedHash>] List of snippets of current user
13
+ def user_snippets
14
+ get('/snippets')
15
+ end
16
+
17
+ # Get a single snippet.
18
+ #
19
+ # @example
20
+ # Gitlab.user_snippet(1)
21
+ #
22
+ # @param [Integer] id ID of snippet to retrieve.
23
+ # @return [Gitlab::ObjectifiedHash] Information about the user snippet
24
+ def user_snippet(id)
25
+ get("/snippets/#{id}")
26
+ end
27
+
28
+ # Get raw contents of a single snippet.
29
+ #
30
+ # @example
31
+ # Gitlab.user_snippet_raw(1)
32
+ #
33
+ # @param [Integer] id ID of snippet to retrieve.
34
+ # @return [String] User snippet text
35
+ def user_snippet_raw(id)
36
+ get("/snippets/#{id}/raw",
37
+ format: nil,
38
+ headers: { Accept: 'text/plain' },
39
+ parser: ::Gitlab::Request::Parser)
40
+ end
41
+
42
+ # Create a new snippet.
43
+ #
44
+ # @example
45
+ # Gitlab.create_user_snippet({ title: 'REST', file_name: 'api.rb', content: 'some code', description: 'Hello World snippet', visibility: 'public'})
46
+ #
47
+ # @param [Hash] options A customizable set of options.
48
+ # @option options [String] :title (required) Title of a snippet.
49
+ # @option options [String] :file_name (required) Name of a snippet file.
50
+ # @option options [String] :content (required) Content of a snippet.
51
+ # @option options [String] :description (optional) Description of a snippet.
52
+ # @option options [String] :visibility (optional) visibility of a snippet.
53
+ # @return [Gitlab::ObjectifiedHash] Information about created snippet.
54
+ def create_user_snippet(options = {})
55
+ post('/snippets', body: options)
56
+ end
57
+
58
+ # Update an existing snippet.
59
+ #
60
+ # @example
61
+ # Gitlab.edit_user_snippet(34, { file_name: 'README.txt' })
62
+ # Gitlab.edit_user_snippet(34, { file_name: 'README.txt', title: 'New title' })
63
+ #
64
+ # @param [Integer] id ID of snippet to update.
65
+ # @param [Hash] options A customizable set of options.
66
+ # @option options [String] :title (optional) Title of a snippet.
67
+ # @option options [String] :file_name (optional) Name of a snippet file.
68
+ # @option options [String] :content (optional) Content of a snippet.
69
+ # @option options [String] :description (optional) Description of a snippet.
70
+ # @option options [String] :visibility (optional) visibility of a snippet.
71
+ # @return [Gitlab::ObjectifiedHash] Information about updated snippet.
72
+ def edit_user_snippet(id, options = {})
73
+ put("/snippets/#{id}", body: options)
74
+ end
75
+
76
+ # Delete an existing snippet.
77
+ #
78
+ # @example
79
+ # Gitlab.delete_user_snippet(14)
80
+ #
81
+ # @param [Integer] id ID of snippet to delete.
82
+ # @return [void] This API call returns an empty response body.
83
+ def delete_user_snippet(id)
84
+ delete("/snippets/#{id}")
85
+ end
86
+
87
+ # List all public snippets.
88
+ #
89
+ # @example
90
+ # Gitlab.public_snippets
91
+ # Gitlab.public_snippets(per_page: 2, page: 1)
92
+ #
93
+ # @param [Hash] options A customizable set of options.
94
+ # @option options [String] :per_page (optional) Number of snippets to return per page.
95
+ # @option options [String] :page (optional) Page to retrieve.
96
+ #
97
+ # @return [Array<Gitlab::ObjectifiedHash>] List of all public snippets
98
+ def public_snippets(options = {})
99
+ get('/snippets/public', query: options)
100
+ end
101
+
102
+ # Get user agent details for a snippet.
103
+ #
104
+ # @example
105
+ # Gitlab.snippet_user_agent_details(1)
106
+ #
107
+ # @param [Integer] id ID of snippet to delete.
108
+ #
109
+ # @return [Array<Gitlab::ObjectifiedHash>] Details of the user agent
110
+ def snippet_user_agent_details(id)
111
+ get("/snippets/#{id}/user_agent_detail")
112
+ end
113
+ end
114
+ end
@@ -123,6 +123,20 @@ class Gitlab::Client
123
123
  post('/session', body: { email: email, password: password }, unauthenticated: true)
124
124
  end
125
125
 
126
+ # Gets a list of user activities (for admin access only).
127
+ #
128
+ # @example
129
+ # Gitlab.activities
130
+ #
131
+ # @param [Hash] options A customizable set of options.
132
+ # @option options [Integer] :page The page number.
133
+ # @option options [Integer] :per_page The number of results per page.
134
+ # @option options [String] :from The start date for paginated results.
135
+ # @return [Array<Gitlab::ObjectifiedHash>]
136
+ def activities(options = {})
137
+ get('/user/activities', query: options)
138
+ end
139
+
126
140
  # Gets a list of user's SSH keys.
127
141
  #
128
142
  # @example
@@ -225,10 +239,15 @@ class Gitlab::Client
225
239
  #
226
240
  # @param [String] email Email address
227
241
  # @param [Integer] user_id The ID of a user.
242
+ # @param [Boolean] skip_confirmation Skip confirmation and assume e-mail is verified
228
243
  # @return [Gitlab::ObjectifiedHash]
229
- def add_email(email, user_id = nil)
244
+ def add_email(email, user_id = nil, skip_confirmation = nil)
230
245
  url = user_id.to_i.zero? ? '/user/emails' : "/users/#{user_id}/emails"
231
- post(url, body: { email: email })
246
+ if skip_confirmation.nil?
247
+ post(url, body: { email: email })
248
+ else
249
+ post(url, body: { email: email, skip_confirmation: skip_confirmation })
250
+ end
232
251
  end
233
252
 
234
253
  # Delete email
@@ -63,6 +63,14 @@ module Gitlab
63
63
  else
64
64
  @response.parsed_response
65
65
  end
66
+ rescue Gitlab::Error::Parsing
67
+ # Return stringified response when receiving a
68
+ # parsing error to avoid obfuscation of the
69
+ # api error.
70
+ #
71
+ # note: The Gitlab API does not always return valid
72
+ # JSON when there are errors.
73
+ @response.to_s
66
74
  end
67
75
 
68
76
  # Handle error response message in case of nested hashes
@@ -80,14 +80,15 @@ module Gitlab::Help
80
80
 
81
81
  # Massage output from 'ri'.
82
82
  def change_help_output!(cmd, output_str)
83
+ output_str = +output_str
83
84
  output_str.gsub!(/#{cmd}\((.*?)\)/m, cmd + ' \1')
84
- output_str.gsub!(/\,[\s]*/, ' ')
85
+ output_str.gsub!(/,\s*/, ' ')
85
86
 
86
87
  # Ensure @option descriptions are on a single line
87
88
  output_str.gsub!(/\n\[/, " \[")
88
89
  output_str.gsub!(/\s(@)/, "\n@")
89
- output_str.gsub!(/(\])\n(\:)/, '\1 \2')
90
- output_str.gsub!(/(\:.*)(\n)(.*\.)/, '\1 \3')
90
+ output_str.gsub!(/(\])\n(:)/, '\1 \2')
91
+ output_str.gsub!(/(:.*)(\n)(.*\.)/, '\1 \3')
91
92
  output_str.gsub!(/\{(.+)\}/, '"{\1}"')
92
93
  end
93
94
  end
@@ -7,29 +7,45 @@ module Gitlab
7
7
  def initialize(hash)
8
8
  @hash = hash
9
9
  @data = hash.each_with_object({}) do |(key, value), data|
10
- value = ObjectifiedHash.new(value) if value.is_a? Hash
10
+ value = self.class.new(value) if value.is_a? Hash
11
+ value = value.map { |v| v.is_a?(Hash) ? self.class.new(v) : v } if value.is_a? Array
11
12
  data[key.to_s] = value
12
13
  end
13
14
  end
14
15
 
15
16
  # @return [Hash] The original hash.
16
17
  def to_hash
17
- @hash
18
+ hash
18
19
  end
19
20
  alias to_h to_hash
20
21
 
21
22
  # @return [String] Formatted string with the class name, object id and original hash.
22
23
  def inspect
23
- "#<#{self.class}:#{object_id} {hash: #{@hash.inspect}}"
24
+ "#<#{self.class}:#{object_id} {hash: #{hash.inspect}}"
24
25
  end
25
26
 
26
- # Delegate to ObjectifiedHash.
27
- def method_missing(key)
28
- @data.key?(key.to_s) ? @data[key.to_s] : super
27
+ def [](key)
28
+ data[key]
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :hash, :data
34
+
35
+ # Respond to messages for which `self.data` has a key
36
+ def method_missing(method_name, *args, &block)
37
+ if data.key?(method_name.to_s)
38
+ data[method_name.to_s]
39
+ elsif data.respond_to?(method_name)
40
+ warn 'WARNING: Please convert ObjectifiedHash object to hash before calling Hash methods on it.'
41
+ data.send(method_name, *args, &block)
42
+ else
43
+ super
44
+ end
29
45
  end
30
46
 
31
47
  def respond_to_missing?(method_name, include_private = false)
32
- @hash.keys.map(&:to_sym).include?(method_name.to_sym) || super
48
+ hash.keys.map(&:to_sym).include?(method_name.to_sym) || super
33
49
  end
34
50
  end
35
51
  end
@@ -7,7 +7,7 @@ module Gitlab
7
7
  class PageLinks
8
8
  HEADER_LINK = 'Link'
9
9
  DELIM_LINKS = ','
10
- LINK_REGEX = /<([^>]+)>; rel=\"([^\"]+)\"/.freeze
10
+ LINK_REGEX = /<([^>]+)>; rel="([^"]+)"/.freeze
11
11
  METAS = %w[last next first prev].freeze
12
12
 
13
13
  attr_accessor(*METAS)
@@ -42,37 +42,20 @@ module Gitlab
42
42
  end
43
43
  end
44
44
 
45
- def auto_paginate
46
- response = block_given? ? nil : []
47
- each_page do |page|
48
- if block_given?
49
- page.each do |item|
50
- yield item
51
- end
52
- else
53
- response += page
54
- end
55
- end
56
- response
57
- end
58
-
59
- def paginate_with_limit(limit)
60
- response = block_given? ? nil : []
61
- count = 0
62
- each_page do |page|
63
- if block_given?
64
- page.each do |item|
65
- yield item
66
- count += 1
67
- break if count >= limit
68
- end
69
- else
70
- response += page[0, limit - count]
71
- count = response.length
72
- end
73
- break if count >= limit
74
- end
75
- response
45
+ def lazy_paginate
46
+ to_enum(:each_page).lazy.flat_map(&:to_ary)
47
+ end
48
+
49
+ def auto_paginate(&block)
50
+ return lazy_paginate.to_a unless block_given?
51
+
52
+ lazy_paginate.each(&block)
53
+ end
54
+
55
+ def paginate_with_limit(limit, &block)
56
+ return lazy_paginate.take(limit).to_a unless block_given?
57
+
58
+ lazy_paginate.take(limit).each(&block)
76
59
  end
77
60
 
78
61
  def last_page?
@@ -83,8 +66,7 @@ module Gitlab
83
66
  def last_page
84
67
  return nil if @client.nil? || !has_last_page?
85
68
 
86
- path = @links.last.sub(/#{@client.endpoint}/, '')
87
- @client.get(path)
69
+ @client.get(client_relative_path(@links.last))
88
70
  end
89
71
 
90
72
  def first_page?
@@ -95,8 +77,7 @@ module Gitlab
95
77
  def first_page
96
78
  return nil if @client.nil? || !has_first_page?
97
79
 
98
- path = @links.first.sub(/#{@client.endpoint}/, '')
99
- @client.get(path)
80
+ @client.get(client_relative_path(@links.first))
100
81
  end
101
82
 
102
83
  def next_page?
@@ -107,8 +88,7 @@ module Gitlab
107
88
  def next_page
108
89
  return nil if @client.nil? || !has_next_page?
109
90
 
110
- path = @links.next.sub(/#{@client.endpoint}/, '')
111
- @client.get(path)
91
+ @client.get(client_relative_path(@links.next))
112
92
  end
113
93
 
114
94
  def prev_page?
@@ -119,8 +99,12 @@ module Gitlab
119
99
  def prev_page
120
100
  return nil if @client.nil? || !has_prev_page?
121
101
 
122
- path = @links.prev.sub(/#{@client.endpoint}/, '')
123
- @client.get(path)
102
+ @client.get(client_relative_path(@links.prev))
103
+ end
104
+
105
+ def client_relative_path(link)
106
+ client_endpoint_path = URI.parse(@client.endpoint).request_uri # api/v4
107
+ URI.parse(link).request_uri.sub(client_endpoint_path, '')
124
108
  end
125
109
  end
126
110
  end
@@ -41,14 +41,16 @@ module Gitlab
41
41
 
42
42
  %w[get post put delete].each do |method|
43
43
  define_method method do |path, options = {}|
44
- httparty_config(options)
44
+ params = options.dup
45
45
 
46
- unless options[:unauthenticated]
47
- options[:headers] ||= {}
48
- options[:headers].merge!(authorization_header)
46
+ httparty_config(params)
47
+
48
+ unless params[:unauthenticated]
49
+ params[:headers] ||= {}
50
+ params[:headers].merge!(authorization_header)
49
51
  end
50
52
 
51
- validate self.class.send(method, @endpoint + path, options)
53
+ validate self.class.send(method, @endpoint + path, params)
52
54
  end
53
55
  end
54
56
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gitlab
4
- VERSION = '4.13.1'
4
+ VERSION = '4.16.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.13.1
4
+ version: 4.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nihad Abbasov
@@ -9,28 +9,28 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-12-19 00:00:00.000000000 Z
12
+ date: 2020-07-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: 0.14.0
21
18
  - - "~>"
22
19
  - !ruby/object:Gem::Version
23
20
  version: '0.14'
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.14.0
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- version: 0.14.0
31
28
  - - "~>"
32
29
  - !ruby/object:Gem::Version
33
30
  version: '0.14'
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.14.0
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: terminal-table
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -51,20 +51,6 @@ dependencies:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: 1.5.1
54
- - !ruby/object:Gem::Dependency
55
- name: pry
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '0'
61
- type: :development
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: '0'
68
54
  - !ruby/object:Gem::Dependency
69
55
  name: rake
70
56
  requirement: !ruby/object:Gem::Requirement
@@ -93,20 +79,6 @@ dependencies:
93
79
  - - ">="
94
80
  - !ruby/object:Gem::Version
95
81
  version: '0'
96
- - !ruby/object:Gem::Dependency
97
- name: rubocop
98
- requirement: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - ">="
101
- - !ruby/object:Gem::Version
102
- version: '0'
103
- type: :development
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
82
  - !ruby/object:Gem::Dependency
111
83
  name: webmock
112
84
  requirement: !ruby/object:Gem::Requirement
@@ -152,6 +124,7 @@ files:
152
124
  - lib/gitlab/client/container_registry.rb
153
125
  - lib/gitlab/client/deployments.rb
154
126
  - lib/gitlab/client/environments.rb
127
+ - lib/gitlab/client/epic_issues.rb
155
128
  - lib/gitlab/client/epics.rb
156
129
  - lib/gitlab/client/events.rb
157
130
  - lib/gitlab/client/features.rb
@@ -193,6 +166,7 @@ files:
193
166
  - lib/gitlab/client/tags.rb
194
167
  - lib/gitlab/client/templates.rb
195
168
  - lib/gitlab/client/todos.rb
169
+ - lib/gitlab/client/user_snippets.rb
196
170
  - lib/gitlab/client/users.rb
197
171
  - lib/gitlab/client/versions.rb
198
172
  - lib/gitlab/client/wikis.rb
@@ -219,14 +193,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
219
193
  requirements:
220
194
  - - ">="
221
195
  - !ruby/object:Gem::Version
222
- version: '2.3'
196
+ version: '2.5'
223
197
  required_rubygems_version: !ruby/object:Gem::Requirement
224
198
  requirements:
225
199
  - - ">="
226
200
  - !ruby/object:Gem::Version
227
201
  version: '0'
228
202
  requirements: []
229
- rubygems_version: 3.0.6
203
+ rubygems_version: 3.1.2
230
204
  signing_key:
231
205
  specification_version: 4
232
206
  summary: A Ruby wrapper and CLI for the GitLab API