gerry 0.1.1 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 54504c142edb7bfbe2b9bcc7ad1c4e0d8e288ec0
4
- data.tar.gz: 52bb964e310b1d57507e2443d6eb5170939ba2f7
3
+ metadata.gz: 66ad45b3c22d4eb38ac5829b13bf6a9423cf2fbb
4
+ data.tar.gz: 1047b76e06a51d583ea2b42f66456b1914f67602
5
5
  SHA512:
6
- metadata.gz: a9edca037aead6cf979a3f331de2a7122fba12de1fd171517bbf439912223cf4c375bfe3d510ed9724acb5820745a15de91900ffba09130f7d6c02fd827e0cea
7
- data.tar.gz: 01c5ca61b668906666d7599184aefeebfc7779192f172ecddd47eb51f5f08631a55831ca01264f84fbfc848fee2d68468469e172ac431f4bab581bb80c1dea62
6
+ metadata.gz: 9ba5ebc6c65e04e4c87ee5685a68add849ed53530f7102f4baf84f2224c8c8a319f4617aeda246a363af6c3f5e7c75c0d84895094bcc7c99e5a76244501f88ac
7
+ data.tar.gz: cf25c860e26863235b9d22f3eda7fc5093ee2f2ef3e6982ba8e47b7fecee467d9e521fd4c38db750092cca37370aad4fa5ffefaf72f87361b67a3597c6d7e886
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # gerry[![Build Status](https://travis-ci.org/trumant/gerry.svg)][travis]
2
2
 
3
+ Base Gerrit Version V2.14.6
4
+
3
5
  Simple Ruby wrapper for the Gerrit Code Review REST-API.
4
6
 
