quay 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .quay.yml
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ..gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Braintree
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.
@@ -0,0 +1,29 @@
1
+ # quay
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'quay
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install quay
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/pitluga/quay/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'quay'
4
+
5
+ Quay::CLI.start(ARGV)
@@ -0,0 +1,9 @@
1
+ require 'thor'
2
+ require 'docker'
3
+
4
+ require 'quay/cli'
5
+ require 'quay/config'
6
+ require 'quay/container'
7
+ require 'quay/env_lookup'
8
+ require 'quay/state'
9
+ require 'quay/version'
@@ -0,0 +1,98 @@
1
+ module Quay
2
+ class CLI < Thor
3
+ include Thor::Actions
4
+
5
+ class_option :config, type: :string
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ def self.exit_on_failure?
9
+ true
10
+ end
11
+
12
+ desc "version", "Prints version and exits"
13
+ def version
14
+ puts "Quay Version #{VERSION}"
15
+ end
16
+
17
+ desc "init [dir]", "create a new Quayfile"
18
+ def init(dir=nil)
19
+ target = dir ? File.join(dir, 'Quayfile') : 'Quayfile'
20
+ copy_file('Quayfile', target)
21
+ end
22
+
23
+ desc "tasks", "list available tasks"
24
+ def tasks
25
+ config = Quay::Config.eval_from_path(options[:config])
26
+ config.tasks.each do |name, _|
27
+ puts name
28
+ end
29
+ end
30
+
31
+ desc "run TASK", "runs the given task"
32
+ def run_task(name)
33
+ config = Quay::Config.eval_from_path(options[:config])
34
+ task = config.tasks[name]
35
+ raise Thor::Error.new("unknown task #{name.inspect}") if task.nil?
36
+
37
+ Array(task[:depends]).each do |dependency|
38
+ puts "starting #{dependency}"
39
+ Container.start(dependency, config.services[dependency])
40
+ end
41
+
42
+ container = Container.start(name, task)
43
+
44
+ puts "Started #{name} #{container.id[0...12]}"
45
+ container.attach do |stream, chunk|
46
+ puts "#{stream}: #{chunk}"
47
+ end
48
+
49
+ Array(task[:depends]).each do |dependency|
50
+ puts "stopping #{dependency}"
51
+ Container.stop(dependency, config.services[dependency])
52
+ end
53
+ end
54
+
55
+ desc "services", "lists available services"
56
+ def services
57
+ config = Quay::Config.eval_from_path(options[:config])
58
+ state = Quay::State.new
59
+ lines = config.services.keys.sort.map do |service|
60
+ id = state.containers[service]
61
+ if id
62
+ container = Docker::Container.get(id)
63
+ [service, container.id[0...12]]
64
+ else
65
+ [service, nil]
66
+ end
67
+ end
68
+ puts "DEPENDENCY CONTAINER_ID"
69
+ puts lines.map{|col| col.join(" ") }.join("\n")
70
+ end
71
+
72
+ desc "start SERVICE", "start a SERVICE"
73
+ def start(name)
74
+ config = Quay::Config.eval_from_path(options[:config])
75
+ service = config.services[name]
76
+
77
+ raise Thor::Error.new("unknown service #{name.inspect}") if service.nil?
78
+
79
+ container = Container.start(name, service)
80
+ puts "Started #{name} #{container.id[0...12]}"
81
+ end
82
+
83
+ desc "stop SERVICE", "stop a SERVICE"
84
+ def stop(name)
85
+ config = Quay::Config.eval_from_path(options[:config])
86
+ service = config.services[name]
87
+
88
+ raise Thor::Error.new("unknown service #{name.inspect}") if service.nil?
89
+
90
+ container = Container.stop(name, service)
91
+ if container.nil?
92
+ puts "Skipping #{name}"
93
+ else
94
+ puts "Stopped #{name} #{container.id[0...12]}"
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,29 @@
1
+ module Quay
2
+ class Config
3
+ def self.eval_from_path(path)
4
+ path ||= "Quayfile"
5
+ evaluate(File.read(path))
6
+ end
7
+
8
+ def self.evaluate(contents)
9
+ config = self.new
10
+ config.instance_eval(contents)
11
+ config
12
+ end
13
+
14
+ attr_reader :services, :tasks
15
+
16
+ def initialize
17
+ @services = {}
18
+ @tasks = {}
19
+ end
20
+
21
+ def service(name, options={})
22
+ @services[name] = options
23
+ end
24
+
25
+ def task(name, options={})
26
+ @tasks[name] = options
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,60 @@
1
+ module Quay
2
+ class Container
3
+ def self.ensure_image(image)
4
+ Docker::Image.get(image)
5
+ rescue Docker::Error::NotFoundError
6
+ Docker::Image.create('fromImage' => image)
7
+ end
8
+
9
+ def self.start(name, container_config)
10
+ state = Quay::State.new
11
+ env_lookup = Quay::EnvLookup.new(state)
12
+
13
+ env = container_config.fetch(:env, {}).map do |k,v|
14
+ if v =~ /^\$/
15
+ value = env_lookup.get(v)
16
+ "#{k}=#{value}"
17
+ else
18
+ "#{k}=#{v}"
19
+ end
20
+ end
21
+
22
+ volumes = container_config.fetch(:volumes, []).map do |host, container, mode|
23
+ [container, {}]
24
+ end
25
+
26
+ binds = container_config.fetch(:volumes, []).map do |*args|
27
+ args.join(":")
28
+ end
29
+
30
+ opts = {
31
+ 'Image' => container_config[:image],
32
+ 'Cmd' => container_config[:cmd],
33
+ 'WorkingDir' => container_config[:working_dir],
34
+ 'Volumes' => Hash[volumes],
35
+ 'Env' => env,
36
+ }
37
+ ensure_image(container_config[:image])
38
+ container = Docker::Container.create(opts)
39
+ container.start('Binds' => binds)
40
+
41
+ state.save_container(name, container.id)
42
+
43
+ container
44
+ end
45
+
46
+ def self.stop(name, dependency)
47
+ state = Quay::State.new
48
+ id = state.containers[name]
49
+
50
+ return if id.nil?
51
+
52
+ container = Docker::Container.get(id)
53
+ container.stop
54
+
55
+ state.remove_container(name)
56
+
57
+ container
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,18 @@
1
+ module Quay
2
+ class EnvLookup
3
+ def initialize(state)
4
+ @state = state
5
+ end
6
+
7
+ def get(value)
8
+ name, path = value.match(/\$(\w+):(.*)/).captures
9
+ id = @state.containers[name]
10
+ container = Docker::Container.get(id)
11
+ json = container.json
12
+
13
+ path.split("/").reduce(json) do |current, key|
14
+ current[key]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module Quay
2
+ class State
3
+ def initialize(file = ".quay.yml")
4
+ @file = file
5
+ end
6
+
7
+ def containers
8
+ _state["containers"]
9
+ end
10
+
11
+ def save_container(name, id)
12
+ containers[name] = id
13
+ _save
14
+ end
15
+
16
+ def remove_container(name)
17
+ containers.delete(name)
18
+ _save
19
+ end
20
+
21
+ def _state
22
+ _load if @state.nil?
23
+ @state
24
+ end
25
+
26
+ def _save
27
+ File.open(@file, "w") do |file|
28
+ YAML.dump(@state, file)
29
+ end
30
+ end
31
+
32
+ def _load
33
+ if File.exists?(@file)
34
+ @state = YAML.load_file(@file)
35
+ else
36
+ @state = {}
37
+ end
38
+ @state.default_proc = proc { |hash, key| hash[key] = {} }
39
+ @state
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,25 @@
1
+ # vim: ft=ruby:
2
+
3
+ service 'redis', image: 'orchardup/redis'
4
+ service 'memcache', image: 'jacksoncage/memcache'
5
+
6
+ task 'sayhi', image: 'ubuntu', cmd: ['/bin/echo', 'hello world']
7
+
8
+ task 'redis_info',
9
+ depends: 'redis',
10
+ image: 'orchardup/redis',
11
+ env: {
12
+ 'REDIS_HOST' => '$redis:NetworkSettings/IPAddress',
13
+ 'REDIS_PORT' => '6379'
14
+ },
15
+ cmd: ['/bin/bash', '-c', '/usr/bin/redis-cli -h $REDIS_HOST -p $REDIS_PORT info']
16
+
17
+ project_root = File.expand_path(File.dirname(__FILE__))
18
+
19
+ task 'ls_volume',
20
+ image: 'ubuntu',
21
+ volumes: [
22
+ [project_root, '/mnt', 'ro']
23
+ ],
24
+ working_dir: '/mnt',
25
+ cmd: ['/bin/ls']
@@ -0,0 +1,3 @@
1
+ module Quay
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'quay/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "quay"
8
+ spec.version = Quay::VERSION
9
+ spec.authors = ["Tony Pitluga"]
10
+ spec.email = ["tony.pitluga@gmail.com"]
11
+ spec.summary = %q{automating docker dev environments}
12
+ spec.description = %q{automation for docker dev environments}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "thor", "~> 0.18.1"
22
+ spec.add_dependency "docker-api", "~> 1.7.6"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "rake", "~> 10.1.1"
26
+ spec.add_development_dependency "rspec", "~> 2.14.1"
27
+ end
@@ -0,0 +1,24 @@
1
+ # vim: ft=ruby:
2
+ service 'redis', image: 'orchardup/redis'
3
+ service 'memcache', image: 'jacksoncage/memcache'
4
+
5
+ task 'sayhi', image: 'ubuntu', cmd: ['/bin/echo', 'hello world']
6
+
7
+ task 'redis_info',
8
+ depends: 'redis',
9
+ image: 'orchardup/redis',
10
+ env: {
11
+ 'REDIS_HOST' => '$redis:NetworkSettings/IPAddress',
12
+ 'REDIS_PORT' => '6379'
13
+ },
14
+ cmd: ['/bin/bash', '-c', '/usr/bin/redis-cli -h $REDIS_HOST -p $REDIS_PORT info']
15
+
16
+ project_root = File.expand_path(File.dirname(__FILE__))
17
+
18
+ task 'ls_volume',
19
+ image: 'ubuntu',
20
+ volumes: [
21
+ [project_root, '/mnt', 'ro']
22
+ ],
23
+ working_dir: '/mnt',
24
+ cmd: ['/bin/ls']
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quay::CLI, type: :cli do
4
+ describe "default config" do
5
+ it "looks in the working directory" do
6
+ Dir.chdir(File.dirname(EXAMPLE_FILE)) do
7
+ output = quay('services')
8
+ output.should match(/DEPENDENCY CONTAINER_ID/)
9
+ output.should match(/^memcache *$/)
10
+ output.should match(/^redis *$/)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe "version" do
16
+ it "prints the version and exits" do
17
+ quay("version").should match(/Quay Version [\d\.]+/)
18
+ end
19
+ end
20
+
21
+ describe "init" do
22
+ it "generates a Quayfile in the current dir" do
23
+ Dir.mktmpdir do |dir|
24
+ Dir.chdir(dir) do
25
+ File.exist?("Quayfile").should == false
26
+ quay("init")
27
+ File.exist?("Quayfile").should == true
28
+ end
29
+ end
30
+ end
31
+
32
+ it "generates a Quayfile in the given dir" do
33
+ Dir.mktmpdir do |dir|
34
+ File.exist?(File.join(dir, "Quayfile")).should == false
35
+ quay("init #{dir}")
36
+ File.exist?(File.join(dir, "Quayfile")).should == true
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "services" do
42
+ before(:each) do
43
+ quay("stop redis --config #{EXAMPLE_FILE}")
44
+ quay("stop memcache --config #{EXAMPLE_FILE}")
45
+ end
46
+
47
+ after(:each) do
48
+ quay("stop redis --config #{EXAMPLE_FILE}")
49
+ quay("stop memcache --config #{EXAMPLE_FILE}")
50
+ end
51
+
52
+ describe "start" do
53
+ it "starts the given dependency" do
54
+ quay("start redis --config #{EXAMPLE_FILE}").should match(/Started redis/)
55
+ end
56
+
57
+ it "returns an error if the name is unknown" do
58
+ quay("start unknown --config #{EXAMPLE_FILE}").should match(/unknown service "unknown"/)
59
+ $?.exitstatus.should == 1
60
+ end
61
+ end
62
+
63
+ describe "stop" do
64
+ it "stop the given dependency" do
65
+ quay("start redis --config #{EXAMPLE_FILE}").should match(/Started redis/)
66
+ quay("stop redis --config #{EXAMPLE_FILE}").should match(/Stopped redis/)
67
+ end
68
+
69
+ it "skips dependencies that are not running" do
70
+ quay("stop redis --config #{EXAMPLE_FILE}").should match(/Skipping redis/)
71
+ end
72
+
73
+ it "returns an error if the name is unknown" do
74
+ quay("stop unknown --config #{EXAMPLE_FILE}").should match(/unknown service "unknown"/)
75
+ $?.exitstatus.should == 1
76
+ end
77
+ end
78
+
79
+ describe "list" do
80
+ it "show the status of all dependencies" do
81
+ output = quay("services --config #{EXAMPLE_FILE}")
82
+ output.should match(/DEPENDENCY CONTAINER_ID/)
83
+ output.should match(/^memcache *$/)
84
+ output.should match(/^redis *$/)
85
+ end
86
+
87
+ it "shows the container id of a running container" do
88
+ quay("start redis --config #{EXAMPLE_FILE}").should match(/Started redis/)
89
+
90
+ output = quay("services --config #{EXAMPLE_FILE}")
91
+ output.should match(/DEPENDENCY CONTAINER_ID/)
92
+ output.should match(/^redis [a-z0-9]{12}*$/)
93
+ output.should match(/^memcache *$/)
94
+ end
95
+ end
96
+ end
97
+
98
+ describe 'list' do
99
+ it "lists the available tasks" do
100
+ output = quay("tasks --config #{EXAMPLE_FILE}")
101
+ output.should match(/sayhi/)
102
+ end
103
+ end
104
+
105
+ describe 'run' do
106
+ it "runs the specified task" do
107
+ output = quay("run sayhi --config #{EXAMPLE_FILE}")
108
+ output.should match(/hello world/)
109
+ end
110
+
111
+ it "can run a task with a dependency" do
112
+ output = quay("run redis_info --config #{EXAMPLE_FILE}")
113
+ output.should match(/used_memory/)
114
+ end
115
+
116
+ it "returns an error if the name is unknown" do
117
+ quay("run unknown --config #{EXAMPLE_FILE}").should match(/unknown task "unknown"/)
118
+ $?.exitstatus.should == 1
119
+ end
120
+
121
+ it "can mount a volume" do
122
+ quay("run ls_volume --config #{EXAMPLE_FILE}").should match(/quay.gemspec/)
123
+ end
124
+
125
+ it "will pull an image that doesn't exist" do
126
+ images = Docker::Image.search('ubuntu')
127
+ images.each(&:remove)
128
+ quay("run sayhi --config #{EXAMPLE_FILE}").should match(/hello world/)
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quay::Config do
4
+ describe ".evaluate" do
5
+ context "service" do
6
+ it "is an empty hash by default" do
7
+ config = Quay::Config.evaluate("")
8
+ config.services.should == {}
9
+ end
10
+
11
+ it "adds a dependency" do
12
+ config = Quay::Config.evaluate <<-EOS
13
+ service "foo", image: "bar"
14
+ EOS
15
+
16
+ config.services.has_key?("foo").should be_true
17
+ config.services["foo"].should == { image: "bar" }
18
+ end
19
+ end
20
+
21
+ context "task" do
22
+ it "is an empty hash by default" do
23
+ config = Quay::Config.evaluate("")
24
+ config.tasks.should == {}
25
+ end
26
+
27
+ it "defines a task" do
28
+ config = Quay::Config.evaluate <<-EOS
29
+ task "sayhi", image: "bar"
30
+ EOS
31
+
32
+ config.tasks.has_key?("sayhi").should be_true
33
+ config.tasks["sayhi"].should == { image: "bar" }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quay::State do
4
+ around(:each) do |spec|
5
+ tmpfile = Tempfile.new('quay')
6
+ @file = tmpfile.path
7
+ tmpfile.delete
8
+ spec.run
9
+ tmpfile.delete
10
+ end
11
+
12
+ describe "containers" do
13
+ it "is initially an empty hash" do
14
+ state = Quay::State.new(@file)
15
+ state.containers.should == {}
16
+ end
17
+
18
+ it "can save a container for later" do
19
+ state = Quay::State.new(@file)
20
+ state.save_container("foo", "bar")
21
+
22
+ state = Quay::State.new(@file)
23
+ state.containers.should == {"foo" => "bar"}
24
+ end
25
+
26
+ it "can remove a container" do
27
+ state = Quay::State.new(@file)
28
+ state.save_container("foo", "bar")
29
+ state.containers.should == {"foo" => "bar"}
30
+ state.remove_container("foo")
31
+
32
+ state = Quay::State.new(@file)
33
+ state.containers.should == {}
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require 'quay'
3
+ require 'support/cli_driver'
4
+
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.run_all_when_everything_filtered = true
8
+ config.filter_run :focus
9
+ config.order = 'random'
10
+
11
+ config.include CLIDriver, type: :cli
12
+ end
13
+
14
+ EXAMPLE_FILE = File.expand_path('../Quayfile', __FILE__)
@@ -0,0 +1,7 @@
1
+ module CLIDriver
2
+ def quay(args)
3
+ lib = File.expand_path('../../../lib', __FILE__)
4
+ bin = File.expand_path('../../../bin/quay', __FILE__)
5
+ %x[ruby -I #{lib} #{bin} #{args} 2>&1]
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quay
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tony Pitluga
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.18.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.18.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: docker-api
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.7.6
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.7.6
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.5'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 10.1.1
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 10.1.1
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.14.1
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.14.1
94
+ description: automation for docker dev environments
95
+ email:
96
+ - tony.pitluga@gmail.com
97
+ executables:
98
+ - quay
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - .gitignore
103
+ - .rspec
104
+ - Gemfile
105
+ - LICENSE.txt
106
+ - README.md
107
+ - Rakefile
108
+ - bin/quay
109
+ - lib/quay.rb
110
+ - lib/quay/cli.rb
111
+ - lib/quay/config.rb
112
+ - lib/quay/container.rb
113
+ - lib/quay/env_lookup.rb
114
+ - lib/quay/state.rb
115
+ - lib/quay/templates/Quayfile
116
+ - lib/quay/version.rb
117
+ - quay.gemspec
118
+ - spec/Quayfile
119
+ - spec/quay/cli_spec.rb
120
+ - spec/quay/config_spec.rb
121
+ - spec/quay/state_spec.rb
122
+ - spec/spec_helper.rb
123
+ - spec/support/cli_driver.rb
124
+ homepage: ''
125
+ licenses:
126
+ - MIT
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ! '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 1.8.23
146
+ signing_key:
147
+ specification_version: 3
148
+ summary: automating docker dev environments
149
+ test_files:
150
+ - spec/Quayfile
151
+ - spec/quay/cli_spec.rb
152
+ - spec/quay/config_spec.rb
153
+ - spec/quay/state_spec.rb
154
+ - spec/spec_helper.rb
155
+ - spec/support/cli_driver.rb