gitlab-akerl 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.prospectus +11 -0
  4. data/.travis.yml +8 -0
  5. data/CHANGELOG.md +229 -0
  6. data/CONTRIBUTING.md +195 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +24 -0
  9. data/README.md +192 -0
  10. data/Rakefile +9 -0
  11. data/bin/console +10 -0
  12. data/bin/setup +6 -0
  13. data/exe/gitlab +7 -0
  14. data/gitlab-akerl.gemspec +31 -0
  15. data/lib/gitlab.rb +45 -0
  16. data/lib/gitlab/api.rb +19 -0
  17. data/lib/gitlab/cli.rb +89 -0
  18. data/lib/gitlab/cli_helpers.rb +241 -0
  19. data/lib/gitlab/client.rb +48 -0
  20. data/lib/gitlab/client/branches.rb +91 -0
  21. data/lib/gitlab/client/build_triggers.rb +51 -0
  22. data/lib/gitlab/client/build_variables.rb +66 -0
  23. data/lib/gitlab/client/builds.rb +106 -0
  24. data/lib/gitlab/client/commits.rb +121 -0
  25. data/lib/gitlab/client/groups.rb +144 -0
  26. data/lib/gitlab/client/issues.rb +113 -0
  27. data/lib/gitlab/client/labels.rb +57 -0
  28. data/lib/gitlab/client/merge_requests.rb +168 -0
  29. data/lib/gitlab/client/milestones.rb +78 -0
  30. data/lib/gitlab/client/namespaces.rb +20 -0
  31. data/lib/gitlab/client/notes.rb +161 -0
  32. data/lib/gitlab/client/pipelines.rb +68 -0
  33. data/lib/gitlab/client/projects.rb +471 -0
  34. data/lib/gitlab/client/repositories.rb +78 -0
  35. data/lib/gitlab/client/repository_files.rb +88 -0
  36. data/lib/gitlab/client/runners.rb +115 -0
  37. data/lib/gitlab/client/services.rb +50 -0
  38. data/lib/gitlab/client/snippets.rb +91 -0
  39. data/lib/gitlab/client/system_hooks.rb +59 -0
  40. data/lib/gitlab/client/tags.rb +96 -0
  41. data/lib/gitlab/client/users.rb +250 -0
  42. data/lib/gitlab/configuration.rb +55 -0
  43. data/lib/gitlab/error.rb +85 -0
  44. data/lib/gitlab/file_response.rb +46 -0
  45. data/lib/gitlab/help.rb +95 -0
  46. data/lib/gitlab/objectified_hash.rb +34 -0
  47. data/lib/gitlab/page_links.rb +33 -0
  48. data/lib/gitlab/paginated_response.rb +97 -0
  49. data/lib/gitlab/request.rb +117 -0
  50. data/lib/gitlab/shell.rb +84 -0
  51. data/lib/gitlab/shell_history.rb +59 -0
  52. data/lib/gitlab/version.rb +3 -0
  53. data/spec/fixtures/branch.json +1 -0
  54. data/spec/fixtures/branch_delete.json +3 -0
  55. data/spec/fixtures/branches.json +1 -0
  56. data/spec/fixtures/build.json +38 -0
  57. data/spec/fixtures/build_artifacts.json +0 -0
  58. data/spec/fixtures/build_cancel.json +24 -0
  59. data/spec/fixtures/build_erase.json +24 -0
  60. data/spec/fixtures/build_retry.json +24 -0
  61. data/spec/fixtures/builds.json +78 -0
  62. data/spec/fixtures/builds_commits.json +64 -0
  63. data/spec/fixtures/compare_merge_request_diff.json +31 -0
  64. data/spec/fixtures/error_already_exists.json +1 -0
  65. data/spec/fixtures/error_project_not_found.json +1 -0
  66. data/spec/fixtures/get_repository_file.json +1 -0
  67. data/spec/fixtures/git_hook.json +1 -0
  68. data/spec/fixtures/group.json +60 -0
  69. data/spec/fixtures/group_create.json +1 -0
  70. data/spec/fixtures/group_create_with_description.json +1 -0
  71. data/spec/fixtures/group_delete.json +1 -0
  72. data/spec/fixtures/group_member.json +1 -0
  73. data/spec/fixtures/group_member_delete.json +1 -0
  74. data/spec/fixtures/group_member_edit.json +1 -0
  75. data/spec/fixtures/group_members.json +1 -0
  76. data/spec/fixtures/group_projects.json +44 -0
  77. data/spec/fixtures/group_search.json +2 -0
  78. data/spec/fixtures/groups.json +2 -0
  79. data/spec/fixtures/issue.json +1 -0
  80. data/spec/fixtures/issues.json +1 -0
  81. data/spec/fixtures/key.json +1 -0
  82. data/spec/fixtures/keys.json +1 -0
  83. data/spec/fixtures/label.json +1 -0
  84. data/spec/fixtures/labels.json +1 -0
  85. data/spec/fixtures/merge_request.json +1 -0
  86. data/spec/fixtures/merge_request_changes.json +1 -0
  87. data/spec/fixtures/merge_request_comment.json +1 -0
  88. data/spec/fixtures/merge_request_comments.json +1 -0
  89. data/spec/fixtures/merge_request_commits.json +1 -0
  90. data/spec/fixtures/merge_requests.json +1 -0
  91. data/spec/fixtures/milestone.json +1 -0
  92. data/spec/fixtures/milestone_issues.json +1 -0
  93. data/spec/fixtures/milestones.json +1 -0
  94. data/spec/fixtures/namespaces.json +1 -0
  95. data/spec/fixtures/note.json +1 -0
  96. data/spec/fixtures/notes.json +1 -0
  97. data/spec/fixtures/pipeline.json +23 -0
  98. data/spec/fixtures/pipeline_cancel.json +23 -0
  99. data/spec/fixtures/pipeline_create.json +23 -0
  100. data/spec/fixtures/pipeline_retry.json +23 -0
  101. data/spec/fixtures/pipelines.json +48 -0
  102. data/spec/fixtures/project.json +1 -0
  103. data/spec/fixtures/project_commit.json +13 -0
  104. data/spec/fixtures/project_commit_comment.json +1 -0
  105. data/spec/fixtures/project_commit_comments.json +1 -0
  106. data/spec/fixtures/project_commit_diff.json +10 -0
  107. data/spec/fixtures/project_commit_status.json +42 -0
  108. data/spec/fixtures/project_commits.json +1 -0
  109. data/spec/fixtures/project_edit.json +21 -0
  110. data/spec/fixtures/project_events.json +1 -0
  111. data/spec/fixtures/project_for_user.json +1 -0
  112. data/spec/fixtures/project_fork.json +50 -0
  113. data/spec/fixtures/project_fork_link.json +1 -0
  114. data/spec/fixtures/project_forked_for_user.json +50 -0
  115. data/spec/fixtures/project_hook.json +1 -0
  116. data/spec/fixtures/project_hooks.json +1 -0
  117. data/spec/fixtures/project_issues.json +1 -0
  118. data/spec/fixtures/project_key.json +6 -0
  119. data/spec/fixtures/project_keys.json +6 -0
  120. data/spec/fixtures/project_runner_enable.json +7 -0
  121. data/spec/fixtures/project_runners.json +16 -0
  122. data/spec/fixtures/project_search.json +1 -0
  123. data/spec/fixtures/project_star.json +44 -0
  124. data/spec/fixtures/project_tag_annotated.json +1 -0
  125. data/spec/fixtures/project_tag_lightweight.json +1 -0
  126. data/spec/fixtures/project_tags.json +1 -0
  127. data/spec/fixtures/project_unstar.json +44 -0
  128. data/spec/fixtures/project_update_commit_status.json +20 -0
  129. data/spec/fixtures/projects.json +1 -0
  130. data/spec/fixtures/raw_file.json +2 -0
  131. data/spec/fixtures/release_create.json +1 -0
  132. data/spec/fixtures/release_update.json +1 -0
  133. data/spec/fixtures/repository_file.json +1 -0
  134. data/spec/fixtures/runner.json +26 -0
  135. data/spec/fixtures/runner_delete.json +7 -0
  136. data/spec/fixtures/runner_edit.json +26 -0
  137. data/spec/fixtures/runners.json +16 -0
  138. data/spec/fixtures/runners_all.json +30 -0
  139. data/spec/fixtures/service.json +1 -0
  140. data/spec/fixtures/session.json +1 -0
  141. data/spec/fixtures/shell_history.json +2 -0
  142. data/spec/fixtures/snippet.json +1 -0
  143. data/spec/fixtures/snippet_content.json +3 -0
  144. data/spec/fixtures/snippets.json +1 -0
  145. data/spec/fixtures/system_hook.json +1 -0
  146. data/spec/fixtures/system_hooks.json +1 -0
  147. data/spec/fixtures/tag.json +1 -0
  148. data/spec/fixtures/tag_create.json +1 -0
  149. data/spec/fixtures/tag_create_with_description.json +1 -0
  150. data/spec/fixtures/tag_delete.json +1 -0
  151. data/spec/fixtures/tags.json +1 -0
  152. data/spec/fixtures/team_member.json +1 -0
  153. data/spec/fixtures/team_members.json +1 -0
  154. data/spec/fixtures/tree.json +1 -0
  155. data/spec/fixtures/trigger.json +7 -0
  156. data/spec/fixtures/triggers.json +16 -0
  157. data/spec/fixtures/user.json +1 -0
  158. data/spec/fixtures/user_block_unblock.json +1 -0
  159. data/spec/fixtures/user_email.json +1 -0
  160. data/spec/fixtures/user_emails.json +1 -0
  161. data/spec/fixtures/user_search.json +1 -0
  162. data/spec/fixtures/users.json +1 -0
  163. data/spec/fixtures/variable.json +4 -0
  164. data/spec/fixtures/variables.json +10 -0
  165. data/spec/gitlab/cli_helpers_spec.rb +57 -0
  166. data/spec/gitlab/cli_spec.rb +110 -0
  167. data/spec/gitlab/client/branches_spec.rb +99 -0
  168. data/spec/gitlab/client/build_triggers_spec.rb +67 -0
  169. data/spec/gitlab/client/build_variables_spec.rb +86 -0
  170. data/spec/gitlab/client/builds_spec.rb +148 -0
  171. data/spec/gitlab/client/client_spec.rb +11 -0
  172. data/spec/gitlab/client/commits_spec.rb +137 -0
  173. data/spec/gitlab/client/groups_spec.rb +197 -0
  174. data/spec/gitlab/client/issues_spec.rb +138 -0
  175. data/spec/gitlab/client/labels_spec.rb +68 -0
  176. data/spec/gitlab/client/merge_requests_spec.rb +177 -0
  177. data/spec/gitlab/client/milestones_spec.rb +82 -0
  178. data/spec/gitlab/client/namespaces_spec.rb +22 -0
  179. data/spec/gitlab/client/notes_spec.rb +205 -0
  180. data/spec/gitlab/client/pipelines_spec.rb +95 -0
  181. data/spec/gitlab/client/projects_spec.rb +603 -0
  182. data/spec/gitlab/client/repositories_spec.rb +109 -0
  183. data/spec/gitlab/client/repository_files_spec.rb +62 -0
  184. data/spec/gitlab/client/runners_spec.rb +185 -0
  185. data/spec/gitlab/client/services_spec.rb +55 -0
  186. data/spec/gitlab/client/snippets_spec.rb +100 -0
  187. data/spec/gitlab/client/system_hooks_spec.rb +69 -0
  188. data/spec/gitlab/client/tags_spec.rb +109 -0
  189. data/spec/gitlab/client/users_spec.rb +418 -0
  190. data/spec/gitlab/error_spec.rb +45 -0
  191. data/spec/gitlab/file_response_spec.rb +33 -0
  192. data/spec/gitlab/help_spec.rb +46 -0
  193. data/spec/gitlab/objectified_hash_spec.rb +48 -0
  194. data/spec/gitlab/page_links_spec.rb +16 -0
  195. data/spec/gitlab/paginated_response_spec.rb +60 -0
  196. data/spec/gitlab/request_spec.rb +73 -0
  197. data/spec/gitlab/shell_history_spec.rb +53 -0
  198. data/spec/gitlab/shell_spec.rb +80 -0
  199. data/spec/gitlab_spec.rb +97 -0
  200. data/spec/spec_helper.rb +74 -0
  201. metadata +476 -0
