gitlab 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +1 -0
  4. data/LICENSE.txt +1 -1
  5. data/README.md +28 -3
  6. data/bin/gitlab +7 -0
  7. data/gitlab.gemspec +3 -2
  8. data/lib/gitlab.rb +8 -0
  9. data/lib/gitlab/api.rb +1 -1
  10. data/lib/gitlab/cli.rb +57 -0
  11. data/lib/gitlab/cli_helpers.rb +141 -0
  12. data/lib/gitlab/client.rb +8 -6
  13. data/lib/gitlab/client/branches.rb +79 -0
  14. data/lib/gitlab/client/merge_requests.rb +15 -2
  15. data/lib/gitlab/client/projects.rb +25 -4
  16. data/lib/gitlab/client/repositories.rb +22 -23
  17. data/lib/gitlab/client/system_hooks.rb +58 -0
  18. data/lib/gitlab/client/users.rb +17 -0
  19. data/lib/gitlab/configuration.rb +3 -3
  20. data/lib/gitlab/objectified_hash.rb +8 -2
  21. data/lib/gitlab/request.rb +21 -5
  22. data/lib/gitlab/version.rb +1 -1
  23. data/spec/fixtures/branch.json +1 -0
  24. data/spec/fixtures/{project_branches.json → branches.json} +0 -0
  25. data/spec/fixtures/create_branch.json +1 -0
  26. data/spec/fixtures/merge_request_comments.json +1 -0
  27. data/spec/fixtures/project_commit.json +13 -0
  28. data/spec/fixtures/project_commit_diff.json +10 -0
  29. data/spec/fixtures/{project_branch.json → protect_branch.json} +1 -1
  30. data/spec/fixtures/system_hook.json +1 -0
  31. data/spec/fixtures/system_hook_test.json +1 -0
  32. data/spec/fixtures/system_hooks.json +1 -0
  33. data/spec/fixtures/unprotect_branch.json +1 -0
  34. data/spec/gitlab/cli_spec.rb +80 -0
  35. data/spec/gitlab/client/branches_spec.rb +103 -0
  36. data/spec/gitlab/client/groups_spec.rb +21 -21
  37. data/spec/gitlab/client/issues_spec.rb +26 -26
  38. data/spec/gitlab/client/merge_requests_spec.rb +45 -13
  39. data/spec/gitlab/client/milestones_spec.rb +11 -11
  40. data/spec/gitlab/client/notes_spec.rb +30 -30
  41. data/spec/gitlab/client/projects_spec.rb +93 -59
  42. data/spec/gitlab/client/repositories_spec.rb +28 -25
  43. data/spec/gitlab/client/snippets_spec.rb +16 -16
  44. data/spec/gitlab/client/system_hooks_spec.rb +69 -0
  45. data/spec/gitlab/client/users_spec.rb +60 -24
  46. data/spec/gitlab/objectified_hash_spec.rb +23 -0
  47. data/spec/gitlab/request_spec.rb +48 -0
  48. data/spec/gitlab_spec.rb +16 -7
  49. data/spec/spec_helper.rb +19 -8
  50. metadata +70 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e73d6232b1c15dcf05f0b58e12e4d93ca076d210
4
- data.tar.gz: b8e227455c58f3195448c2712b0ea6f1e3d56ade
3
+ metadata.gz: 88679bf87230b7d3d6bb8f0e96fb779967936216
4
+ data.tar.gz: 6c41b6c43280434257bc160aa38963ef50a4cc72
5
5
  SHA512:
6
- metadata.gz: e624e3813e30c96657d5810788dc56bcf032b8f132a8a36a88ad3a7a13aa9a42f2c7bf3f61a47c9c21c5013dc09327e79d305db7a67f985530a6998c5e94da95
7
- data.tar.gz: d118ef1b86f69311740d79e0f74390c8041e2c8a5b96345ed0edb52bbbc5bfa243fd380b8e8106eeaf71d28114968aeac879938ec5a76aa399d4adb2c075b47d
6
+ metadata.gz: ae58eefafd56dba8d8b87029c89972d036c479d3a3d15b6a7196e08495d9325de841a1860cb29151dd879aa05bee8fef1f340118d6309b520532804615b464d9
7
+ data.tar.gz: a96ddd98eebc816f295856c6996b1b29462c9a236d4a1d67b5c6259dc00e7f1b7b08bbf395c7bc69d1b8983e7be990ca2cda9a143c218f33dab3d3df8134731f
data/.gitignore CHANGED
@@ -16,3 +16,5 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .idea
19
+ .ruby-version
20
+ .ruby-gemset
@@ -2,3 +2,4 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2013 Nihad Abbasov <mail@narkoz.me>
1
+ Copyright (c) 2012-2014 Nihad Abbasov <mail@narkoz.me>
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/NARKOZ/gitlab.png)](http://travis-ci.org/NARKOZ/gitlab)
4
4
 
5
- Gitlab is a Ruby wrapper for the [GitLab API](https://github.com/gitlabhq/gitlabhq/tree/master/doc/api#gitlab-api).
5
+ [website](http://narkoz.github.io/gitlab) |
6
+ [documentation](http://rubydoc.info/gems/gitlab/frames)
7
+
8
+ Gitlab is a Ruby wrapper and CLI for the [GitLab API](https://github.com/gitlabhq/gitlabhq/tree/master/doc/api#gitlab-api).
6
9
 
7
10
  ## Installation
8
11
 
@@ -25,7 +28,7 @@ Configuration example:
25
28
 
26
29
  ```ruby
27
30
  Gitlab.configure do |config|
28
- config.endpoint = 'https://example.net/api/v2' # API endpoint URL (required)
31
+ config.endpoint = 'https://example.net/api/v3' # API endpoint URL (required)
29
32
  config.private_token = 'qEsq1pt6HJPaNciie3MG' # user's private token (required)
30
33
  config.user_agent = 'Custom User Agent' # user agent, default to 'Gitlab Ruby Gem [version]' (optional)
31
34
  end
@@ -35,7 +38,7 @@ Usage examples:
35
38
 
36
39
  ```ruby
37
40
  # set an API endpoint
38
- Gitlab.endpoint = 'http://example.net/api/v2'
41
+ Gitlab.endpoint = 'http://example.net/api/v3'
39
42
  # => "http://example.net/api/v2"
40
43
 
41
44
  # set a user private token
@@ -69,6 +72,28 @@ Gitlab.sudo = nil
69
72
 
70
73
  For more information, refer to [documentation](http://rubydoc.info/gems/gitlab/frames).
71
74
 
75
+ ## CLI
76
+
77
+ Usage examples:
78
+
79
+ ```sh
80
+ # list users
81
+ gitlab users
82
+
83
+ # get current user
84
+ gitlab user
85
+
86
+ # get a user
87
+ gitlab user 2
88
+
89
+ # filter output
90
+ gitlab user --only=id,username
91
+
92
+ gitlab user --except=email,bio
93
+ ```
94
+
95
+ For more information, refer to [website](http://narkoz.github.io/gitlab).
96
+
72
97
  ## License
73
98
 
74
99
  Released under the BSD 2-clause license. See LICENSE.txt for details.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'gitlab/cli'
6
+
7
+ Gitlab::CLI.start(ARGV)
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Gitlab::VERSION
9
9
  gem.authors = ["Nihad Abbasov"]
10
10
  gem.email = ["mail@narkoz.me"]
11
- gem.description = %q{Ruby client for GitLab API}
12
- gem.summary = %q{A Ruby wrapper for the GitLab API}
11
+ gem.description = %q{Ruby client and CLI for GitLab API}
12
+ gem.summary = %q{A Ruby wrapper and CLI for the GitLab API}
13
13
  gem.homepage = "https://github.com/narkoz/gitlab"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|
18
18
  gem.require_paths = ["lib"]
19
19
 
20
20
  gem.add_runtime_dependency 'httparty'
21
+ gem.add_runtime_dependency 'terminal-table'
21
22
 
22
23
  gem.add_development_dependency 'rake'
23
24
  gem.add_development_dependency 'rspec'
@@ -26,4 +26,12 @@ module Gitlab
26
26
  def self.respond_to?(method)
27
27
  return client.respond_to?(method) || super
28
28
  end
29
+
30
+ # Returns an unsorted array of available client methods.
31
+ #
32
+ # @return [Array<Symbol>]
33
+ def self.actions
34
+ hidden = /endpoint|private_token|user_agent|sudo|get|post|put|\Adelete\z|validate|set_request_defaults/
35
+ (Gitlab::Client.instance_methods - Object.methods).reject {|e| e[hidden]}
36
+ end
29
37
  end
@@ -2,7 +2,7 @@ module Gitlab
2
2
  # @private
3
3
  class API < Request
4
4
  # @private
5
- attr_accessor *Configuration::VALID_OPTIONS_KEYS
5
+ attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
6
6
 
7
7
  # Creates a new API.
8
8
  # @raise [Error:MissingCredentials]
@@ -0,0 +1,57 @@
1
+ require 'gitlab'
2
+ require 'terminal-table/import'
3
+ require_relative 'cli_helpers'
4
+
5
+ class Gitlab::CLI
6
+ extend Helpers
7
+
8
+ def self.start(args)
9
+ command = args.shift.strip rescue 'help'
10
+ run(command, args)
11
+ end
12
+
13
+ def self.run(cmd, args=[])
14
+ case cmd
15
+ when 'help'
16
+ puts actions_table
17
+ when 'info'
18
+ endpoint = Gitlab.endpoint ? Gitlab.endpoint : 'not set'
19
+ private_token = Gitlab.private_token ? Gitlab.private_token : 'not set'
20
+ puts "Gitlab endpoint is #{endpoint}"
21
+ puts "Gitlab private token is #{private_token}"
22
+ puts "Ruby Version is #{RUBY_VERSION}"
23
+ puts "Gitlab Ruby Gem #{Gitlab::VERSION}"
24
+ when '-v', '--version'
25
+ puts "Gitlab Ruby Gem #{Gitlab::VERSION}"
26
+ else
27
+ unless Gitlab.actions.include?(cmd.to_sym)
28
+ puts "Unknown command. Run `gitlab help` for a list of available commands."
29
+ exit(1)
30
+ end
31
+
32
+ if args.any? && (args.last.start_with?('--only=') || args.last.start_with?('--except='))
33
+ command_args = args[0..-2]
34
+ else
35
+ command_args = args
36
+ end
37
+
38
+ confirm_command(cmd)
39
+
40
+ begin
41
+ data = args.any? ? Gitlab.send(cmd, *command_args) : Gitlab.send(cmd)
42
+ rescue => e
43
+ puts e.message
44
+ exit(1)
45
+ end
46
+
47
+ case data
48
+ when Gitlab::ObjectifiedHash
49
+ puts single_record_table(data, cmd, args)
50
+ when Array
51
+ puts multiple_record_table(data, cmd, args)
52
+ else
53
+ puts data.inspect
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,141 @@
1
+ class Gitlab::CLI
2
+ # Defines methods related to CLI output and formatting.
3
+ module Helpers
4
+ extend self
5
+
6
+ # Returns filtered required fields.
7
+ #
8
+ # @return [Array]
9
+ def required_fields(args)
10
+ if args.any? && args.last.start_with?('--only=')
11
+ args.last.gsub('--only=', '').split(',')
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+ # Returns filtered excluded fields.
18
+ #
19
+ # @return [Array]
20
+ def excluded_fields(args)
21
+ if args.any? && args.last.start_with?('--except=')
22
+ args.last.gsub('--except=', '').split(',')
23
+ else
24
+ []
25
+ end
26
+ end
27
+
28
+ # Confirms command with a desctructive action.
29
+ #
30
+ # @return [String]
31
+ def confirm_command(cmd)
32
+ if cmd.start_with?('remove_') || cmd.start_with?('delete_')
33
+ puts "Are you sure? (y/n)"
34
+ if %w(y yes).include?($stdin.gets.to_s.strip.downcase)
35
+ puts 'Proceeding..'
36
+ else
37
+ puts 'Command aborted.'
38
+ exit(1)
39
+ end
40
+ end
41
+ end
42
+
43
+ # Table with available commands.
44
+ #
45
+ # @return [String]
46
+ def actions_table
47
+ client = Gitlab::Client.new(endpoint: '')
48
+ actions = Gitlab.actions
49
+ methods = []
50
+
51
+ actions.each do |action|
52
+ methods << {
53
+ name: action,
54
+ owner: client.method(action).owner.to_s.gsub('Gitlab::Client::', '')
55
+ }
56
+ end
57
+
58
+ owners = methods.map {|m| m[:owner]}.uniq.sort
59
+ methods_c = methods.group_by {|m| m[:owner]}
60
+ methods_c = methods_c.map {|_, v| [_, v.sort_by {|hv| hv[:name]}] }
61
+ methods_c = Hash[methods_c.sort_by(&:first).map {|k, v| [k, v]}]
62
+ max_column_length = methods_c.values.max_by(&:size).size
63
+
64
+ rows = max_column_length.times.map do |i|
65
+ methods_c.keys.map do |key|
66
+ methods_c[key][i] ? methods_c[key][i][:name] : ''
67
+ end
68
+ end
69
+
70
+ table do |t|
71
+ t.title = "Available commands (#{actions.size} total)"
72
+ t.headings = owners
73
+
74
+ rows.each do |row|
75
+ t.add_row row
76
+ end
77
+ end
78
+ end
79
+
80
+ # Table for a single record.
81
+ #
82
+ # @return [String]
83
+ def single_record_table(data, cmd, args)
84
+ hash = data.to_h
85
+ keys = hash.keys.sort {|x, y| x.to_s <=> y.to_s }
86
+ keys = keys & required_fields(args) if required_fields(args).any?
87
+ keys = keys - excluded_fields(args)
88
+
89
+ table do |t|
90
+ t.title = "Gitlab.#{cmd} #{args.join(', ')}"
91
+
92
+ keys.each_with_index do |key, index|
93
+ case value = hash[key]
94
+ when Hash
95
+ value = 'Hash'
96
+ when nil
97
+ value = 'null'
98
+ end
99
+
100
+ t.add_row [key, value]
101
+ t.add_separator unless keys.size - 1 == index
102
+ end
103
+ end
104
+ end
105
+
106
+ # Table for multiple records.
107
+ #
108
+ # @return [String]
109
+ def multiple_record_table(data, cmd, args)
110
+ return 'No data' if data.empty?
111
+
112
+ arr = data.map(&:to_h)
113
+ keys = arr.first.keys.sort {|x, y| x.to_s <=> y.to_s }
114
+ keys = keys & required_fields(args) if required_fields(args).any?
115
+ keys = keys - excluded_fields(args)
116
+
117
+ table do |t|
118
+ t.title = "Gitlab.#{cmd} #{args.join(', ')}"
119
+ t.headings = keys
120
+
121
+ arr.each_with_index do |hash, index|
122
+ values = []
123
+
124
+ keys.each do |key|
125
+ case value = hash[key]
126
+ when Hash
127
+ value = 'Hash'
128
+ when nil
129
+ value = 'null'
130
+ end
131
+
132
+ values << value
133
+ end
134
+
135
+ t.add_row values
136
+ t.add_separator unless arr.size - 1 == index
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -1,16 +1,18 @@
1
1
  module Gitlab
2
2
  # Wrapper for the Gitlab REST API.
3
3
  class Client < API
4
- Dir[File.expand_path('../client/*.rb', __FILE__)].each{|f| require f}
4
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each {|f| require f}
5
5
 
6
- include Users
6
+ include Branches
7
+ include Groups
7
8
  include Issues
8
- include Notes
9
+ include MergeRequests
9
10
  include Milestones
10
- include Snippets
11
+ include Notes
11
12
  include Projects
12
13
  include Repositories
13
- include MergeRequests
14
- include Groups
14
+ include Snippets
15
+ include SystemHooks
16
+ include Users
15
17
  end
16
18
  end
@@ -0,0 +1,79 @@
1
+ class Gitlab::Client
2
+ # Defines methods related to repositories.
3
+ module Branches
4
+ # Gets a list of project repositiory branches.
5
+ #
6
+ # @example
7
+ # Gitlab.branches(42)
8
+ #
9
+ # @param [Integer] project The ID of a project.
10
+ # @param [Hash] options A customizable set of options.
11
+ # @option options [Integer] :page The page number.
12
+ # @option options [Integer] :per_page The number of results per page.
13
+ # @return [Array<Gitlab::ObjectifiedHash>]
14
+ def branches(project, options={})
15
+ get("/projects/#{project}/repository/branches", :query => options)
16
+ end
17
+ alias_method :repo_branches, :branches
18
+
19
+ # Gets information about a repository branch.
20
+ #
21
+ # @example
22
+ # Gitlab.branch(3, 'api')
23
+ # Gitlab.repo_branch(5, 'master')
24
+ #
25
+ # @param [Integer] project The ID of a project.
26
+ # @param [String] branch The name of the branch.
27
+ # @return [Gitlab::ObjectifiedHash]
28
+ def branch(project, branch)
29
+ get("/projects/#{project}/repository/branches/#{branch}")
30
+ end
31
+
32
+ alias_method :repo_branch, :branch
33
+
34
+ # Protects a repository branch.
35
+ #
36
+ # @example
37
+ # Gitlab.protect_branch(3, 'api')
38
+ # Gitlab.repo_protect_branch(5, 'master')
39
+ #
40
+ # @param [Integer] project The ID of a project.
41
+ # @param [String] branch The name of the branch.
42
+ # @return [Gitlab::ObjectifiedHash]
43
+ def protect_branch(project, branch)
44
+ put("/projects/#{project}/repository/branches/#{branch}/protect")
45
+ end
46
+ alias_method :repo_protect_branch, :protect_branch
47
+
48
+ # Unprotects a repository branch.
49
+ #
50
+ # @example
51
+ # Gitlab.unprotect_branch(3, 'api')
52
+ # Gitlab.repo_unprotect_branch(5, 'master')
53
+ #
54
+ # @param [Integer] project The ID of a project.
55
+ # @param [String] branch The name of the branch.
56
+ # @return [Gitlab::ObjectifiedHash]
57
+ def unprotect_branch(project, branch)
58
+ put("/projects/#{project}/repository/branches/#{branch}/unprotect")
59
+ end
60
+ alias_method :repo_unprotect_branch, :unprotect_branch
61
+
62
+ # Creates a repository branch. Requires Gitlab >= 6.8.x
63
+ #
64
+ # @example
65
+ # Gitlab.create_branch(3, 'api')
66
+ # Gitlab.repo_create_branch(5, 'master')
67
+ #
68
+ # @param [Integer] project The ID of a project.
69
+ # @param [String] branch The name of the new branch.
70
+ # @param [String] ref Create branch from commit sha or existing branch
71
+ # @return [Gitlab::ObjectifiedHash]
72
+ def create_branch(project, branch, ref)
73
+ post("/projects/#{project}/repository/branches",:body => {:branch_name => branch, :ref => ref})
74
+ end
75
+ alias_method :repo_create_branch, :create_branch
76
+
77
+ end
78
+ end
79
+
@@ -62,6 +62,7 @@ class Gitlab::Client
62
62
  # @option options [String] :source_branch The source branch name.
63
63
  # @option options [String] :target_branch The target branch name.
64
64
  # @option options [Integer] :assignee_id The ID of a user to assign merge request.
65
+ # @option options [String] :state_event New state (close|reopen|merge).
65
66
  # @return [Gitlab::ObjectifiedHash] Information about updated merge request.
66
67
  def update_merge_request(project, id, options={})
67
68
  put("/projects/#{project}/merge_request/#{id}", :body => options)
@@ -70,8 +71,8 @@ class Gitlab::Client
70
71
  # Adds a comment to a merge request.
71
72
  #
72
73
  # @example
73
- # Gitlab.comment_merge_request(5, 1, "Awesome merge!")
74
- # Gitlab.comment_merge_request('gitlab', 1, "Awesome merge!")
74
+ # Gitlab.create_merge_request_comment(5, 1, "Awesome merge!")
75
+ # Gitlab.create_merge_request_comment('gitlab', 1, "Awesome merge!")
75
76
  #
76
77
  # @param [Integer] project The ID of a project.
77
78
  # @param [Integer] id The ID of a merge request.
@@ -81,6 +82,18 @@ class Gitlab::Client
81
82
  post("/projects/#{project}/merge_request/#{id}/comments", :body => {:note => note})
82
83
  end
83
84
 
85
+ # Gets the comments on a merge request.
86
+ #
87
+ # @example
88
+ # Gitlab.merge_request_comments(5, 1)
89
+ #
90
+ # @param [Integer] project The ID of a project.
91
+ # @param [Integer] id The ID of a merge request.
92
+ # @return [Gitlab::ObjectifiedHash] The merge request's comments.
93
+ def merge_request_comments(project, id)
94
+ get("/projects/#{project}/merge_request/#{id}/comments")
95
+ end
96
+
84
97
  private
85
98
 
86
99
  def check_attributes!(options, attrs)