semaphore_client 2.3.1 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/semaphore_client.rb +7 -5
- data/lib/semaphore_client/api/config_file.rb +59 -81
- data/lib/semaphore_client/api/env_var.rb +59 -81
- data/lib/semaphore_client/api/org.rb +15 -27
- data/lib/semaphore_client/api/project.rb +42 -73
- data/lib/semaphore_client/api/shared_config.rb +81 -108
- data/lib/semaphore_client/api/team.rb +50 -85
- data/lib/semaphore_client/api/user.rb +34 -64
- data/lib/semaphore_client/exceptions.rb +34 -2
- data/lib/semaphore_client/http_client.rb +73 -53
- data/lib/semaphore_client/version.rb +1 -1
- data/semaphore_client.gemspec +3 -1
- metadata +21 -7
@@ -5,101 +5,71 @@ class SemaphoreClient
|
|
5
5
|
@http_client = http_client
|
6
6
|
end
|
7
7
|
|
8
|
-
def list_for_org(org_id, query = nil)
|
9
|
-
list_for_org!(org_id, query)
|
10
|
-
rescue SemaphoreClient::Exceptions::RequestFailed
|
11
|
-
end
|
12
8
|
|
13
|
-
def
|
14
|
-
|
15
|
-
rescue SemaphoreClient::Exceptions::
|
9
|
+
def list_for_org(org_id, params = nil, options = {})
|
10
|
+
list_for_org!(org_id, params, options)
|
11
|
+
rescue SemaphoreClient::Exceptions::ResponseError
|
16
12
|
end
|
17
13
|
|
18
|
-
def
|
19
|
-
|
20
|
-
rescue SemaphoreClient::Exceptions::RequestFailed
|
21
|
-
end
|
14
|
+
def list_for_org!(org_id, params = nil, options = {})
|
15
|
+
path = "/orgs/#{org_id}/users"
|
22
16
|
|
23
|
-
|
24
|
-
detach_from_team!(user_id, team_id)
|
25
|
-
rescue SemaphoreClient::Exceptions::RequestFailed
|
17
|
+
@http_client.get(path, params, options = {}).body.map { |e| SemaphoreClient::Model::User.load(e) }
|
26
18
|
end
|
27
19
|
|
28
|
-
def list_for_project(project_id, query = nil)
|
29
|
-
list_for_project!(project_id, query)
|
30
|
-
rescue SemaphoreClient::Exceptions::RequestFailed
|
31
|
-
end
|
32
20
|
|
33
|
-
def list_for_org!(org_id, query = nil)
|
34
|
-
query_string =
|
35
|
-
unless query.nil? || query.empty?
|
36
|
-
"?" + query.map { |key, value| "#{key}=#{value}" }.join("&")
|
37
|
-
end
|
38
21
|
|
39
|
-
|
40
|
-
|
41
|
-
|
22
|
+
def list_for_team(team_id, params = nil, options = {})
|
23
|
+
list_for_team!(team_id, params, options)
|
24
|
+
rescue SemaphoreClient::Exceptions::ResponseError
|
25
|
+
end
|
42
26
|
|
43
|
-
|
27
|
+
def list_for_team!(team_id, params = nil, options = {})
|
28
|
+
path = "/teams/#{team_id}/users"
|
44
29
|
|
45
|
-
|
46
|
-
SemaphoreClient::Model::User.load(entity)
|
47
|
-
end
|
30
|
+
@http_client.get(path, params, options = {}).body.map { |e| SemaphoreClient::Model::User.load(e) }
|
48
31
|
end
|
49
32
|
|
50
|
-
def list_for_team!(team_id, query = nil)
|
51
|
-
query_string =
|
52
|
-
unless query.nil? || query.empty?
|
53
|
-
"?" + query.map { |key, value| "#{key}=#{value}" }.join("&")
|
54
|
-
end
|
55
33
|
|
56
|
-
response = @http_client.get([:teams, team_id, :users, query_string].compact)
|
57
34
|
|
58
|
-
|
35
|
+
def attach_to_team(user_id, team_id, params = nil, options = {})
|
36
|
+
attach_to_team!(user_id, team_id, params, options)
|
37
|
+
rescue SemaphoreClient::Exceptions::ResponseError
|
38
|
+
end
|
59
39
|
|
60
|
-
|
40
|
+
def attach_to_team!(user_id, team_id, params = nil, options = {})
|
41
|
+
path = "/teams/#{team_id}/users/#{user_id}"
|
61
42
|
|
62
|
-
|
63
|
-
SemaphoreClient::Model::User.load(entity)
|
64
|
-
end
|
43
|
+
@http_client.post(path, params, options)
|
65
44
|
end
|
66
45
|
|
67
|
-
def attach_to_team!(user_id, team_id)
|
68
|
-
response = @http_client.post([:teams, team_id, :users, user_id])
|
69
46
|
|
70
|
-
|
47
|
+
|
48
|
+
def detach_from_team(user_id, team_id, params = nil, options = {})
|
49
|
+
detach_from_team!(user_id, team_id, params, options)
|
50
|
+
rescue SemaphoreClient::Exceptions::ResponseError
|
71
51
|
end
|
72
52
|
|
73
|
-
def detach_from_team!(user_id, team_id)
|
74
|
-
|
53
|
+
def detach_from_team!(user_id, team_id, params = nil, options = {})
|
54
|
+
path = "/teams/#{team_id}/users/#{user_id}"
|
75
55
|
|
76
|
-
|
56
|
+
@http_client.delete(path, params, options)
|
77
57
|
end
|
78
58
|
|
79
|
-
def list_for_project!(project_id, query = nil)
|
80
|
-
query_string =
|
81
|
-
unless query.nil? || query.empty?
|
82
|
-
"?" + query.map { |key, value| "#{key}=#{value}" }.join("&")
|
83
|
-
end
|
84
59
|
|
85
|
-
response = @http_client.get([:projects, project_id, :users, query_string].compact)
|
86
60
|
|
87
|
-
|
61
|
+
def list_for_project(project_id, params = nil, options = {})
|
62
|
+
list_for_project!(project_id, params, options)
|
63
|
+
rescue SemaphoreClient::Exceptions::ResponseError
|
64
|
+
end
|
88
65
|
|
89
|
-
|
66
|
+
def list_for_project!(project_id, params = nil, options = {})
|
67
|
+
path = "/projects/#{project_id}/users"
|
90
68
|
|
91
|
-
|
92
|
-
SemaphoreClient::Model::User.load(entity)
|
93
|
-
end
|
69
|
+
@http_client.get(path, params, options = {}).body.map { |e| SemaphoreClient::Model::User.load(e) }
|
94
70
|
end
|
95
71
|
|
96
|
-
private
|
97
72
|
|
98
|
-
def assert_response_status(response, expected_status)
|
99
|
-
return if response.status == expected_status
|
100
|
-
|
101
|
-
raise SemaphoreClient::Exceptions::RequestFailed, response.status
|
102
|
-
end
|
103
73
|
end
|
104
74
|
end
|
105
75
|
end
|
@@ -1,6 +1,38 @@
|
|
1
1
|
class SemaphoreClient
|
2
2
|
class Exceptions
|
3
|
-
class
|
4
|
-
|
3
|
+
class Base < StandardError; end
|
4
|
+
|
5
|
+
class AttributeNotAvailable < Base; end
|
6
|
+
|
7
|
+
class ResponseError < Base
|
8
|
+
attr_reader :env
|
9
|
+
|
10
|
+
def initialize(env)
|
11
|
+
@env = env
|
12
|
+
|
13
|
+
super(env[:message])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# 400
|
18
|
+
class BadRequest < ResponseError; end
|
19
|
+
|
20
|
+
# 401
|
21
|
+
class Unauthorized < ResponseError; end
|
22
|
+
|
23
|
+
# 404
|
24
|
+
class NotFound < ResponseError; end
|
25
|
+
|
26
|
+
# 405
|
27
|
+
class NotAllowed < ResponseError; end
|
28
|
+
|
29
|
+
# 409
|
30
|
+
class Conflict < ResponseError; end
|
31
|
+
|
32
|
+
# 422
|
33
|
+
class UnprocessableEntity < ResponseError; end
|
34
|
+
|
35
|
+
# 500+
|
36
|
+
class ServerError < ResponseError; end
|
5
37
|
end
|
6
38
|
end
|
@@ -1,87 +1,107 @@
|
|
1
1
|
class SemaphoreClient
|
2
|
+
|
2
3
|
class HttpClient
|
3
|
-
class RouteNotSupported < StandardError; end
|
4
4
|
|
5
|
-
|
5
|
+
class ResponseErrorMiddleware < Faraday::Middleware
|
6
|
+
def call(env)
|
7
|
+
@app.call(env).on_complete do |env|
|
8
|
+
case env[:status]
|
9
|
+
when 401
|
10
|
+
raise SemaphoreClient::Exceptions::Unauthorized, env
|
11
|
+
when 404
|
12
|
+
raise SemaphoreClient::Exceptions::NotFound, env
|
13
|
+
when 405
|
14
|
+
raise SemaphoreClient::Exceptions::NotAllowed, env
|
15
|
+
when 409
|
16
|
+
raise SemaphoreClient::Exceptions::Conflict, env
|
17
|
+
when 422
|
18
|
+
raise SemaphoreClient::Exceptions::UnprocessableEntity, env
|
19
|
+
when 400...500
|
20
|
+
raise SemaphoreClient::Exceptions::BadRequest, env
|
21
|
+
when 500...600
|
22
|
+
raise SemaphoreClient::Exceptions::ServerError, env
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(auth_token, api_url, api_version, verbose, logger, auto_paginate)
|
6
29
|
@auth_token = auth_token
|
7
30
|
@api_url = api_url
|
8
31
|
@api_version = api_version
|
9
32
|
@verbose = verbose
|
10
33
|
@logger = logger
|
34
|
+
@auto_paginate = auto_paginate
|
11
35
|
end
|
12
36
|
|
13
|
-
def get(
|
14
|
-
|
37
|
+
def get(path, params = nil, options = {})
|
38
|
+
api_call(:get, path, params, options)
|
39
|
+
end
|
15
40
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
41
|
+
def post(path, params = nil, options = {})
|
42
|
+
api_call(:post, path, params, options)
|
19
43
|
end
|
20
44
|
|
21
|
-
def
|
22
|
-
|
45
|
+
def patch(path, params = nil, options = {})
|
46
|
+
api_call(:patch, path, params, options)
|
47
|
+
end
|
23
48
|
|
24
|
-
|
25
|
-
|
26
|
-
connection.post(route, content)
|
27
|
-
end
|
28
|
-
else
|
29
|
-
trace("POST", route) do
|
30
|
-
connection.post(route)
|
31
|
-
end
|
32
|
-
end
|
49
|
+
def delete(path, params = nil, options = {})
|
50
|
+
api_call(:delete, path, params, options)
|
33
51
|
end
|
34
52
|
|
35
|
-
|
36
|
-
route = route(route_elements)
|
53
|
+
private
|
37
54
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
55
|
+
def api_call(method, path, params = nil, options = {})
|
56
|
+
response = connection.public_send(method, "/#{@api_version}/#{path}", params)
|
57
|
+
|
58
|
+
if auto_paginate?(options)
|
59
|
+
links = parse_links(response)
|
60
|
+
|
61
|
+
if links[:next]
|
62
|
+
# recursivly follow the :next link
|
63
|
+
next_response = api_call(method, links[:next], params, options)
|
64
|
+
|
65
|
+
# append the rest to the body of the original request
|
66
|
+
response.body.concat(next_response.body)
|
45
67
|
end
|
46
68
|
end
|
69
|
+
|
70
|
+
response
|
47
71
|
end
|
48
72
|
|
49
|
-
def
|
50
|
-
|
73
|
+
def auto_paginate?(options)
|
74
|
+
# first check the options, then the global settings
|
75
|
+
options.key?(:auto_paginate) ? options[:auto_paginate] : @auto_paginate
|
76
|
+
end
|
51
77
|
|
52
|
-
|
53
|
-
|
78
|
+
def parse_links(response)
|
79
|
+
links = ( response.headers["Link"] || "" ).split(', ').map do |link|
|
80
|
+
href, name = link.match(/<(.*?)>; rel="(\w+)"/).captures
|
81
|
+
|
82
|
+
[name.to_sym, href.gsub("#{@api_url}/v2", "")]
|
54
83
|
end
|
55
|
-
end
|
56
84
|
|
57
|
-
|
85
|
+
Hash[*links.flatten]
|
86
|
+
end
|
58
87
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
88
|
+
def connection
|
89
|
+
@connection ||= Faraday.new(:url => @api_url, :headers => headers) do |conn|
|
90
|
+
conn.request :json
|
91
|
+
conn.response :json
|
63
92
|
|
64
|
-
@
|
65
|
-
|
93
|
+
if @verbose
|
94
|
+
conn.response :logger, @logger, :headers => false, :bodies => true
|
95
|
+
end
|
66
96
|
|
67
|
-
|
68
|
-
@logger.info "#{id} #{response.status} duration: #{finished_at - started_at}s body: #{response.body}"
|
97
|
+
conn.use SemaphoreClient::HttpClient::ResponseErrorMiddleware
|
69
98
|
|
70
|
-
|
71
|
-
else
|
72
|
-
yield
|
99
|
+
conn.adapter Faraday.default_adapter
|
73
100
|
end
|
74
101
|
end
|
75
102
|
|
76
|
-
def
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
def connection
|
81
|
-
@connection ||= Faraday.new(
|
82
|
-
:url => @api_url,
|
83
|
-
:headers => { "Authorization" => "Token #{@auth_token}" }
|
84
|
-
)
|
103
|
+
def headers
|
104
|
+
{ "Authorization" => "Token #{@auth_token}" }
|
85
105
|
end
|
86
106
|
end
|
87
107
|
end
|
data/semaphore_client.gemspec
CHANGED
@@ -20,7 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_dependency "faraday"
|
23
|
+
spec.add_dependency "faraday", "~> 0.13.1"
|
24
|
+
spec.add_dependency "faraday_middleware", "~> 0.12.2"
|
25
|
+
|
24
26
|
spec.add_development_dependency "byebug"
|
25
27
|
spec.add_development_dependency "bundler", "~> 1.14"
|
26
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semaphore_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jovan Ivanović
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.13.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.13.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday_middleware
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.12.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.12.2
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: byebug
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
151
|
version: '0'
|
138
152
|
requirements: []
|
139
153
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.
|
154
|
+
rubygems_version: 2.6.13
|
141
155
|
signing_key:
|
142
156
|
specification_version: 4
|
143
157
|
summary: Client for Semaphore's API.
|