@@ -0,0 +1,46 @@
1
+ module Gitlab
2
+ # Wrapper class of file response.
3
+ class FileResponse
4
+ HEADER_CONTENT_DISPOSITION = 'Content-Disposition'.freeze
5
+
6
+ attr_reader :filename
7
+
8
+ def initialize(file)
9
+ @file = file
10
+ end
11
+
12
+ # @return [bool] Always false
13
+ def empty?
14
+ false
15
+ end
16
+
17
+ # @return [Hash] A hash consisting of filename and io object
18
+ def to_hash
19
+ { filename: @filename, data: @file }
20
+ end
21
+ alias_method :to_h, :to_hash
22
+
23
+ # @return [String] Formatted string with the class name, object id and filename.
24
+ def inspect
25
+ "#<#{self.class}:#{object_id} {filename: #{filename.inspect}}>"
26
+ end
27
+
28
+ def method_missing(name, *args, &block)
29
+ if @file.respond_to?(name)
30
+ @file.send(name, *args, &block)
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ def respond_to_missing?(method_name, include_private = false)
37
+ super || @file.respond_to?(method_name, include_private)
38
+ end
39
+
40
+ # Parse filename from the 'Content Disposition' header.
41
+ def parse_headers!(headers)
42
+ @filename = headers[HEADER_CONTENT_DISPOSITION].split("filename=")[1]
43
+ @filename = @filename[1...-1] if @filename[0] == '"' # Unquote filenames
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,95 @@
1
+ require 'gitlab'
2
+ require 'gitlab/cli_helpers'
3
+
4
+ module Gitlab::Help
5
+ extend Gitlab::CLI::Helpers
6
+
7
+ class << self
8
+ # Returns the (modified) help from the 'ri' command or returns an error.
9
+ #
10
+ # @return [String]
11
+ def get_help(cmd)
12
+ cmd_namespace = namespace cmd
13
+
14
+ if cmd_namespace
15
+ ri_output = `#{ri_cmd} -T #{cmd_namespace} 2>&1`.chomp
16
+
17
+ if $CHILD_STATUS == 0
18
+ change_help_output! cmd, ri_output
19
+ yield ri_output if block_given?
20
+
21
+ ri_output
22
+ else
23
+ "Ri docs not found for #{cmd}, please install the docs to use 'help'."
24
+ end
25
+ else
26
+ "Unknown command: #{cmd}."
27
+ end
28
+ end
29
+
30
+ # Finds the location of 'ri' on a system.
31
+ #
32
+ # @return [String]
33
+ def ri_cmd
34
+ which_ri = `which ri`.chomp
35
+ if which_ri.empty?
36
+ fail "'ri' tool not found in $PATH. Please install it to use the help."
37
+ end
38
+
39
+ which_ri
40
+ end
41
+
42
+ # A hash map that contains help topics (Branches, Groups, etc.)
43
+ # and a list of commands that are defined under a topic (create_branch,
44
+ # branches, protect_branch, etc.).
45
+ #
46
+ # @return [Hash<Array>]
47
+ def help_map
48
+ @help_map ||= begin
49
+ actions.each_with_object({}) do |action, hsh|
50
+ key = client.method(action).
51
+ owner.to_s.gsub(/Gitlab::(?:Client::)?/, '')
52
+ hsh[key] ||= []
53
+ hsh[key] << action.to_s
54
+ end
55
+ end
56
+ end
57
+
58
+ # Table with available commands.
59
+ #
60
+ # @return [Terminal::Table]
61
+ def actions_table(topic=nil)
62
+ rows = topic ? help_map[topic] : help_map.keys
63
+ table do |t|
64
+ t.title = topic || "Help Topics"
65
+
66
+ # add_row expects an array and we have strings hence the map.
67
+ rows.sort.map { |r| [r] }.each_with_index do |row, index|
68
+ t.add_row row
69
+ t.add_separator unless rows.size - 1 == index
70
+ end
71
+ end
72
+ end
73
+
74
+ # Returns full namespace of a command (e.g. Gitlab::Client::Branches.cmd)
75
+ def namespace(cmd)
76
+ method_owners.select { |method| method[:name] === cmd }.
77
+ map { |method| method[:owner] + '.' + method[:name] }.
78
+ shift
79
+ end
80
+
81
+ # Massage output from 'ri'.
82
+ def change_help_output!(cmd, output_str)
83
+ output_str.gsub!(/#{cmd}\((.*?)\)/m, cmd + ' \1')
84
+ output_str.gsub!(/\,[\s]*/, ' ')
85
+
86
+ # Ensure @option descriptions are on a single line
87
+ output_str.gsub!(/\n\[/, " \[")
88
+ output_str.gsub!(/\s(@)/, "\n@")
89
+ output_str.gsub!(/(\])\n(\:)/, '\1 \2')
90
+ output_str.gsub!(/(\:.*)(\n)(.*\.)/, '\1 \3')
91
+ output_str.gsub!(/\{(.+)\}/, '"{\1}"')
92
+
93
+ end
94
+ end # class << self
95
+ end
@@ -0,0 +1,34 @@
1
+ module Gitlab
2
+ # Converts hashes to the objects.
3
+ class ObjectifiedHash
4
+ # Creates a new ObjectifiedHash object.
5
+ def initialize(hash)
6
+ @hash = hash
7
+ @data = hash.inject({}) do |data, (key, value)|
8
+ value = ObjectifiedHash.new(value) if value.is_a? Hash
9
+ data[key.to_s] = value
10
+ data
11
+ end
12
+ end
13
+
14
+ # @return [Hash] The original hash.
15
+ def to_hash
16
+ @hash
17
+ end
18
+ alias_method :to_h, :to_hash
19
+
20
+ # @return [String] Formatted string with the class name, object id and original hash.
21
+ def inspect
22
+ "#<#{self.class}:#{object_id} {hash: #{@hash.inspect}}"
23
+ end
24
+
25
+ # Delegate to ObjectifiedHash.
26
+ def method_missing(key)
27
+ @data.key?(key.to_s) ? @data[key.to_s] : nil
28
+ end
29
+
30
+ def respond_to_missing?(method_name, include_private = false)
31
+ @hash.keys.map(&:to_sym).include?(method_name.to_sym) || super
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ module Gitlab
2
+ # Parses link header.
3
+ #
4
+ # @private
5
+ class PageLinks
6
+ HEADER_LINK = 'Link'.freeze
7
+ DELIM_LINKS = ','.freeze
8
+ LINK_REGEX = /<([^>]+)>; rel=\"([^\"]+)\"/
9
+ METAS = %w(last next first prev)
10
+
11
+ attr_accessor(*METAS)
12
+
13
+ def initialize(headers)
14
+ link_header = headers[HEADER_LINK]
15
+
16
+ if link_header && link_header =~ /(next|first|last|prev)/
17
+ extract_links(link_header)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def extract_links(header)
24
+ header.split(DELIM_LINKS).each do |link|
25
+ LINK_REGEX.match(link.strip) do |match|
26
+ url, meta = match[1], match[2]
27
+ next if !url || !meta || METAS.index(meta).nil?
28
+ self.send("#{meta}=", url)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,97 @@
1
+ module Gitlab
2
+ # Wrapper class of paginated response.
3
+ class PaginatedResponse
4
+ attr_accessor :client
5
+
6
+ def initialize(array)
7
+ @array = array
8
+ end
9
+
10
+ def ==(other)
11
+ @array == other
12
+ end
13
+
14
+ def inspect
15
+ @array.inspect
16
+ end
17
+
18
+ def method_missing(name, *args, &block)
19
+ if @array.respond_to?(name)
20
+ @array.send(name, *args, &block)
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def respond_to_missing?(method_name, include_private = false)
27
+ super || @array.respond_to?(method_name, include_private)
28
+ end
29
+
30
+ def parse_headers!(headers)
31
+ @links = PageLinks.new headers
32
+ end
33
+
34
+ def each_page
35
+ current = self
36
+ yield current
37
+ while current.has_next_page?
38
+ current = current.next_page
39
+ yield current
40
+ end
41
+ end
42
+
43
+ def auto_paginate
44
+ response = block_given? ? nil : []
45
+ each_page do |page|
46
+ if block_given?
47
+ page.each do |item|
48
+ yield item
49
+ end
50
+ else
51
+ response += page
52
+ end
53
+ end
54
+ response
55
+ end
56
+
57
+ def has_last_page?
58
+ !(@links.nil? || @links.last.nil?)
59
+ end
60
+
61
+ def last_page
62
+ return nil if @client.nil? || !has_last_page?
63
+ path = @links.last.sub(/#{@client.endpoint}/, '')
64
+ @client.get(path)
65
+ end
66
+
67
+ def has_first_page?
68
+ !(@links.nil? || @links.first.nil?)
69
+ end
70
+
71
+ def first_page
72
+ return nil if @client.nil? || !has_first_page?
73
+ path = @links.first.sub(/#{@client.endpoint}/, '')
74
+ @client.get(path)
75
+ end
76
+
77
+ def has_next_page?
78
+ !(@links.nil? || @links.next.nil?)
79
+ end
80
+
81
+ def next_page
82
+ return nil if @client.nil? || !has_next_page?
83
+ path = @links.next.sub(/#{@client.endpoint}/, '')
84
+ @client.get(path)
85
+ end
86
+
87
+ def has_prev_page?
88
+ !(@links.nil? || @links.prev.nil?)
89
+ end
90
+
91
+ def prev_page
92
+ return nil if @client.nil? || !has_prev_page?
93
+ path = @links.prev.sub(/#{@client.endpoint}/, '')
94
+ @client.get(path)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,117 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ module Gitlab
5
+ # @private
6
+ class Request
7
+ include HTTParty
8
+ format :json
9
+ headers 'Accept' => 'application/json'
10
+ parser proc { |body, _| parse(body) }
11
+
12
+ attr_accessor :private_token, :endpoint
13
+
14
+ # Converts the response body to an ObjectifiedHash.
15
+ def self.parse(body)
16
+ body = decode(body)
17
+
18
+ if body.is_a? Hash
19
+ ObjectifiedHash.new body
20
+ elsif body.is_a? Array
21
+ PaginatedResponse.new(body.collect! { |e| ObjectifiedHash.new(e) })
22
+ elsif body
23
+ true
24
+ elsif !body
25
+ false
26
+ elsif body.nil?
27
+ false
28
+ else
29
+ raise Error::Parsing.new "Couldn't parse a response body"
30
+ end
31
+ end
32
+
33
+ # Decodes a JSON response into Ruby object.
34
+ def self.decode(response)
35
+ JSON.load response
36
+ rescue JSON::ParserError
37
+ raise Error::Parsing.new "The response is not a valid JSON"
38
+ end
39
+
40
+ def get(path, options={})
41
+ set_httparty_config(options)
42
+ set_authorization_header(options)
43
+ validate self.class.get(@endpoint + path, options)
44
+ end
45
+
46
+ def post(path, options={})
47
+ set_httparty_config(options)
48
+ set_authorization_header(options, path)
49
+ validate self.class.post(@endpoint + path, options)
50
+ end
51
+
52
+ def put(path, options={})
53
+ set_httparty_config(options)
54
+ set_authorization_header(options)
55
+ validate self.class.put(@endpoint + path, options)
56
+ end
57
+
58
+ def delete(path, options={})
59
+ set_httparty_config(options)
60
+ set_authorization_header(options)
61
+ validate self.class.delete(@endpoint + path, options)
62
+ end
63
+
64
+ # Checks the response code for common errors.
65
+ # Returns parsed response for successful requests.
66
+ def validate(response)
67
+ error_klass = case response.code
68
+ when 400 then Error::BadRequest
69
+ when 401 then Error::Unauthorized
70
+ when 403 then Error::Forbidden
71
+ when 404 then Error::NotFound
72
+ when 405 then Error::MethodNotAllowed
73
+ when 409 then Error::Conflict
74
+ when 422 then Error::Unprocessable
75
+ when 500 then Error::InternalServerError
76
+ when 502 then Error::BadGateway
77
+ when 503 then Error::ServiceUnavailable
78
+ end
79
+
80
+ fail error_klass.new(response) if error_klass
81
+
82
+ parsed = response.parsed_response
83
+ parsed.client = self if parsed.respond_to?(:client=)
84
+ parsed.parse_headers!(response.headers) if parsed.respond_to?(:parse_headers!)
85
+ parsed
86
+ end
87
+
88
+ # Sets a base_uri and default_params for requests.
89
+ # @raise [Error::MissingCredentials] if endpoint not set.
90
+ def set_request_defaults(sudo=nil)
91
+ self.class.default_params sudo: sudo
92
+ raise Error::MissingCredentials.new("Please set an endpoint to API") unless @endpoint
93
+ self.class.default_params.delete(:sudo) if sudo.nil?
94
+ end
95
+
96
+ private
97
+
98
+ # Sets a PRIVATE-TOKEN or Authorization header for requests.
99
+ # @raise [Error::MissingCredentials] if private_token and auth_token are not set.
100
+ def set_authorization_header(options, path=nil)
101
+ unless path == '/session'
102
+ raise Error::MissingCredentials.new("Please provide a private_token or auth_token for user") unless @private_token
103
+ if @private_token.length <= 20
104
+ options[:headers] = { 'PRIVATE-TOKEN' => @private_token }
105
+ else
106
+ options[:headers] = { 'Authorization' => "Bearer #{@private_token}" }
107
+ end
108
+ end
109
+ end
110
+
111
+ # Set HTTParty configuration
112
+ # @see https://github.com/jnunemaker/httparty
113
+ def set_httparty_config(options)
114
+ options.merge!(httparty) if httparty
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,84 @@
1
+ require 'gitlab'
2
+ require 'gitlab/help'
3
+ require 'gitlab/cli_helpers'
4
+ require 'gitlab/shell_history'
5
+ require 'readline'
6
+ require 'shellwords'
7
+
8
+ class Gitlab::Shell
9
+ extend Gitlab::CLI::Helpers
10
+
11
+ class << self
12
+ attr_reader :arguments, :command
13
+
14
+ def start
15
+ trap('INT') { quit_shell } # capture ctrl-c
16
+ setup
17
+
18
+ while buffer = Readline.readline('gitlab> ')
19
+ begin
20
+ parse_input buffer
21
+
22
+ @arguments.map! { |arg| symbolize_keys(yaml_load(arg)) }
23
+
24
+ case buffer
25
+ when nil, ''
26
+ next
27
+ when 'exit'
28
+ quit_shell
29
+ when /^\bhelp\b+/
30
+ puts help(arguments[0]) { |out| out.gsub!(/Gitlab\./, 'gitlab> ') }
31
+ else
32
+ history << buffer
33
+
34
+ data = execute command, arguments
35
+ output_table command, arguments, data
36
+ end
37
+ rescue => e
38
+ puts e.message
39
+ end
40
+ end
41
+
42
+ quit_shell # save history if user presses ctrl-d
43
+ end
44
+
45
+ def parse_input(buffer)
46
+ buf = Shellwords.shellwords(buffer)
47
+
48
+ @command = buf.shift
49
+ @arguments = buf.count > 0 ? buf : []
50
+ end
51
+
52
+ def setup
53
+ history.load
54
+
55
+ Readline.completion_proc = completion
56
+ Readline.completion_append_character = ' '
57
+ end
58
+
59
+ # Gets called when user hits TAB key to do completion
60
+ def completion
61
+ proc { |str| actions.map(&:to_s).grep(/^#{Regexp.escape(str)}/) }
62
+ end
63
+
64
+ # Execute a given command with arguements
65
+ def execute(cmd=command, args=arguments)
66
+ if actions.include?(cmd.to_sym)
67
+ confirm_command(cmd)
68
+ gitlab_helper(cmd, args)
69
+ else
70
+ fail "Unknown command: #{cmd}. " \
71
+ "See the 'help' for a list of valid commands."
72
+ end
73
+ end
74
+
75
+ def quit_shell
76
+ history.save
77
+ exit
78
+ end
79
+
80
+ def history
81
+ @history ||= History.new
82
+ end
83
+ end # class << self
84
+ end