gitlab 4.13.1 → 4.16.1

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: 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