gitlab 3.0.0 → 3.1.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +1 -0
- data/LICENSE.txt +1 -1
- data/README.md +28 -3
- data/bin/gitlab +7 -0
- data/gitlab.gemspec +3 -2
- data/lib/gitlab.rb +8 -0
- data/lib/gitlab/api.rb +1 -1
- data/lib/gitlab/cli.rb +57 -0
- data/lib/gitlab/cli_helpers.rb +141 -0
- data/lib/gitlab/client.rb +8 -6
- data/lib/gitlab/client/branches.rb +79 -0
- data/lib/gitlab/client/merge_requests.rb +15 -2
- data/lib/gitlab/client/projects.rb +25 -4
- data/lib/gitlab/client/repositories.rb +22 -23
- data/lib/gitlab/client/system_hooks.rb +58 -0
- data/lib/gitlab/client/users.rb +17 -0
- data/lib/gitlab/configuration.rb +3 -3
- data/lib/gitlab/objectified_hash.rb +8 -2
- data/lib/gitlab/request.rb +21 -5
- data/lib/gitlab/version.rb +1 -1
- data/spec/fixtures/branch.json +1 -0
- data/spec/fixtures/{project_branches.json → branches.json} +0 -0
- data/spec/fixtures/create_branch.json +1 -0
- data/spec/fixtures/merge_request_comments.json +1 -0
- data/spec/fixtures/project_commit.json +13 -0
- data/spec/fixtures/project_commit_diff.json +10 -0
- data/spec/fixtures/{project_branch.json → protect_branch.json} +1 -1
- data/spec/fixtures/system_hook.json +1 -0
- data/spec/fixtures/system_hook_test.json +1 -0
- data/spec/fixtures/system_hooks.json +1 -0
- data/spec/fixtures/unprotect_branch.json +1 -0
- data/spec/gitlab/cli_spec.rb +80 -0
- data/spec/gitlab/client/branches_spec.rb +103 -0
- data/spec/gitlab/client/groups_spec.rb +21 -21
- data/spec/gitlab/client/issues_spec.rb +26 -26
- data/spec/gitlab/client/merge_requests_spec.rb +45 -13
- data/spec/gitlab/client/milestones_spec.rb +11 -11
- data/spec/gitlab/client/notes_spec.rb +30 -30
- data/spec/gitlab/client/projects_spec.rb +93 -59
- data/spec/gitlab/client/repositories_spec.rb +28 -25
- data/spec/gitlab/client/snippets_spec.rb +16 -16
- data/spec/gitlab/client/system_hooks_spec.rb +69 -0
- data/spec/gitlab/client/users_spec.rb +60 -24
- data/spec/gitlab/objectified_hash_spec.rb +23 -0
- data/spec/gitlab/request_spec.rb +48 -0
- data/spec/gitlab_spec.rb +16 -7
- data/spec/spec_helper.rb +19 -8
- metadata +70 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88679bf87230b7d3d6bb8f0e96fb779967936216
|
4
|
+
data.tar.gz: 6c41b6c43280434257bc160aa38963ef50a4cc72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae58eefafd56dba8d8b87029c89972d036c479d3a3d15b6a7196e08495d9325de841a1860cb29151dd879aa05bee8fef1f340118d6309b520532804615b464d9
|
7
|
+
data.tar.gz: a96ddd98eebc816f295856c6996b1b29462c9a236d4a1d67b5c6259dc00e7f1b7b08bbf395c7bc69d1b8983e7be990ca2cda9a143c218f33dab3d3df8134731f
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
[](http://travis-ci.org/NARKOZ/gitlab)
|
4
4
|
|
5
|
-
|
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/
|
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/
|
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.
|
data/bin/gitlab
ADDED
data/gitlab.gemspec
CHANGED
@@ -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'
|
data/lib/gitlab.rb
CHANGED
@@ -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
|
data/lib/gitlab/api.rb
CHANGED
data/lib/gitlab/cli.rb
ADDED
@@ -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
|
data/lib/gitlab/client.rb
CHANGED
@@ -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
|
6
|
+
include Branches
|
7
|
+
include Groups
|
7
8
|
include Issues
|
8
|
-
include
|
9
|
+
include MergeRequests
|
9
10
|
include Milestones
|
10
|
-
include
|
11
|
+
include Notes
|
11
12
|
include Projects
|
12
13
|
include Repositories
|
13
|
-
include
|
14
|
-
include
|
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.
|
74
|
-
# Gitlab.
|
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)
|