marathon-api 0.9.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 +7 -0
- data/.cane +3 -0
- data/.gitignore +7 -0
- data/.simplecov +5 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +91 -0
- data/Rakefile +34 -0
- data/TESTING.md +49 -0
- data/fixtures/marathon_docker_sample.json +14 -0
- data/fixtures/marathon_docker_sample_2.json +14 -0
- data/fixtures/vcr/Marathon/_info/returns_the_info_hash.yml +30 -0
- data/fixtures/vcr/Marathon/_ping/ping/.yml +35 -0
- data/fixtures/vcr/Marathon_App/_changes/changes_the_app.yml +57 -0
- data/fixtures/vcr/Marathon_App/_changes/fails_with_stange_attributes.yml +32 -0
- data/fixtures/vcr/Marathon_App/_delete/deletes_the_app.yml +30 -0
- data/fixtures/vcr/Marathon_App/_delete/fails_deleting_not_existing_app.yml +30 -0
- data/fixtures/vcr/Marathon_App/_get/fails_getting_not_existing_app.yml +30 -0
- data/fixtures/vcr/Marathon_App/_get/gets_the_app.yml +30 -0
- data/fixtures/vcr/Marathon_App/_list/lists_apps.yml +32 -0
- data/fixtures/vcr/Marathon_App/_restart/fails_restarting_not_existing_app.yml +30 -0
- data/fixtures/vcr/Marathon_App/_start/fails_getting_not_existing_app.yml +30 -0
- data/fixtures/vcr/Marathon_App/_start/starts_the_app.yml +32 -0
- data/fixtures/vcr/Marathon_App/_tasks/has_tasks.yml +30 -0
- data/fixtures/vcr/Marathon_App/_version/gets_a_version.yml +61 -0
- data/fixtures/vcr/Marathon_App/_versions/gets_versions.yml +32 -0
- data/fixtures/vcr/Marathon_Deployment/_delete/deletes_deployments.yml +61 -0
- data/fixtures/vcr/Marathon_Deployment/_list/lists_deployments.yml +90 -0
- data/fixtures/vcr/Marathon_EventSubscriptions/_list/lists_callbacks.yml +30 -0
- data/fixtures/vcr/Marathon_EventSubscriptions/_register/registers_callback.yml +30 -0
- data/fixtures/vcr/Marathon_EventSubscriptions/_unregister/unregisters_callback.yml +30 -0
- data/fixtures/vcr/Marathon_Leader/_delete/delete/.yml +30 -0
- data/fixtures/vcr/Marathon_Leader/_get/get/.yml +30 -0
- data/fixtures/vcr/Marathon_Queue/_list/lists_queue.yml +33 -0
- data/fixtures/vcr/Marathon_Task/_delete/kills_a_tasks_of_an_app.yml +57 -0
- data/fixtures/vcr/Marathon_Task/_delete_all/kills_all_tasks_of_an_app.yml +30 -0
- data/fixtures/vcr/Marathon_Task/_get/gets_tasks_of_an_app.yml +30 -0
- data/fixtures/vcr/Marathon_Task/_list/lists_running_tasks.yml +30 -0
- data/fixtures/vcr/Marathon_Task/_list/lists_tasks.yml +30 -0
- data/lib/marathon.rb +65 -0
- data/lib/marathon/app.rb +200 -0
- data/lib/marathon/connection.rb +97 -0
- data/lib/marathon/deployment.rb +60 -0
- data/lib/marathon/error.rb +62 -0
- data/lib/marathon/event_subscriptions.rb +33 -0
- data/lib/marathon/leader.rb +19 -0
- data/lib/marathon/queue.rb +36 -0
- data/lib/marathon/task.rb +85 -0
- data/lib/marathon/util.rb +35 -0
- data/lib/marathon/version.rb +3 -0
- data/marathon-api.gemspec +31 -0
- data/spec/marathon/app_spec.rb +334 -0
- data/spec/marathon/connection_spec.rb +40 -0
- data/spec/marathon/deployment_spec.rb +95 -0
- data/spec/marathon/error_spec.rb +40 -0
- data/spec/marathon/event_subscriptions_spec.rb +37 -0
- data/spec/marathon/leader_spec.rb +21 -0
- data/spec/marathon/marathon_spec.rb +47 -0
- data/spec/marathon/queue_spec.rb +62 -0
- data/spec/marathon/task_spec.rb +100 -0
- data/spec/marathon/util_spec.rb +44 -0
- data/spec/spec_helper.rb +34 -0
- metadata +271 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
# This class represents a Marathon API Connection.
|
2
|
+
class Marathon::Connection
|
3
|
+
|
4
|
+
include Marathon::Error
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
headers(
|
8
|
+
'Content-Type' => 'application/json',
|
9
|
+
'Accept' => 'application/json',
|
10
|
+
'User-Agent' => "ub0r/Marathon-API #{Marathon::VERSION}"
|
11
|
+
)
|
12
|
+
|
13
|
+
default_timeout 5
|
14
|
+
maintain_method_across_redirects
|
15
|
+
|
16
|
+
attr_reader :url
|
17
|
+
|
18
|
+
# Create a new API connection.
|
19
|
+
# ++url++: URL of the marathon API.
|
20
|
+
def initialize(url)
|
21
|
+
@url = url
|
22
|
+
end
|
23
|
+
|
24
|
+
# Delegate all HTTP methods to the #request.
|
25
|
+
[:get, :put, :post, :delete].each do |method|
|
26
|
+
define_method(method) { |*args, &block| request(method, *args) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"Marathon::Connection { :url => #{url} }"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Create URL suffix for a hash of query parameters.
|
36
|
+
# URL escaping is done internally.
|
37
|
+
# ++query++: Hash of query parameters.
|
38
|
+
def query_params(query)
|
39
|
+
query = query.select { |k,v| !v.nil? }
|
40
|
+
URI.escape(query.map { |k,v| "#{k}=#{v}" }.join('&'))
|
41
|
+
end
|
42
|
+
|
43
|
+
# Create request object.
|
44
|
+
# ++http_method++: GET/POST/PUT/DELETE.
|
45
|
+
# ++path++: Relative path to connection's URL.
|
46
|
+
# ++query++: Optional query parameters.
|
47
|
+
# ++opts++: Optional options. Ex. opts[:body] is used for PUT/POST request.
|
48
|
+
def compile_request_params(http_method, path, query = nil, opts = nil)
|
49
|
+
query ||= {}
|
50
|
+
opts ||= {}
|
51
|
+
headers = opts.delete(:headers) || {}
|
52
|
+
opts[:body] = opts[:body].to_json unless opts[:body].nil?
|
53
|
+
{
|
54
|
+
:method => http_method,
|
55
|
+
:url => "#{@url}#{path}",
|
56
|
+
:query => query
|
57
|
+
}.merge(opts).reject { |_, v| v.nil? }
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create full URL with query parameters.
|
61
|
+
# ++url++: Base URL.
|
62
|
+
# ++query++: Hash of query parameters.
|
63
|
+
def build_url(url, query)
|
64
|
+
url = URI.escape(url)
|
65
|
+
if query.size > 0
|
66
|
+
url += '?' + query_params(query)
|
67
|
+
end
|
68
|
+
url
|
69
|
+
end
|
70
|
+
|
71
|
+
# Send a request to the server and parse response.
|
72
|
+
# ++http_method++: GET/POST/PUT/DELETE.
|
73
|
+
# ++path++: Relative path to connection's URL.
|
74
|
+
# ++query++: Optional query parameters.
|
75
|
+
# ++opts++: Optional options. Ex. opts[:body] is used for PUT/POST request.
|
76
|
+
def request(*args)
|
77
|
+
request = compile_request_params(*args)
|
78
|
+
url = build_url(request[:url], request[:query])
|
79
|
+
response = self.class.send(request[:method], url, request)
|
80
|
+
if response.success?
|
81
|
+
response.parsed_response
|
82
|
+
else
|
83
|
+
raise Marathon::Error.from_response(response)
|
84
|
+
end
|
85
|
+
rescue MarathonError => e
|
86
|
+
raise e
|
87
|
+
rescue SocketError => e
|
88
|
+
raise IOError, "HTTP call failed: #{e.message}"
|
89
|
+
rescue SystemCallError => e
|
90
|
+
if e.class.name.start_with?('Errno::')
|
91
|
+
raise IOError, "HTTP call failed: #{e.message}"
|
92
|
+
else
|
93
|
+
raise e
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# This class represents a Marathon Deployment.
|
2
|
+
# See https://mesosphere.github.io/marathon/docs/rest-api.html#deployments for full list of API's methods.
|
3
|
+
class Marathon::Deployment
|
4
|
+
|
5
|
+
attr_reader :info
|
6
|
+
|
7
|
+
# Create a new deployment object.
|
8
|
+
# ++hash++: Hash including all attributes.
|
9
|
+
# See https://mesosphere.github.io/marathon/docs/rest-api.html#get-/v2/deployments for full details.
|
10
|
+
def initialize(hash = {})
|
11
|
+
@info = hash
|
12
|
+
end
|
13
|
+
|
14
|
+
# Shortcuts for reaching attributes
|
15
|
+
%w[ id affectedApps steps currentActions version currentStep totalSteps ].each do |method|
|
16
|
+
define_method(method) { |*args, &block| info[method] }
|
17
|
+
end
|
18
|
+
|
19
|
+
# Cancel the deployment.
|
20
|
+
# ++force++: If set to false (the default) then the deployment is canceled and a new deployment
|
21
|
+
# is created to restore the previous configuration. If set to true, then the deployment
|
22
|
+
# is still canceled but no rollback deployment is created.
|
23
|
+
def delete(force = false)
|
24
|
+
self.class.delete(id, force)
|
25
|
+
end
|
26
|
+
alias :cancel :delete
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
"Marathon::Deployment { " \
|
30
|
+
+ ":id => #{id} :affectedApps => #{affectedApps} :currentStep => #{currentStep} :totalSteps => #{totalSteps} }"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return deployment as JSON formatted string.
|
34
|
+
def to_json
|
35
|
+
info.to_json
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
|
40
|
+
# List running deployments.
|
41
|
+
def list
|
42
|
+
json = Marathon.connection.get('/v2/deployments')
|
43
|
+
json.map { |j| new(j) }
|
44
|
+
end
|
45
|
+
|
46
|
+
# Cancel the deployment with id.
|
47
|
+
# ++id++: Deployment's id
|
48
|
+
# ++force++: If set to false (the default) then the deployment is canceled and a new deployment
|
49
|
+
# is created to restore the previous configuration. If set to true, then the deployment
|
50
|
+
# is still canceled but no rollback deployment is created.
|
51
|
+
def delete(id, force = false)
|
52
|
+
query = {}
|
53
|
+
query[:force] = true if force
|
54
|
+
json = Marathon.connection.delete("/v2/deployments/#{id}")
|
55
|
+
# TODO parse deploymentId + version
|
56
|
+
end
|
57
|
+
alias :cancel :delete
|
58
|
+
alias :remove :delete
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# This module holds the Errors for the gem.
|
2
|
+
module Marathon::Error
|
3
|
+
# The default error. It's never actually raised, but can be used to catch all
|
4
|
+
# gem-specific errors that are thrown as they all subclass from this.
|
5
|
+
class MarathonError < StandardError; end
|
6
|
+
|
7
|
+
# Raised when invalid arguments are passed to a method.
|
8
|
+
class ArgumentError < MarathonError; end
|
9
|
+
|
10
|
+
# Raised when a request returns a 400.
|
11
|
+
class ClientError < MarathonError; end
|
12
|
+
|
13
|
+
# Raised when a request returns a 404.
|
14
|
+
class NotFoundError < MarathonError; end
|
15
|
+
|
16
|
+
# Raised when there is an unexpected response code / body.
|
17
|
+
class UnexpectedResponseError < MarathonError; end
|
18
|
+
|
19
|
+
# Raised when a request times out.
|
20
|
+
class TimeoutError < MarathonError; end
|
21
|
+
|
22
|
+
# Raised when login fails.
|
23
|
+
class AuthenticationError < MarathonError; end
|
24
|
+
|
25
|
+
# Raised when an IO action fails.
|
26
|
+
class IOError < MarathonError; end
|
27
|
+
|
28
|
+
# Raise error specific to http response.
|
29
|
+
# ++response++: HTTParty response object.
|
30
|
+
def from_response(response)
|
31
|
+
error_class(response).new(error_message(response))
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Get reponse code specific error class.
|
37
|
+
# ++response++: HTTParty response object.
|
38
|
+
def error_class(response)
|
39
|
+
case response.code
|
40
|
+
when 400
|
41
|
+
ClientError
|
42
|
+
when 404
|
43
|
+
NotFoundError
|
44
|
+
else
|
45
|
+
UnexpectedResponseError
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get response code from http response.
|
50
|
+
# ++response++: HTTParty response object.
|
51
|
+
def error_message(response)
|
52
|
+
body = response.parsed_response
|
53
|
+
if body.is_a?(Hash)
|
54
|
+
body['message']
|
55
|
+
else
|
56
|
+
body
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module_function :error_class, :error_message, :from_response
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This class represents a Marathon Event Subscriptions.
|
2
|
+
# See https://mesosphere.github.io/marathon/docs/rest-api.html#event-subscriptions for full list of API's methods.
|
3
|
+
class Marathon::EventSubscriptions
|
4
|
+
|
5
|
+
class << self
|
6
|
+
# List all event subscriber callback URLs.
|
7
|
+
# Returns a list of strings/URLs.
|
8
|
+
def list
|
9
|
+
json = Marathon.connection.get('/v2/eventSubscriptions')
|
10
|
+
json['callbackUrls']
|
11
|
+
end
|
12
|
+
|
13
|
+
# Register a callback URL as an event subscriber.
|
14
|
+
# ++callbackUrl++: URL to which events should be posted.
|
15
|
+
# Returns an event as hash.
|
16
|
+
def register(callbackUrl)
|
17
|
+
query = {}
|
18
|
+
query[:callbackUrl] = callbackUrl
|
19
|
+
json = Marathon.connection.post('/v2/eventSubscriptions', query)
|
20
|
+
json
|
21
|
+
end
|
22
|
+
|
23
|
+
# Unregister a callback URL from the event subscribers list.
|
24
|
+
# ++callbackUrl++: URL passed when the event subscription was created.
|
25
|
+
# Returns an event as hash.
|
26
|
+
def unregister(callbackUrl)
|
27
|
+
query = {}
|
28
|
+
query[:callbackUrl] = callbackUrl
|
29
|
+
json = Marathon.connection.delete('/v2/eventSubscriptions', query)
|
30
|
+
json
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# This class represents a Marathon Leader.
|
2
|
+
# See https://mesosphere.github.io/marathon/docs/rest-api.html#get-/v2/leader for full list of API's methods.
|
3
|
+
class Marathon::Leader
|
4
|
+
|
5
|
+
class << self
|
6
|
+
# Returns the current leader. If no leader exists, raises NotFoundError.
|
7
|
+
def get
|
8
|
+
json = Marathon.connection.get('/v2/leader')
|
9
|
+
json['leader']
|
10
|
+
end
|
11
|
+
|
12
|
+
# Causes the current leader to abdicate, triggering a new election.
|
13
|
+
# If no leader exists, raises NotFoundError.
|
14
|
+
def delete
|
15
|
+
json = Marathon.connection.delete('/v2/leader')
|
16
|
+
json['message']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# This class represents a Marathon Queue element.
|
2
|
+
# See https://mesosphere.github.io/marathon/docs/rest-api.html#queue for full list of API's methods.
|
3
|
+
class Marathon::Queue
|
4
|
+
|
5
|
+
attr_reader :app
|
6
|
+
attr_reader :delay
|
7
|
+
|
8
|
+
# Create a new queue element object.
|
9
|
+
# ++hash++: Hash returned by API, including 'app' and 'delay'
|
10
|
+
def initialize(hash = {})
|
11
|
+
@app = Marathon::App.new(hash['app'], true)
|
12
|
+
@delay = hash['delay']
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
"Marathon::Queue { :appId => #{app.id} :delay => #{delay} }"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return queue element as JSON formatted string.
|
20
|
+
def to_json
|
21
|
+
{
|
22
|
+
'app' => @app.info,
|
23
|
+
'delay' => @delay
|
24
|
+
}.to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
|
29
|
+
# Show content of the task queue.
|
30
|
+
# Returns Array of Queue objects.
|
31
|
+
def list
|
32
|
+
json = Marathon.connection.get('/v2/queue')['queue']
|
33
|
+
json.map { |j| new(j) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# This class represents a Marathon Task.
|
2
|
+
# See https://mesosphere.github.io/marathon/docs/rest-api.html#get-/v2/tasks for full list of API's methods.
|
3
|
+
class Marathon::Task
|
4
|
+
|
5
|
+
attr_reader :info
|
6
|
+
|
7
|
+
# Create a new task object.
|
8
|
+
# ++hash++: Hash including all attributes
|
9
|
+
def initialize(hash = {})
|
10
|
+
@info = hash
|
11
|
+
end
|
12
|
+
|
13
|
+
# Shortcuts for reaching attributes
|
14
|
+
%w[ id appId host ports servicePorts version stagedAt startedAt ].each do |method|
|
15
|
+
define_method(method) { |*args, &block| info[method] }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Kill the task that belongs to an application.
|
19
|
+
# ++scale++: Scale the app down (i.e. decrement its instances setting by the number of tasks killed)
|
20
|
+
# after killing the specified tasks.
|
21
|
+
def delete!(scale = false)
|
22
|
+
new_task = self.class.delete(appId, id, scale)
|
23
|
+
@info = new_task.info
|
24
|
+
end
|
25
|
+
alias :kill! :delete!
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"Marathon::Task { :id => #{self.id} :appId => #{appId} :host => #{host} }"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return task as JSON formatted string.
|
32
|
+
def to_json
|
33
|
+
info.to_json
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
|
38
|
+
# List tasks of all applications.
|
39
|
+
# ++status++: Return only those tasks whose status matches this parameter.
|
40
|
+
# If not specified, all tasks are returned. Possible values: running, staging.
|
41
|
+
def list(status = nil)
|
42
|
+
query = {}
|
43
|
+
Marathon::Util.add_choice(query, :status, status, %w[running staging])
|
44
|
+
json = Marathon.connection.get('/v2/tasks', query)['tasks']
|
45
|
+
json.map { |j| new(j) }
|
46
|
+
end
|
47
|
+
|
48
|
+
# List all running tasks for application appId.
|
49
|
+
# ++appId++: Application's id
|
50
|
+
def get(appId)
|
51
|
+
json = Marathon.connection.get("/v2/apps/#{appId}/tasks")['tasks']
|
52
|
+
json.map { |j| new(j) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Kill the task that belongs to the application appId.
|
56
|
+
# ++appId++: Application's id
|
57
|
+
# ++id++: Id of target task.
|
58
|
+
# ++scale++: Scale the app down (i.e. decrement its instances setting by the number of tasks killed)
|
59
|
+
# after killing the specified tasks.
|
60
|
+
def delete(appId, id, scale = false)
|
61
|
+
query = {}
|
62
|
+
query[:scale] = true if scale
|
63
|
+
json = Marathon.connection.delete("/v2/apps/#{appId}/tasks/#{id}", query)
|
64
|
+
new(json)
|
65
|
+
end
|
66
|
+
alias :remove :delete
|
67
|
+
alias :kill :delete
|
68
|
+
|
69
|
+
# Kill tasks that belong to the application appId.
|
70
|
+
# ++appId++: Application's id
|
71
|
+
# ++host++: Kill only those tasks running on host host.
|
72
|
+
# ++scale++: Scale the app down (i.e. decrement its instances setting by the number of tasks killed)
|
73
|
+
# after killing the specified tasks.
|
74
|
+
def delete_all(appId, host = nil, scale = false)
|
75
|
+
query = {}
|
76
|
+
query[:host] = host if host
|
77
|
+
query[:scale] = true if scale
|
78
|
+
json = Marathon.connection.delete("/v2/apps/#{appId}/tasks", query)['tasks']
|
79
|
+
json.map { |j| new(j) }
|
80
|
+
end
|
81
|
+
alias :remove_all :delete_all
|
82
|
+
alias :kill_all :delete_all
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Some helper things.
|
2
|
+
class Marathon::Util
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# Checks if parameter is of allowed value.
|
6
|
+
# ++name++: parameter's name
|
7
|
+
# ++value++: parameter's value
|
8
|
+
# ++allowed++: array of allowd values
|
9
|
+
# ++nil_allowed++: allow nil values
|
10
|
+
def validate_choice(name, value, allowed, nil_allowed = true)
|
11
|
+
if value.nil?
|
12
|
+
unless nil_allowed
|
13
|
+
raise Marathon::Error::ArgumentError, "#{name} must not be nil"
|
14
|
+
end
|
15
|
+
else
|
16
|
+
# value is not nil
|
17
|
+
unless allowed.include?(value)
|
18
|
+
msg = nil_allowed ? "#{name} must be one of #{allowed}, or nil" : "#{name} must be one of #{allowed}"
|
19
|
+
raise Marathon::Error::ArgumentError, msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Check parameter and add it to hash if not nil.
|
25
|
+
# ++opts++: hash of parameters
|
26
|
+
# ++name++: parameter's name
|
27
|
+
# ++value++: parameter's value
|
28
|
+
# ++allowed++: array of allowd values
|
29
|
+
# ++nil_allowed++: allow nil values
|
30
|
+
def add_choice(opts, name, value, allowed, nil_allowed = true)
|
31
|
+
validate_choice(name, value, allowed, nil_allowed)
|
32
|
+
opts[name] = value if value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/marathon/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "marathon-api"
|
6
|
+
gem.version = Marathon::VERSION
|
7
|
+
gem.authors = ["Felix Bechstein"]
|
8
|
+
gem.email = %w{f@ub0r.de}
|
9
|
+
gem.description = %q{A simple REST client for the Marathon Remote API}
|
10
|
+
gem.summary = %q{A simple REST client for the Marathon Remote API}
|
11
|
+
gem.homepage = 'https://github.com/felixb/marathon-api'
|
12
|
+
gem.license = 'MIT'
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($\)
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = %w{lib}
|
18
|
+
|
19
|
+
gem.add_dependency 'json'
|
20
|
+
gem.add_dependency "httparty", ">= 0.11"
|
21
|
+
|
22
|
+
gem.add_development_dependency 'rake'
|
23
|
+
gem.add_development_dependency 'rspec', '~> 3.0'
|
24
|
+
gem.add_development_dependency 'rspec-its'
|
25
|
+
gem.add_development_dependency 'vcr', '>= 2.7.0'
|
26
|
+
gem.add_development_dependency 'webmock'
|
27
|
+
gem.add_development_dependency 'pry'
|
28
|
+
gem.add_development_dependency 'cane'
|
29
|
+
gem.add_development_dependency 'simplecov'
|
30
|
+
gem.add_development_dependency 'codeclimate-test-reporter'
|
31
|
+
end
|