travis-saucelabs-api 0.0.2

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 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