travis-saucelabs-api 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9a020d8e584148b881c96d7060206d23d527886c
4
+ data.tar.gz: e8280c6e4bbdd885ed75f91ba220bd4ea784e605
5
+ SHA512:
6
+ metadata.gz: ec8900ed99b31da6d0a1d4f9708f74aeaca8b2e8032d86e78a7c2ab5f02c1dd774345a8c7cde179978dce23008a73d78e8177656375f89dafb79128819459182
7
+ data.tar.gz: 158a5a18df2bed7ef52197ad75b6b49400537e0ed0c031e82d62a0701080adc4cf072d4509015eec6a7edc2e0e7ad668057dc5eeacc2e548f7480bbe615d3d3b
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --order random
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - jruby-19mode
5
+
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+
5
+ group :test do
6
+ gem 'rspec'
7
+ gem 'webmock'
8
+ end
9
+
10
+ # Specify your gem's dependencies in travis-saucelabs-api.gemspec
11
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Henrik Hodne
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Travis::SaucelabsAPI
2
+
3
+ This is an API wrapper to the Travis<->Saucelabs API for Mac VMs
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'travis-saucelabs-api'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install travis-saucelabs-api
18
+
19
+ ## Usage
20
+
21
+ ``` ruby
22
+ require 'travis-saucelabs-api'
23
+
24
+ api = Travis::SaucelabsAPI.new('http://user:password@api.example.com:1234')
25
+
26
+ # The available capacity for the cloud
27
+ #
28
+ # ichef is the VM type
29
+ api.capacity # => { 'ichef' => 10 }
30
+
31
+ # Start up a VM instance
32
+ api.start_instance # => { 'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1' }
33
+
34
+ # Get a list of the running instances
35
+ api.list_instances # => { 'instances' => [ '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1' ]}
36
+
37
+ # Get information about an instance
38
+ api.instance_info('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1') # => {
39
+ # 'public_ip' => '10.10.10.10',
40
+ # 'vnc_port' => '5900',
41
+ # 'FQDN' => 'vm1.example.com',
42
+ # 'time_created' => 1355294100.609689,
43
+ # 'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1',
44
+ # 'image_id' => 'ichef-osx8-10.8-working',
45
+ # 'State' => 'Running',
46
+ # 'private_ip' => '10.10.20.10',
47
+ # 'real_image_id' => 'ichef-osx8-10.8-working',
48
+ # }
49
+
50
+ # Stop a VM instance (like unplugging its power)
51
+ api.kill_instance('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1')
52
+
53
+ # Open the firewall for a given VM instance to allow outgoing connections
54
+ # (firewalled off by default, watch out.)
55
+ api.open_outgoing('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1')
56
+
57
+ # Save a disk image from a running VM. Use this sparingly.
58
+ api.save_image('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1')
59
+ ```
60
+
61
+ ## Contributing
62
+
63
+ 1. Fork it
64
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
65
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
66
+ 4. Push to the branch (`git push origin my-new-feature`)
67
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: :spec
8
+
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env ruby
2
+ require 'thor'
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'travis-saucelabs-api'
5
+
6
+ class TravisSaucelabs < Thor
7
+ desc 'list', 'Print a list of the currently running instances'
8
+ def list
9
+ instances = api.list_instances['instances']
10
+ instances.each do |instance_id|
11
+ info = api.instance_info(instance_id)
12
+ puts "Instance ID: #{info['instance_id']}"
13
+ info.each do |key, value|
14
+ puts " #{key}: #{value}"
15
+ end
16
+ puts
17
+ end
18
+ end
19
+
20
+ desc 'start', 'Starts a new VM instance'
21
+ option :hostname
22
+ option :password
23
+ def start
24
+ instance_id = api.start_instance(startup_info)['instance_id']
25
+ puts "Started instance with ID #{instance_id}"
26
+ print "Allowing outgoing connections..."
27
+ api.allow_outgoing(instance_id)
28
+ puts "done"
29
+ end
30
+
31
+ desc 'kill INSTANCE_ID', 'Kills the instance with the given instance ID'
32
+ def kill(instance_id)
33
+ puts api.kill_instance(instance_id)['message']
34
+ end
35
+
36
+ desc 'kill_pid PID', 'Kills all instances belonging to a PID'
37
+ def kill_pid(pid)
38
+ instances = api.list_instances['instances'].select do |instance_id|
39
+ info = api.instance_info(instance_id)
40
+ info['extra_info'] &&
41
+ info['extra_info']['hostname'] &&
42
+ info['extra_info']['hostname'] =~ /^testing-saucelabs-mac-#{pid}/
43
+ end
44
+
45
+ instances.each do |instance_id|
46
+ kill(instance_id)
47
+ end
48
+ end
49
+
50
+ desc 'save_image INSTANCE_ID NAME', 'Saves an image of instance with name'
51
+ def save_image(instance_id, name)
52
+ puts api.save_image(instance_id, name)['message']
53
+ end
54
+
55
+ desc 'allow_incoming INSTANCE_ID CIDR PORT', 'Opens an incoming port in the firewall'
56
+ def allow_incoming(instance_id, cidr, port)
57
+ puts api.allow_incoming(instance_id, cidr, port)['message']
58
+ end
59
+
60
+ private
61
+
62
+ def api
63
+ @api ||= begin
64
+ unless ENV['TRAVIS_SAUCE_API_URI']
65
+ puts 'You need to set the TRAVIS_SAUCE_API_URI environment variable'
66
+ puts ' export TRAVIS_SAUCE_API_URI="http://user:password@api-endpoint:port"'
67
+ exit 1
68
+ end
69
+ Travis::SaucelabsAPI.new(ENV['TRAVIS_SAUCE_API_URI'])
70
+ end
71
+ end
72
+
73
+ def startup_info
74
+ if options[:hostname] || options[:password]
75
+ startup_info = {}
76
+ startup_info[:hostname] = options[:hostname] if options[:hostname]
77
+ startup_info[:password] = options[:password] if options[:password]
78
+ startup_info
79
+ else
80
+ nil
81
+ end
82
+ end
83
+ end
84
+
85
+ TravisSaucelabs.start
@@ -0,0 +1,83 @@
1
+ require 'travis-saucelabs-api/version'
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+
5
+ module Travis
6
+ class SaucelabsAPI
7
+ class NotFoundError < StandardError; end
8
+
9
+ DEFAULT_IMAGE = 'ichef-osx8-10.8-travis'
10
+
11
+ # Public: Initialize a new API client instance
12
+ #
13
+ # uri - The URI or String endpoint for the API. This should include the
14
+ # username and password used for authentication.
15
+ def initialize(uri)
16
+ @connection = Faraday.new(uri) do |connection|
17
+ connection.use FaradayMiddleware::EncodeJson
18
+ connection.use FaradayMiddleware::ParseJson, content_type: /\bjson$/
19
+ connection.adapter Faraday.default_adapter
20
+ end
21
+ end
22
+
23
+ def capacity
24
+ handle_response(@connection.get('/capacity'))
25
+ end
26
+
27
+ def start_instance(startup_info=nil, image=DEFAULT_IMAGE)
28
+ response = @connection.post('/instances', startup_info) do |request|
29
+ request.params.update(image: image)
30
+ end
31
+
32
+ handle_response(response)
33
+ end
34
+
35
+ def list_instances
36
+ handle_response(@connection.get('/instances'))
37
+ end
38
+
39
+ def instance_info(instance_id)
40
+ handle_response(@connection.get("/instances/#{uri_escape(instance_id)}"))
41
+ end
42
+
43
+ def kill_instance(instance_id)
44
+ instance_id = uri_escape(instance_id)
45
+ handle_response(@connection.delete("/instances/#{instance_id}"))
46
+ end
47
+
48
+ def allow_outgoing(instance_id)
49
+ instance_id = uri_escape(instance_id)
50
+ handle_response(@connection.post("/instances/#{instance_id}/allow_outgoing"))
51
+ end
52
+
53
+ def allow_incoming(instance_id, cidr, port)
54
+ instance_id = uri_escape(instance_id)
55
+ response = @connection.post("/instances/#{instance_id}/allow_incoming") do |request|
56
+ request.params.update(cidr: cidr, port: port)
57
+ end
58
+
59
+ handle_response(response)
60
+ end
61
+
62
+ def save_image(instance_id, name)
63
+ instance_id = uri_escape(instance_id)
64
+ response = @connection.post("/instances/#{instance_id}/save_image") do |request|
65
+ request.params.update(name: name)
66
+ end
67
+
68
+ handle_response(response)
69
+ end
70
+
71
+ private
72
+
73
+ def handle_response(response)
74
+ raise NotFoundError if response.status == 404
75
+
76
+ response.body
77
+ end
78
+
79
+ def uri_escape(str)
80
+ Faraday::Utils.escape(str)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,5 @@
1
+ module Travis
2
+ class SaucelabsAPI
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ {"message": "outgoing connections allowed"}
@@ -0,0 +1 @@
1
+ {"ichef": 3}
@@ -0,0 +1 @@
1
+ {"public_ip": "10.10.10.10", "vnc_port": "5900", "FQDN": "vm1.example.com", "time_created": 1355294100.609689, "instance_id": "38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1", "image_id": "ichef-osx8-10.8-working", "State": "Running", "private_ip": "10.10.20.10", "real_image_id": "ichef-osx8-10.8-working"}
@@ -0,0 +1 @@
1
+ {"instances": ["38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1"]}
@@ -0,0 +1 @@
1
+ {"message": "stopped '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1'"}
@@ -0,0 +1 @@
1
+ {"message": "in progress"}
@@ -0,0 +1 @@
1
+ {"instance_id": "38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1"}
@@ -0,0 +1,50 @@
1
+ require 'travis-saucelabs-api'
2
+ require 'rspec'
3
+ require 'webmock/rspec'
4
+
5
+ RSpec.configure do |rspec|
6
+ rspec.expect_with(:rspec) do |config|
7
+ config.syntax = :expect
8
+ end
9
+ end
10
+
11
+ def a_delete(endpoint, path)
12
+ a_request(:delete, endpoint + path)
13
+ end
14
+
15
+ def a_get(endpoint, path)
16
+ a_request(:get, endpoint + path)
17
+ end
18
+
19
+ def a_post(endpoint, path)
20
+ a_request(:post, endpoint + path)
21
+ end
22
+
23
+ def a_put(endpoint, path)
24
+ a_request(:put, endpoint + path)
25
+ end
26
+
27
+ def stub_delete(endpoint, path)
28
+ stub_request(:delete, endpoint + path)
29
+ end
30
+
31
+ def stub_get(endpoint, path)
32
+ stub_request(:get, endpoint + path)
33
+ end
34
+
35
+ def stub_post(endpoint, path)
36
+ stub_request(:post, endpoint + path)
37
+ end
38
+
39
+ def stub_put(endpoint, path)
40
+ stub_request(:put, endpoint + path)
41
+ end
42
+
43
+ def fixture_path
44
+ File.expand_path('../fixtures', __FILE__)
45
+ end
46
+
47
+ def fixture(file)
48
+ File.new(fixture_path + '/' + file)
49
+ end
50
+
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe Travis::SaucelabsAPI do
4
+ let(:endpoint) { 'http://user:password@travis-saucelabs.dev:1234' }
5
+ let(:api) { Travis::SaucelabsAPI.new(endpoint) }
6
+
7
+ describe '#capacity' do
8
+ before do
9
+ stub_get(endpoint, '/capacity').to_return(body: fixture('capacity.json'), headers: { content_type: 'text/html' })
10
+ end
11
+
12
+ it 'requests the correct resource' do
13
+ api.capacity
14
+ expect(a_get(endpoint, '/capacity')).to have_been_made
15
+ end
16
+
17
+ it 'returns the number of available VMs' do
18
+ expect(api.capacity).to eq({ 'ichef' => 3 })
19
+ end
20
+ end
21
+
22
+ describe '#start_instance' do
23
+ context 'with no parameters' do
24
+ before do
25
+ stub_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE }).to_return(body: fixture('start_instance.json'), headers: { content_type: 'text/html' })
26
+ end
27
+
28
+ it 'requests the correct resource' do
29
+ api.start_instance
30
+ expect(a_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE })).to have_been_made
31
+ end
32
+
33
+ it 'returns the instance ID' do
34
+ expect(api.start_instance).to eq({ 'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1' })
35
+ end
36
+ end
37
+
38
+ context 'with a different image' do
39
+ before do
40
+ stub_post(endpoint, '/instances').with(query: { image: 'custom-image' }).to_return(body: fixture('start_instance.json'), headers: { content_type: 'text/html' })
41
+ end
42
+
43
+ it 'requests the correct resource' do
44
+ api.start_instance(nil, 'custom-image')
45
+ expect(a_post(endpoint, '/instances').with(query: { image: 'custom-image' })).to have_been_made
46
+ end
47
+ end
48
+
49
+ context 'with startup info' do
50
+ before do
51
+ stub_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE }, body: { foo: 'bar' }).to_return(body: fixture('start_instance.json'), headers: { content_type: 'text/html' })
52
+ end
53
+
54
+ it 'requests the correct resource' do
55
+ api.start_instance({ foo: 'bar' }, Travis::SaucelabsAPI::DEFAULT_IMAGE)
56
+ expect(a_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE }, body: { foo: 'bar' })).to have_been_made
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#list_instances' do
62
+ before do
63
+ stub_get(endpoint, '/instances').to_return(body: fixture('instances.json'), content_type: 'text/html')
64
+ end
65
+
66
+ it 'requests the correct resource' do
67
+ api.list_instances
68
+ expect(a_get(endpoint, '/instances')).to have_been_made
69
+ end
70
+
71
+ it 'returns the running instances' do
72
+ expect(api.list_instances).to eq({ 'instances' => ['38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1'] })
73
+ end
74
+ end
75
+
76
+ describe '#instance_info' do
77
+ before do
78
+ stub_get(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252').to_return(body: fixture('instance_info.json'), content_type: 'text/html')
79
+ end
80
+
81
+ it 'requests the correct resource' do
82
+ api.instance_info('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')
83
+ expect(a_get(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252')).to have_been_made
84
+ end
85
+
86
+ it 'returns information about the instance' do
87
+ expect(api.instance_info('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')).to eq({
88
+ 'public_ip' => '10.10.10.10',
89
+ 'vnc_port' => '5900',
90
+ 'FQDN' => 'vm1.example.com',
91
+ 'time_created' => 1355294100.609689,
92
+ 'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1',
93
+ 'image_id' => 'ichef-osx8-10.8-working',
94
+ 'State' => 'Running',
95
+ 'private_ip' => '10.10.20.10',
96
+ 'real_image_id' => 'ichef-osx8-10.8-working',
97
+ })
98
+ end
99
+ end
100
+
101
+ describe '#kill_instance' do
102
+ before do
103
+ stub_delete(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252').to_return(body: fixture('kill_instance.json'), content_type: 'text/html')
104
+ end
105
+
106
+ it 'requests the correct resource' do
107
+ api.kill_instance('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')
108
+ expect(a_delete(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252')).to have_been_made
109
+ end
110
+ end
111
+
112
+ describe '#allow_outgoing' do
113
+ before do
114
+ stub_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/allow_outgoing').to_return(body: fixture('allow_outgoing.json'), content_type: 'text/html')
115
+ end
116
+
117
+ it 'requests the correct resource' do
118
+ api.allow_outgoing('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')
119
+ expect(a_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/allow_outgoing')).to have_been_made
120
+ end
121
+ end
122
+
123
+ describe '#save_image' do
124
+ before do
125
+ stub_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/save_image?name=foo').to_return(body: fixture('save_image.json'), content_type: 'text/html')
126
+ end
127
+
128
+ it 'requests the correct resource' do
129
+ api.save_image('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252', 'foo')
130
+ expect(a_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/save_image?name=foo')).to have_been_made
131
+ end
132
+ end
133
+
134
+
135
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'travis-saucelabs-api/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "travis-saucelabs-api"
8
+ gem.version = Travis::SaucelabsAPI::VERSION
9
+ gem.authors = ["Henrik Hodne"]
10
+ gem.email = ["me@henrikhodne.com"]
11
+ gem.description = %q{Ruby client library for the API Travis uses to spin up OS X VMs}
12
+ gem.summary = %q{Travis/Sauce Labs API client}
13
+ gem.homepage = 'https://github.com/henrikhodne/travis-saucelabs-api'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency('faraday', '~> 0.7')
21
+ gem.add_runtime_dependency('faraday_middleware', '~> 0.9')
22
+ gem.add_runtime_dependency('thor', '~> 0.14')
23
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: travis-saucelabs-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Henrik Hodne
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
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.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.14'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.14'
55
+ description: Ruby client library for the API Travis uses to spin up OS X VMs
56
+ email:
57
+ - me@henrikhodne.com
58
+ executables:
59
+ - travis-saucelabs
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - .rspec
65
+ - .travis.yml
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/travis-saucelabs
71
+ - lib/travis-saucelabs-api.rb
72
+ - lib/travis-saucelabs-api/version.rb
73
+ - spec/fixtures/allow_outgoing.json
74
+ - spec/fixtures/capacity.json
75
+ - spec/fixtures/instance_info.json
76
+ - spec/fixtures/instances.json
77
+ - spec/fixtures/kill_instance.json
78
+ - spec/fixtures/save_image.json
79
+ - spec/fixtures/start_instance.json
80
+ - spec/spec_helper.rb
81
+ - spec/travis-saucelabs-api_spec.rb
82
+ - travis-saucelabs-api.gemspec
83
+ homepage: https://github.com/henrikhodne/travis-saucelabs-api
84
+ licenses: []
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.0.3
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Travis/Sauce Labs API client
106
+ test_files:
107
+ - spec/fixtures/allow_outgoing.json
108
+ - spec/fixtures/capacity.json
109
+ - spec/fixtures/instance_info.json
110
+ - spec/fixtures/instances.json
111
+ - spec/fixtures/kill_instance.json
112
+ - spec/fixtures/save_image.json
113
+ - spec/fixtures/start_instance.json
114
+ - spec/spec_helper.rb
115
+ - spec/travis-saucelabs-api_spec.rb