5
7
  ![Gary from spongebob square pants](http://en.spongepedia.org/images/3/37/Garry.jpg)
@@ -39,10 +41,14 @@ client.changes(['q=is:open'])
39
41
  => [{"project"=>"awesome", "branch"=>"master", "id"=>"Ibfedd978...."}]
40
42
  ```
41
43
 
44
+ ### Authentication type
45
+ Since 2.14, Gerrit no longer supports digest authentication.
46
+ Gerry uses basic authentication against gerrit.
47
+
42
48
  ## Licence
43
49
  The MIT Licence
44
50
 
45
- Copyright (c) Fabian Mettler, Andrew Erickson, Travis Truman, Sebastian Schuberth
51
+ Copyright (c) Fabian Mettler, Andrew Erickson, Travis Truman, Sebastian Schuberth, Orgad Shaneh
46
52
 
47
53
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
48
54
 
@@ -51,10 +57,6 @@ The above copyright notice and this permission notice shall be included in all c
51
57
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52
58
 
53
59
  ## References
54
- [http://code.google.com/p/gerrit/][gerrit]
55
-
56
- [gerrit]: http://code.google.com/p/gerrit/
57
-
58
- [https://gerrit-review.googlesource.com/Documentation/rest-api.html][apidocumentation]
60
+ https://www.gerritcodereview.com/
59
61
 
60
- [apidocumentation]: https://gerrit-review.googlesource.com/Documentation/rest-api.html
62
+ https://gerrit-review.googlesource.com/Documentation/rest-api.html
@@ -1,7 +1,7 @@
1
1
  require 'erb'
2
2
 
3
3
  module Gerry
4
- class Client
4
+ module Api
5
5
  module Access
6
6
  # Get access rights for the specified project
7
7
  #
@@ -1,17 +1,26 @@
1
1
  module Gerry
2
- class Client
2
+ module Api
3
3
  module Accounts
4
+ # Get the account info for the specified account ID.
5
+ #
6
+ # @param [String] account_id the account.
7
+ # @return [Hash] the account info.
8
+ def account_info(account_id)
9
+ url = "/accounts/#{account_id}"
10
+ get(url)
11
+ end
12
+
4
13
  # Get the global capabilities that are enabled for the calling user.
5
14
  #
6
15
  # @param [Array] options the query parameters.
7
16
  # @return [Hash] the account capabilities.
8
17
  def account_capabilities(options = [])
9
18
  url = '/accounts/self/capabilities'
10
-
19
+
11
20
  if options.empty?
12
21
  return get(url)
13
22
  end
14
-
23
+
15
24
  options = map_options(options)
16
25
  get("#{url}?#{options}")
17
26
  end
@@ -26,4 +35,4 @@ module Gerry
26
35
  end
27
36
  end
28
37
  end
29
- end
38
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gerry
4
+ module Api
5
+ module Branches
6
+ ##
7
+ # Get the branches of project
8
+ #
9
+ def branches(project_name)
10
+ get("/projects/#{project_name}/branches")
11
+ end
12
+
13
+ # Get the projects that start with the specified prefix
14
+ # and accessible by the caller.
15
+ #
16
+ # @param [String] name the project name.
17
+ # @return [Hash] the projects.
18
+ def branch(project_name, branch_name)
19
+ get("/projects/#{project_name}/branches/#{branch_name}")
20
+ end
21
+
22
+ ##
23
+ # create branch that derived from branch name or revision
24
+ #
25
+ # example: create_branch('foo', 'master', 'stable')
26
+ # create_branch('foo', 'revision', 'stable')
27
+ #
28
+ def create_branch(project_name, source, branch)
29
+ # try source as ref
30
+ body = { ref: source }
31
+ put("/projects/#{project_name}/branches/#{branch}", body)
32
+ rescue Gerry::Api::Request::RequestError
33
+ # try source as revision
34
+ body = { revision: source }
35
+ put("/projects/#{project_name}/branches/#{branch}", body)
36
+ end
37
+
38
+ ##
39
+ # Gets the reflog of a certain branch.
40
+ def branch_reflog(project_name, branch, number)
41
+ get("/projects/#{project_name}/branches/#{branch}/reflog?n=#{number}")
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,38 @@
1
+ require 'cgi'
2
+
3
+ module Gerry
4
+ module Api
5
+ module Changes
6
+ # Get changes visible to the caller.
7
+ #
8
+ # @param [Array] options the query parameters.
9
+ # @return [Hash] the changes.
10
+ def changes(options = [])
11
+ endpoint = '/changes/'
12
+ url = endpoint
13
+
14
+ if !options.empty?
15
+ url += '?' + map_options(options)
16
+ end
17
+
18
+ response = get(url)
19
+ return response if response.empty? || !response.last.delete('_more_changes')
20
+
21
+ # Get the original start parameter, if any, else start from 0.
22
+ query = URI.parse(url).query
23
+ query = query ? CGI.parse(query) : { 'S' => ['0'] }
24
+ start = query['S'].join.to_i
25
+
26
+ # Keep getting data until there are no more changes.
27
+ loop do
28
+ # Replace the start parameter, using the original start as an offset.
29
+ query['S'] = ["#{start + response.size}"]
30
+ url = endpoint + '?' + map_options(query)
31
+
32
+ response.concat(get(url))
33
+ return response if response.empty? || !response.last.delete('_more_changes')
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,7 +1,7 @@
1
1
  require 'json'
2
2
 
3
3
  module Gerry
4
- class Client
4
+ module Api
5
5
  module Groups
6
6
  # Get all groups
7
7
  #
@@ -69,4 +69,4 @@ module Gerry
69
69
  end
70
70
  end
71
71
  end
72
- end
72
+ end
@@ -1,5 +1,5 @@
1
1
  module Gerry
2
- class Client
2
+ module Api
3
3
  module Projects
4
4
  # Get the projects accessible by the caller.
5
5
  #
@@ -38,6 +38,36 @@ module Gerry
38
38
  }
39
39
  put(url, body)
40
40
  end
41
+
42
+ ##
43
+ # lists the access rights for signle project
44
+ def project_access(project)
45
+ get("/projects/#{project}/access")
46
+ end
47
+
48
+ def create_project_access(project, permissions)
49
+ access = {
50
+ 'add' => permissions
51
+ }
52
+ post("/projects/#{project}/access", access)
53
+ end
54
+
55
+ def remove_project_access(project, permissions)
56
+ access = {
57
+ 'remove' => permissions
58
+ }
59
+ post("/projects/#{project}/access", access)
60
+ end
61
+
62
+ ##
63
+ # Retrieves a commit of a project.
64
+ def project_commit(project, commit_id)
65
+ get("/projects/#{project}/commits/#{commit_id}")
66
+ end
67
+
68
+ def project_file(project, commit_id, file_id)
69
+ get("/projects/#{project}/commits/#{commit_id}/files/#{file_id}/content")
70
+ end
41
71
  end
42
72
  end
43
73
  end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gerry
4
+ module Api
5
+ module Request # :nodoc:
6
+ class RequestError < StandardError
7
+ end
8
+
9
+ # Get the mapped options.
10
+ #
11
+ # @param [Array] or [Hash] options the query parameters.
12
+ # @return [String] the mapped options.
13
+ def map_options(options)
14
+ if options.is_a?(Array)
15
+ options.map { |v| "#{v}" }.join('&')
16
+ elsif options.is_a?(Hash)
17
+ options.map { |k,v| "#{k}=#{v.join(',')}" }.join('&')
18
+ end
19
+ end
20
+
21
+ def options(body = nil, is_json = true)
22
+ return {} unless body
23
+ default_options = {
24
+ headers: {
25
+ 'Content-Type' => is_json ? 'application/json' : 'text/plain'
26
+ }
27
+ }
28
+ default_options[:body] = is_json ? body.to_json : body
29
+ default_options
30
+ end
31
+
32
+ def get(url)
33
+ response = self.class.get(auth_url(url))
34
+ parse(response)
35
+ end
36
+
37
+ def auth_url(url)
38
+ self.class.default_options[:basic_auth] ? "/a#{url}" : url
39
+ end
40
+
41
+ def put(url, body = nil, is_json = true)
42
+ response = self.class.put(auth_url(url), options(body, is_json))
43
+ parse(response)
44
+ end
45
+
46
+ def post(url, body, is_json = true)
47
+ response = self.class.post(auth_url(url), options(body, is_json))
48
+ parse(response)
49
+ end
50
+
51
+ def delete(url)
52
+ self.class.delete(auth_url(url))
53
+ parse(response)
54
+ end
55
+
56
+ private
57
+
58
+ def parse(response)
59
+ unless /2[0-9][0-9]/.match(response.code.to_s)
60
+ raise_request_error(response)
61
+ end
62
+ unless response.body.size.zero?
63
+ source = remove_magic_prefix(response.body)
64
+ if source.lines.count == 1 && !source.start_with?('{') && !source.start_with?('[')
65
+ # Work around the JSON gem not being able to parse top-level values, see
66
+ # https://github.com/flori/json/issues/206.
67
+ source.gsub!(/^"|"$/, '')
68
+ else
69
+ JSON.parse(source)
70
+ end
71
+ else
72
+ nil
73
+ end
74
+ end
75
+
76
+ def raise_request_error(response)
77
+ raise RequestError.new("There was a request error! Response was: #{response.message}")
78
+ end
79
+
80
+ def remove_magic_prefix(response_body)
81
+ # We need to strip the magic prefix from the first line of the response, see
82
+ # https://gerrit-review.googlesource.com/Documentation/rest-api.html#output.
83
+ # magic prefix: )]}
84
+ response_body[4..-1].strip!
85
+ end
86
+ end
87
+ end
88
+ end
@@ -1,24 +1,43 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'httparty'
2
4
  require 'json'
3
5
 
6
+ require_relative 'api/access'
7
+ require_relative 'api/accounts'
8
+ require_relative 'api/changes'
9
+ require_relative 'api/groups'
10
+ require_relative 'api/projects'
11
+ require_relative 'api/request'
12
+ require_relative 'api/branches'
13
+
14
+
4
15
  module Gerry
16
+ ##
17
+ # Client for gerrit request api
18
+ #
19
+ # - for anonymout user
20
+ # client = Gerry::Client.new('http://gerrit.example.com')
21
+ # - for user/password
22
+ # client = Gerry::Client.new('http://gerrit.example.com', 'username', 'password')
23
+ #
24
+ #
25
+
5
26
  class Client
6
27
  include HTTParty
7
28
  headers 'Accept' => 'application/json'
8
29
 
9
- require_relative 'client/access'
10
- require_relative 'client/accounts'
11
- require_relative 'client/changes'
12
- require_relative 'client/groups'
13
- require_relative 'client/projects'
14
- require_relative 'client/request'
30
+ include Api::Access
31
+ include Api::Accounts
32
+ include Api::Changes
33
+ include Api::Groups
34
+ include Api::Projects
35
+ include Api::Branches
36
+ include Api::Request
15
37
 
16
- include Access
17
- include Accounts
18
- include Changes
19
- include Groups
20
- include Projects
21
- include Request
38
+ def set_auth_type(auth_type)
39
+ warn 'set_auth_type is deprecated. digest auth is no longer supported'
40
+ end
22
41
 
23
42
  def initialize(url, username = nil, password = nil)
24
43
  self.class.base_uri(url)
@@ -26,7 +45,14 @@ module Gerry
26
45
  if username && password
27
46
  @username = username
28
47
  @password = password
48
+ else
49
+ require 'netrc'
50
+ @username, @password = Netrc.read[URI.parse(url).host]
51
+ end
52
+ if @username && @password
53
+ self.class.basic_auth(@username, @password)
29
54
  end
30
55
  end
31
56
  end
32
57
  end
58
+
@@ -1,5 +1,5 @@
1
1
  module Gerry
2
2
 
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.6"
4
4
 
5
- end
5
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'branches' do
4
+ before(:all) do
5
+ @client = MockGerry.new
6
+ end
7
+
8
+ it 'fetchs all branches' do
9
+ stub = stub_get('/projects/foo/branches', 'project_branches.json')
10
+
11
+ groups = @client.branches('foo')
12
+ expect(stub).to have_been_requested
13
+
14
+ expect(groups.size).to eq(3)
15
+ expect(groups.first.fetch('ref')).to eq('master')
16
+ end
17
+
18
+ it 'create branch' do
19
+ body = {
20
+ ref: 'master'
21
+ }
22
+ response = %Q<)]}'
23
+ {
24
+ "ref": "/refs/heads/stable",
25
+ "revision": "b43",
26
+ "can_delete": true
27
+ }
28
+ >
29
+ stub = stub_put('/projects/foo/branches/stable', body, response)
30
+ branch = @client.create_branch('foo', 'master', 'stable')
31
+
32
+ expect(stub).to have_been_requested
33
+
34
+ expect(branch.fetch('ref')).to eql('/refs/heads/stable')
35
+ end
36
+ end
@@ -20,6 +20,7 @@ describe '.changes' do
20
20
  it 'should fetch all changes in batches' do
21
21
  stub_batch_0 = stub_get('/changes/', 'changes_batch_0.json')
22
22
  stub_batch_1 = stub_get('/changes/?S=1', 'changes_batch_1.json')
23
+ stub_batch_2 = stub_get('/changes/?S=2', 'changes_batch_2.json')
23
24
 
24
25
  client = MockGerry.new
25
26
  changes = client.changes
@@ -29,10 +30,15 @@ describe '.changes' do
29
30
 
30
31
  expect(changes[0]['project']).to eq('awesome')
31
32
  expect(changes[0]['branch']).to eq('master')
33
+ expect(changes[0]['owner']['name']).to eq('The Duke')
32
34
 
33
35
  expect(changes[1]['project']).to eq('clean')
34
36
  expect(changes[1]['subject']).to eq('Refactor code')
35
37
  expect(changes[1]['owner']['name']).to eq('Batman')
38
+
39
+ expect(changes[2]['project']).to eq('X')
40
+ expect(changes[2]['subject']).to eq('Remove unused imports')
41
+ expect(changes[2]['owner']['name']).to eq('Bill')
36
42
  end
37
43
 
38
44
  it 'should fetch all open changes' do
@@ -0,0 +1,2 @@
1
+ )]}'
2
+ "Hello World!"
@@ -0,0 +1,50 @@
1
+ )]}'
2
+ {
3
+ "revision": "61157ed63e14d261b6dca40650472a9b0bd88474",
4
+ "inherits_from": {
5
+ "id": "All-Projects",
6
+ "name": "All-Projects",
7
+ "description": "Access inherited by all other projects."
8
+ },
9
+ "local": {
10
+ "refs/*": {
11
+ "permissions": {
12
+ "read": {
13
+ "rules": {
14
+ "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
15
+ "action": "ALLOW",
16
+ "force": false
17
+ },
18
+ "global:Anonymous-Users": {
19
+ "action": "ALLOW",
20
+ "force": false
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ },
27
+ "is_owner": true,
28
+ "owner_of": [
29
+ "refs/*"
30
+ ],
31
+ "can_upload": true,
32
+ "can_add": true,
33
+ "config_visible": true,
34
+ "groups": {
35
+ "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
36
+ "url": "#/admin/groups/uuid-c2ce4749a32ceb82cd6adcce65b8216e12afb41c",
37
+ "options": {},
38
+ "description": "Users who perform batch actions on Gerrit",
39
+ "group_id": 2,
40
+ "owner": "Administrators",
41
+ "owner_id": "d5b7124af4de52924ed397913e2c3b37bf186948",
42
+ "created_on": "2009-06-08 23:31:00.000000000",
43
+ "name": "Non-Interactive Users"
44
+ },
45
+ "global:Anonymous-Users": {
46
+ "options": {},
47
+ "name": "Anonymous Users"
48
+ }
49
+ }
50
+ }
@@ -12,6 +12,7 @@
12
12
  "_number": 42,
13
13
  "owner": {
14
14
  "name": "Batman"
15
- }
15
+ },
16
+ "_more_changes": true
16
17
  }
17
18
  ]
@@ -0,0 +1,17 @@
1
+ )]}'
2
+ [
3
+ {
4
+ "project": "X",
5
+ "branch": "default",
6
+ "id": "Ieb185f4da8725ae35e9f940e614c6eaa7b88eff5",
7
+ "subject": "Remove unused imports",
8
+ "status": "NEW",
9
+ "created": "2016-01-11 15:51:30.605000000",
10
+ "updated": "2016-02-12 00:45:26.431000000",
11
+ "_sortkey": "002e4203000187d5",
12
+ "_number": 4711,
13
+ "owner": {
14
+ "name": "Bill"
15
+ }
16
+ }
17
+ ]
@@ -0,0 +1,6 @@
1
+ )]}'
2
+ {
3
+ "ref": "refs/heads/stable",
4
+ "revision": "b43",
5
+ "can_delete": true
6
+ }
@@ -0,0 +1,21 @@
1
+ )]}'
2
+ [
3
+ {
4
+ "ref": "master",
5
+ "revision": "b3f3113",
6
+ "can_delete": "yes",
7
+ "web_lnks": "ab"
8
+ },
9
+ {
10
+ "ref": "develop",
11
+ "revision": "b3f3114",
12
+ "can_delete": "yes",
13
+ "web_lnks": "ab"
14
+ },
15
+ {
16
+ "ref": "stage",
17
+ "revision": "b3f3114",
18
+ "can_delete": "yes",
19
+ "web_lnks": "ab"
20
+ }
21
+ ]
@@ -1,11 +1,15 @@
1
1
  require 'spec_helper'
2
+ require 'pry'
2
3
 
3
4
  describe '.projects' do
5
+ before(:all) do
6
+ @client = MockGerry.new
7
+ end
8
+
4
9
  it 'should fetch all projects' do
5
10
  stub = stub_get('/projects/', 'projects.json')
6
11
 
7
- client = MockGerry.new
8
- projects = client.projects
12
+ projects = @client.projects
9
13
 
10
14
  expect(stub).to have_been_requested
11
15
 
@@ -16,20 +20,27 @@ describe '.projects' do
16
20
  it 'should fetch a project' do
17
21
  stub = stub_get('/projects/awesome', 'projects.json')
18
22
 
19
- client = MockGerry.new
20
- projects = client.find_project('awesome')
23
+ projects = @client.find_project('awesome')
21
24
 
22
25
  expect(stub).to have_been_requested
23
26
 
24
27
  expect(projects['awesome']['description']).to eq('Awesome project')
25
28
  end
26
29
 
30
+ it 'should fetch file content' do
31
+ stub = stub_get('/projects/awesome/commits/djfkslj/files/README.md/content','README.md.json')
32
+
33
+ file = @client.project_file('awesome','djfkslj','README.md')
34
+
35
+ expect(stub).to have_been_requested
36
+ expect(file).to eq('Hello World!')
37
+ end
38
+
27
39
  it 'should resolve the symbolic HEAD ref of a project' do
28
40
  project = 'awesome'
29
41
  stub = stub_get("/projects/#{project}/HEAD", 'project_head.json')
30
42
 
31
- client = MockGerry.new
32
- branch = client.get_head(project)
43
+ branch = @client.get_head(project)
33
44
 
34
45
  expect(stub).to have_been_requested
35
46
 
@@ -44,11 +55,36 @@ describe '.projects' do
44
55
  }
45
56
  stub = stub_put("/projects/#{project}/HEAD", input.to_json, get_fixture('project_head.json'))
46
57
 
47
- client = MockGerry.new
48
- new_branch = client.set_head(project, branch)
58
+ new_branch = @client.set_head(project, branch)
49
59
 
50
60
  expect(stub).to have_been_requested
51
61
 
52
62
  expect(new_branch).to eq('refs/heads/' + branch)
53
63
  end
64
+
65
+ it 'list access rights' do
66
+ stub = stub_get('/projects/foo/access', 'branch_access.json')
67
+
68
+ accesses = @client.project_access('foo')
69
+ expect(stub).to have_been_requested
70
+ end
71
+
72
+ it 'create project access rights' do
73
+ access_rights = {
74
+ 'refs/heads/*' => {
75
+ 'permissions' => {
76
+ 'read' => {
77
+ 'rules' => {
78
+ 'user:kobe' => {
79
+ 'action' => 'ALLOW'
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ stub = stub_post('/projects/foo/access', 'add' => access_rights)
87
+ @client.create_project_access('foo', access_rights)
88
+ expect(stub).to have_been_requested
89
+ end
54
90
  end
@@ -20,23 +20,27 @@ describe '.get' do
20
20
  expect(stub).to have_been_requested
21
21
  end
22
22
 
23
- it 'should request projects as user' do
23
+ it 'should request projects as user with basic auth' do
24
24
  username = 'gerry'
25
25
  password = 'whoop'
26
26
 
27
27
  body = get_fixture('projects.json')
28
-
29
- stub = stub_request(:get, "http://localhost/a/projects/").
30
- with(:headers => {'Accept'=>'application/json'}).
31
- to_return(:status => 200, :body => body, :headers => {})
28
+
29
+ stub = stub_request(:get, 'http://localhost/a/projects/').
30
+ with(
31
+ headers:
32
+ {
33
+ 'Accept' => 'application/json',
34
+ 'Authorization' => 'Basic Z2Vycnk6d2hvb3A='
35
+ }
36
+ ).to_return(:status => 200, :body => body, :headers => {})
32
37
 
33
38
  client = Gerry.new(MockGerry::URL, 'gerry', 'whoop')
34
39
  projects = client.projects
35
40
 
36
- # twice because the first is the auth challenge and then the actual request
37
- expect(stub).to have_been_requested.twice
41
+ expect(stub).to have_been_requested
38
42
 
39
43
  expect(projects['awesome']['description']).to eq('Awesome project')
40
44
  expect(projects['clean']['description']).to eq('Clean code!')
41
45
  end
42
- end
46
+ end
metadata CHANGED
@@ -1,17 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gerry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabian Mettler
8
8
  - Andrew Erickson
9
9
  - Travis Truman
10
10
  - Sebastian Schuberth
11
+ - Orgad Shaneh
12
+ - iiithking
11
13
  autorequire:
12
14
  bindir: bin
13
15
  cert_chain: []
14
- date: 2016-01-12 00:00:00.000000000 Z
16
+ date: 2020-12-29 00:00:00.000000000 Z
15
17
  dependencies:
16
18
  - !ruby/object:Gem::Dependency
17
19
  name: httparty
@@ -45,16 +47,16 @@ dependencies:
45
47
  name: rspec
46
48
  requirement: !ruby/object:Gem::Requirement
47
49
  requirements:
48
- - - "~>"
50
+ - - ">="
49
51
  - !ruby/object:Gem::Version
50
- version: 3.1.0
52
+ version: '0'
51
53
  type: :development
52
54
  prerelease: false
53
55
  version_requirements: !ruby/object:Gem::Requirement
54
56
  requirements:
55
- - - "~>"
57
+ - - ">="
56
58
  - !ruby/object:Gem::Version
57
- version: 3.1.0
59
+ version: '0'
58
60
  - !ruby/object:Gem::Dependency
59
61
  name: rack-test
60
62
  requirement: !ruby/object:Gem::Requirement
@@ -125,8 +127,21 @@ dependencies:
125
127
  - - ">="
126
128
  - !ruby/object:Gem::Version
127
129
  version: '0'
128
- description: |2
129
- Simple Ruby wrapper for the Gerrit Code Review REST-API.
130
+ - !ruby/object:Gem::Dependency
131
+ name: pry
132
+ requirement: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ type: :development
138
+ prerelease: false
139
+ version_requirements: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ description: " Simple Ruby wrapper for the Gerrit Code Review REST-API.\n"
130
145
  email: trumant@gmail.com
131
146
  executables: []
132
147
  extensions: []
@@ -135,26 +150,33 @@ files:
135
150
  - README.md
136
151
  - Rakefile
137
152
  - lib/gerry.rb
153
+ - lib/gerry/api/access.rb
154
+ - lib/gerry/api/accounts.rb
155
+ - lib/gerry/api/branches.rb
156
+ - lib/gerry/api/changes.rb
157
+ - lib/gerry/api/groups.rb
158
+ - lib/gerry/api/projects.rb
159
+ - lib/gerry/api/request.rb
138
160
  - lib/gerry/client.rb
139
- - lib/gerry/client/access.rb
140
- - lib/gerry/client/accounts.rb
141
- - lib/gerry/client/changes.rb
142
- - lib/gerry/client/groups.rb
143
- - lib/gerry/client/projects.rb
144
- - lib/gerry/client/request.rb
145
161
  - lib/gerry/version.rb
146
162
  - spec/access_spec.rb
147
163
  - spec/accounts_spec.rb
164
+ - spec/branches_spec.rb
148
165
  - spec/changes_spec.rb
166
+ - spec/fixtures/README.md.json
149
167
  - spec/fixtures/access_rights.json
150
168
  - spec/fixtures/account_groups.json
169
+ - spec/fixtures/branch_access.json
151
170
  - spec/fixtures/capabilities.json
152
171
  - spec/fixtures/changes.json
153
172
  - spec/fixtures/changes_batch_0.json
154
173
  - spec/fixtures/changes_batch_1.json
174
+ - spec/fixtures/changes_batch_2.json
155
175
  - spec/fixtures/group_members.json
156
176
  - spec/fixtures/groups.json
157
177
  - spec/fixtures/open_changes.json
178
+ - spec/fixtures/project_branch.json
179
+ - spec/fixtures/project_branches.json
158
180
  - spec/fixtures/project_head.json
159
181
  - spec/fixtures/projects.json
160
182
  - spec/fixtures/query_capabilities.json
@@ -181,27 +203,33 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
203
  version: '0'
182
204
  requirements: []
183
205
  rubyforge_project:
184
- rubygems_version: 2.2.2
206
+ rubygems_version: 2.6.13
185
207
  signing_key:
186
208
  specification_version: 4
187
209
  summary: Simple Ruby wrapper for the Gerrit Code Review REST-API.
188
210
  test_files:
189
- - spec/access_spec.rb
190
- - spec/accounts_spec.rb
211
+ - spec/spec_helper.rb
191
212
  - spec/changes_spec.rb
192
- - spec/fixtures/access_rights.json
213
+ - spec/branches_spec.rb
214
+ - spec/request_spec.rb
215
+ - spec/accounts_spec.rb
216
+ - spec/projects_spec.rb
193
217
  - spec/fixtures/account_groups.json
194
- - spec/fixtures/capabilities.json
195
- - spec/fixtures/changes.json
218
+ - spec/fixtures/project_head.json
219
+ - spec/fixtures/open_changes.json
220
+ - spec/fixtures/README.md.json
196
221
  - spec/fixtures/changes_batch_0.json
197
222
  - spec/fixtures/changes_batch_1.json
198
- - spec/fixtures/group_members.json
199
- - spec/fixtures/groups.json
200
- - spec/fixtures/open_changes.json
201
- - spec/fixtures/project_head.json
223
+ - spec/fixtures/capabilities.json
224
+ - spec/fixtures/branch_access.json
225
+ - spec/fixtures/project_branch.json
202
226
  - spec/fixtures/projects.json
227
+ - spec/fixtures/groups.json
203
228
  - spec/fixtures/query_capabilities.json
229
+ - spec/fixtures/changes.json
230
+ - spec/fixtures/changes_batch_2.json
231
+ - spec/fixtures/access_rights.json
232
+ - spec/fixtures/group_members.json
233
+ - spec/fixtures/project_branches.json
234
+ - spec/access_spec.rb
204
235
  - spec/groups_spec.rb
205
- - spec/projects_spec.rb
206
- - spec/request_spec.rb
207
- - spec/spec_helper.rb
@@ -1,20 +0,0 @@
1
- module Gerry
2
- class Client
3
- module Changes
4
- # Get changes visible to the caller.
5
- #
6
- # @param [Array] options the query parameters.
7
- # @return [Hash] the changes.
8
- def changes(options = [])
9
- url = '/changes/'
10
-
11
- if options.empty?
12
- return get(url)
13
- end
14
-
15
- options = map_options(options)
16
- get("#{url}?#{options}")
17
- end
18
- end
19
- end
20
- end
@@ -1,113 +0,0 @@
1
- require 'cgi'
2
-
3
- module Gerry
4
- class Client
5
- module Request
6
- # Get the mapped options.
7
- #
8
- # @param [Array] options the query parameters.
9
- # @return [String] the mapped options.
10
- def map_options(options)
11
- options.map{|v| "#{v}"}.join('&')
12
- end
13
-
14
- private
15
- class RequestError < StandardError
16
- end
17
-
18
- def get(url)
19
- orig_url = url
20
-
21
- # Get the original start parameter, if any.
22
- query = URI.parse(orig_url).query
23
- start = query ? CGI.parse(query)['S'].join.to_i : 0
24
-
25
- # Keep requesting data until there are no more changes.
26
- all_results = []
27
- loop do
28
- response = if @username && @password
29
- auth = { username: @username, password: @password }
30
- self.class.get("/a#{url}", digest_auth: auth)
31
- else
32
- self.class.get(url)
33
- end
34
-
35
- result = parse(response)
36
- return result unless result.is_a?(Array) && result.last.is_a?(Hash)
37
-
38
- all_results.concat(result)
39
- return all_results unless result.last.delete('_more_changes')
40
-
41
- # Append the start parameter to the URL, overriding any previous start parameter.
42
- url = orig_url + "#{query ? '&' : '?'}S=#{start + all_results.size}"
43
- end
44
-
45
- all_results
46
- end
47
-
48
- def put(url, body)
49
- if @username && @password
50
- auth = { username: @username, password: @password }
51
- response = self.class.put("/a#{url}",
52
- body: body.to_json,
53
- headers: { 'Content-Type' => 'application/json' },
54
- digest_auth: auth
55
- )
56
- parse(response)
57
- else
58
- response = self.class.put(url,
59
- body: body.to_json,
60
- headers: { 'Content-Type' => 'application/json' }
61
- )
62
- parse(response)
63
- end
64
- end
65
-
66
- def post(url, body)
67
- if @username && @password
68
- auth = { username: @username, password: @password }
69
- response = self.class.post("/a#{url}",
70
- body: body.to_json,
71
- headers: { 'Content-Type' => 'application/json' },
72
- digest_auth: auth
73
- )
74
- parse(response)
75
- else
76
- response = self.class.post(url,
77
- body: body.to_json,
78
- headers: { 'Content-Type' => 'application/json' }
79
- )
80
- parse(response)
81
- end
82
- end
83
-
84
- def parse(response)
85
- unless /2[0-9][0-9]/.match(response.code.to_s)
86
- raise_request_error(response)
87
- end
88
- if response.body
89
- source = remove_magic_prefix(response.body)
90
- if source.lines.count == 1 && !source.start_with?('{') && !source.start_with?('[')
91
- # Work around the JSON gem not being able to parse top-level values, see
92
- # https://github.com/flori/json/issues/206.
93
- source.gsub!(/^"|"$/, '')
94
- else
95
- JSON.parse(source)
96
- end
97
- else
98
- nil
99
- end
100
- end
101
-
102
- def raise_request_error(response)
103
- raise RequestError.new("There was a request error! Response was: #{response.message}")
104
- end
105
-
106
- def remove_magic_prefix(response_body)
107
- # We need to strip the magic prefix from the first line of the response, see
108
- # https://gerrit-review.googlesource.com/Documentation/rest-api.html#output.
109
- response_body.sub(/^\)\]\}'$/, '').strip!
110
- end
111
- end
112
- end
113
- end