dpl 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 93221bbb43d418a1d0813b28be7fe51b9831d1d1
4
+ data.tar.gz: 7fc3ba48af19a3915628e5b8b85b4094205ab7d4
5
+ SHA512:
6
+ metadata.gz: f349cd28f7099db9283274c761006b35278efda7db13494acdc191692ce7d61f1f2eca6dca00d52fa0c9d24cb3f2a33762c56a5632440da86ac6f7abd12c2827
7
+ data.tar.gz: a4fe2772182e3d1e45d8c282bafa2b31adf44ca1ad897bfe63fbcdefcd2008e8f749a8d7e360fe0ac674f4a83f2e852ea2290fefab05c319f626cd5e1e1f5676
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
- Gemfile.lock
1
+ Gemfile.lock
2
+ .coverage
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - jruby
8
+ - rbx
@@ -0,0 +1,11 @@
1
+ Deploy tool made for Continuous Deployment.
2
+
3
+ Usage:
4
+
5
+ dpl --provider=heroku --api-key=`heroku auth:token`
6
+
7
+ Supported providers:
8
+
9
+ * Heroku
10
+ * Engine Yard (experimental)
11
+ * dotCloud (experimental)
@@ -0,0 +1 @@
1
+ task(:default) { ruby '-S rspec' }
@@ -15,4 +15,8 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_path = 'lib'
17
17
  s.required_ruby_version = '>= 1.8.7'
18
+
19
+ s.add_development_dependency 'rspec'
20
+ s.add_development_dependency 'rake'
21
+ s.add_development_dependency 'simplecov'
18
22
  end
@@ -8,7 +8,7 @@ module DPL
8
8
  end
9
9
 
10
10
  OPTION_PATTERN = /\A--([a-z][a-z_\-]*)(?:=(.+))?\z/
11
- attr_accessor :options
11
+ attr_accessor :options, :fold_count
12
12
 
13
13
  def initialize(*args)
14
14
  options = {}
@@ -23,7 +23,8 @@ module DPL
23
23
  end
24
24
  end
25
25
 
26
- self.options = default_options.merge(options)
26
+ self.fold_count = 0
27
+ self.options = default_options.merge(options)
27
28
  end
28
29
 
29
30
  def run
@@ -33,6 +34,15 @@ module DPL
33
34
  options[:debug] ? raise(error) : die(error.message)
34
35
  end
35
36
 
37
+ def fold(message)
38
+ self.fold_count += 1
39
+ print "travis_fold:start:dpl.#{fold_count}\r" if options[:fold]
40
+ puts "\e[33m#{message}\e[0m"
41
+ yield
42
+ ensure
43
+ print "\ntravis_fold:end:dpl.#{fold_count}\r" if options[:fold]
44
+ end
45
+
36
46
  def default_options
37
47
  {
38
48
  :app => File.basename(Dir.pwd),
@@ -11,18 +11,27 @@ module DPL
11
11
 
12
12
  def self.new(context, options)
13
13
  return super if self < Provider
14
- name = super.option(:provider).to_s.downcase.gsub(/[^a-z]/, '')
15
- raise Error, 'could not find provider %p' % options[:provider] unless name = constants.detect { |c| c.to_s.downcase == name }
16
- const_get(name).new(context, options)
14
+
15
+ context.fold("Installing deploy dependencies") do
16
+ name = super.option(:provider).to_s.downcase.gsub(/[^a-z]/, '')
17
+ raise Error, 'could not find provider %p' % options[:provider] unless name = constants.detect { |c| c.to_s.downcase == name }
18
+ const_get(name).new(context, options)
19
+ end
20
+ end
21
+
22
+ def self.experimental(name)
23
+ puts "", "!!! #{name} support is experimental !!!", ""
17
24
  end
18
25
 
19
- def self.requires(name, version = "> 0")
26
+ def self.requires(name, options = {})
27
+ version = options[:version] || '> 0'
28
+ load = options[:load] || name
20
29
  gem(name, version)
21
30
  rescue LoadError
22
31
  system("gem install %s -v %p" % [name, version])
23
32
  Gem.clear_paths
24
33
  ensure
25
- require name
34
+ require load
26
35
  end
27
36
 
28
37
  def self.pip(name, command = name)
@@ -43,19 +52,21 @@ module DPL
43
52
  rm_rf ".dpl"
44
53
  mkdir_p ".dpl"
45
54
 
46
- check_auth
47
- check_app
55
+ context.fold("Preparing deploy") do
56
+ check_auth
57
+ check_app
48
58
 
49
- if needs_key?
50
- create_key(".dpl/id_rsa")
51
- setup_key(".dpl/id_rsa.pub")
52
- setup_git_ssh(".dpl/git-ssh", ".dpl/id_rsa")
59
+ if needs_key?
60
+ create_key(".dpl/id_rsa")
61
+ setup_key(".dpl/id_rsa.pub")
62
+ setup_git_ssh(".dpl/git-ssh", ".dpl/id_rsa")
63
+ end
53
64
  end
54
65
 
55
- push_app
66
+ context.fold("Deploying application") { push_app }
56
67
 
57
68
  Array(options[:run]).each do |command|
58
- run(command)
69
+ context.fold("Running %p" % command) { run(command) }
59
70
  end
60
71
  ensure
61
72
  remove_key if needs_key?
@@ -1,12 +1,17 @@
1
1
  module DPL
2
2
  class Provider
3
3
  class DotCloud < Provider
4
+ experimental "dotCloud"
4
5
  pip 'dotcloud'
5
6
 
6
7
  def check_auth
7
8
  system "echo #{option(:api_key)} | dotcloud setup --api-key"
8
9
  end
9
10
 
11
+ def check_app
12
+ `dotcloud connect #{option(:app)}`
13
+ end
14
+
10
15
  def needs_key?
11
16
  false
12
17
  end
@@ -16,7 +21,7 @@ module DPL
16
21
  end
17
22
 
18
23
  def run(command)
19
- service = option[:instance] || option[:service] || 'www'
24
+ service = options[:instance] || options[:service] || 'www'
20
25
  `dotcloud -A #{option(:app)} #{service} #{command}`
21
26
  end
22
27
  end
@@ -1,6 +1,8 @@
1
1
  module DPL
2
2
  class Provider
3
3
  class EngineYard < Provider
4
+ experimental "Engine Yard"
5
+
4
6
  requires 'engineyard'
5
7
  requires 'engineyard-cloud-client'
6
8
 
@@ -1,48 +1,16 @@
1
1
  module DPL
2
2
  class Provider
3
- class Heroku < Provider
4
- requires 'heroku-api'
5
- requires 'rendezvous'
3
+ module Heroku
4
+ autoload :Anvil, 'dpl/provider/heroku/anvil'
5
+ autoload :Git, 'dpl/provider/heroku/git'
6
6
 
7
- def api
8
- @api ||= ::Heroku::API.new(:api_key => option(:api_key)) unless options[:user] and options[:password]
9
- @api ||= ::Heroku::API.new(:user => options[:user], :password => options[:password])
10
- end
11
-
12
- def check_auth
13
- log "authenticated as %s" % api.get_user.body["email"]
14
- end
15
-
16
- def check_app
17
- info = api.get_app(option(:app)).body
18
- options[:git] ||= info['git_url']
19
- log "found app #{info['name']}"
20
- end
21
-
22
- def setup_key(file)
23
- api.post_key File.read(file)
24
- end
25
-
26
- def remove_key
27
- api.delete_key(option(:key_name))
28
- end
29
-
30
- def push_app
31
- system "git push #{option(:git)} HEAD:master -f"
32
- end
33
-
34
- def run(command)
35
- data = api.post_ps(option(:app), command, :attach => true).body
36
- rendezvous_url = data['rendezvous_url']
37
- Rendezvous.start(:url => rendezvous_url) unless rendezvous_url.nil?
38
- end
7
+ extend self
39
8
 
40
- def deploy
41
- super
42
- rescue ::Heroku::API::Errors::NotFound=> error
43
- raise Error, "#{error.message} (wrong app #{options[:app].inspect}?)", error.backtrace
44
- rescue ::Heroku::API::Errors::Unauthorized => error
45
- raise Error, "#{error.message} (wrong API key?)", error.backtrace
9
+ def new(context, options)
10
+ strategy = options[:strategy] || 'anvil'
11
+ constant = constants.detect { |c| c.to_s.downcase == strategy }
12
+ raise Error, 'unknown strategy %p' % strategy unless constant
13
+ const_get(constant).new(context, options)
46
14
  end
47
15
  end
48
16
  end
@@ -0,0 +1,49 @@
1
+ module DPL
2
+ class Provider
3
+ module Heroku
4
+ class Anvil < Git
5
+ requires 'anvil-cli', :load => 'anvil/engine'
6
+ requires 'excon' # comes with heroku
7
+ requires 'json'
8
+
9
+ def api
10
+ raise Error, 'anvil deploy strategy only works with api_key' unless options[:api_key]
11
+ super
12
+ end
13
+
14
+ def needs_key?
15
+ false
16
+ end
17
+
18
+ def push_app
19
+ response = Excon.post release_url,
20
+ :body => { "slug_url" => slug_url, "description" => "Travis CI deploy" }.to_json,
21
+ :headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json' }
22
+
23
+ print "\nDeploying slug "
24
+ while response.status == 202
25
+ location = response.headers['Location']
26
+ response = Excon.get("https://:#{option(:api_key)}@cisaurus.heroku.com#{location}")
27
+ sleep(1)
28
+ print '.'
29
+ end
30
+
31
+ puts
32
+ raise Error, 'deploy failed' unless response.status == 200
33
+ end
34
+
35
+ def slug_url
36
+ @slug_url ||= begin
37
+ ::Anvil.headers["X-Heroku-User"] = user
38
+ ::Anvil.headers["X-Heroku-App"] = option(:app)
39
+ ::Anvil::Engine.build "."
40
+ end
41
+ end
42
+
43
+ def release_url
44
+ "https://:#{option(:api_key)}@cisaurus.heroku.com/v1/apps/#{option(:app)}/release"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,55 @@
1
+ module DPL
2
+ class Provider
3
+ module Heroku
4
+ class Git < Provider
5
+ requires 'heroku-api'
6
+ requires 'rendezvous'
7
+
8
+ def api
9
+ @api ||= ::Heroku::API.new(:api_key => option(:api_key)) unless options[:user] and options[:password]
10
+ @api ||= ::Heroku::API.new(:user => options[:user], :password => options[:password])
11
+ end
12
+
13
+ def user
14
+ @user ||= api.get_user.body["email"]
15
+ end
16
+
17
+ def check_auth
18
+ log "authenticated as %s" % user
19
+ end
20
+
21
+ def check_app
22
+ info = api.get_app(option(:app)).body
23
+ options[:git] ||= info['git_url']
24
+ log "found app #{info['name']}"
25
+ end
26
+
27
+ def setup_key(file)
28
+ api.post_key File.read(file)
29
+ end
30
+
31
+ def remove_key
32
+ api.delete_key(option(:key_name))
33
+ end
34
+
35
+ def push_app
36
+ system "git push #{option(:git)} HEAD:master -f"
37
+ end
38
+
39
+ def run(command)
40
+ data = api.post_ps(option(:app), command, :attach => true).body
41
+ rendezvous_url = data['rendezvous_url']
42
+ Rendezvous.start(:url => rendezvous_url) unless rendezvous_url.nil?
43
+ end
44
+
45
+ def deploy
46
+ super
47
+ rescue ::Heroku::API::Errors::NotFound => error
48
+ raise Error, "#{error.message} (wrong app #{options[:app].inspect}?)", error.backtrace
49
+ rescue ::Heroku::API::Errors::Unauthorized => error
50
+ raise Error, "#{error.message} (wrong API key?)", error.backtrace
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,3 +1,3 @@
1
1
  module DPL
2
- VERSION = '0.2.0'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -0,0 +1,8 @@
1
+ Destroy and redeploy a service:
2
+
3
+ ```
4
+ dotcloud destroy -A <appname> <stateless service>
5
+ dotcloud deploy latest
6
+ ```
7
+
8
+ https://dotcloud.zendesk.com/requests/23637
@@ -0,0 +1 @@
1
+ EY has a a special deploy app. Get in touch with Kevin Holler if we don't hear back from them.
@@ -0,0 +1,3 @@
1
+ Heroku might send out emails for new deploy keys (doesn't do it for me, but for some others).
2
+
3
+ Alternative is Anvil, but it's not perfect, as it duplicates a lot of Heroku logic internally (and failed for me in one case).
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'dpl/cli'
3
+
4
+ describe DPL::CLI do
5
+ describe :options do
6
+ example { described_class.new.options[:app] .should be == File.basename(Dir.pwd) }
7
+ example { described_class.new(:app => 'foo') .options[:app].should be == 'foo' }
8
+ example { described_class.new("--app=foo") .options[:app].should be == 'foo' }
9
+ example { described_class.new("--app") .options[:app].should be == true }
10
+ example { described_class.new("--app=foo", "--app=bar") .options[:app].should be == ['foo', 'bar'] }
11
+
12
+ example "error handling" do
13
+ $stderr.should_receive(:puts).with('invalid option "app"')
14
+ expect { described_class.new("app") }.to raise_error(SystemExit)
15
+ end
16
+ end
17
+
18
+ describe :run do
19
+ example "triggers deploy" do
20
+ provider = stub('provider')
21
+ DPL::Provider.should_receive(:new).and_return(provider)
22
+ provider.should_receive(:deploy)
23
+
24
+ described_class.run("--provider=foo")
25
+ end
26
+
27
+ example "error handling" do
28
+ $stderr.should_receive(:puts).with('missing provider')
29
+ expect { described_class.run }.to raise_error(SystemExit)
30
+ end
31
+
32
+ example "error handling in debug mode" do
33
+ expect { described_class.run("--debug") }.to raise_error(DPL::Error, 'missing provider')
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+ require 'heroku-api'
3
+ require 'dpl/provider/heroku'
4
+
5
+ describe DPL::Provider::Heroku do
6
+ subject :provider do
7
+ described_class.new(nil, :app => 'example', :key_name => 'key', :api_key => "foo", :strategy => "git")
8
+ end
9
+
10
+ describe :api do
11
+ it 'accepts an api key' do
12
+ api = stub(:api)
13
+ ::Heroku::API.should_receive(:new).with(:api_key => "foo").and_return(api)
14
+ provider.api.should be == api
15
+ end
16
+
17
+ it 'accepts a user and a password' do
18
+ api = stub(:api)
19
+ provider.options.update(:user => "foo", :password => "bar")
20
+ ::Heroku::API.should_receive(:new).with(:user => "foo", :password => "bar").and_return(api)
21
+ provider.api.should be == api
22
+ end
23
+ end
24
+
25
+ context "with fake api" do
26
+ let :api do
27
+ stub "api",
28
+ :get_user => stub("get_user", :body => { "email" => "foo@bar.com" }),
29
+ :get_app => stub("get_app", :body => { "name" => "example", "git_url" => "GIT URL" })
30
+ end
31
+
32
+ before do
33
+ ::Heroku::API.should_receive(:new).and_return(api)
34
+ provider.api
35
+ end
36
+
37
+ its(:api) { should be == api }
38
+
39
+ describe :check_auth do
40
+ example do
41
+ provider.should_receive(:log).with("authenticated as foo@bar.com")
42
+ provider.check_auth
43
+ end
44
+ end
45
+
46
+ describe :check_app do
47
+ example do
48
+ provider.should_receive(:log).with("found app example")
49
+ provider.check_app
50
+ provider.options[:git].should be == "GIT URL"
51
+ end
52
+ end
53
+
54
+ describe :setup_key do
55
+ example do
56
+ File.should_receive(:read).with("the file").and_return("foo")
57
+ api.should_receive(:post_key).with("foo")
58
+ provider.setup_key("the file")
59
+ end
60
+ end
61
+
62
+ describe :remove_key do
63
+ example do
64
+ api.should_receive(:delete_key).with("key")
65
+ provider.remove_key
66
+ end
67
+ end
68
+
69
+ describe :push_app do
70
+ example do
71
+ provider.options[:git] = "git://something"
72
+ provider.should_receive(:system).with("git push git://something HEAD:master -f")
73
+ provider.push_app
74
+ end
75
+ end
76
+
77
+ describe :run do
78
+ example do
79
+ data = stub("data", :body => { "rendezvous_url" => "rendezvous url" })
80
+ api.should_receive(:post_ps).with("example", "that command", :attach => true).and_return(data)
81
+ Rendezvous.should_receive(:start).with(:url => "rendezvous url")
82
+ provider.run("that command")
83
+ end
84
+ end
85
+
86
+ describe :deploy do
87
+ example "not found error" do
88
+ provider.should_receive(:api) { raise ::Heroku::API::Errors::NotFound.new("the message", nil) }.at_least(:once)
89
+ expect { provider.deploy }.to raise_error(DPL::Error, 'the message (wrong app "example"?)')
90
+ end
91
+
92
+ example "unauthorized error" do
93
+ provider.should_receive(:api) { raise ::Heroku::API::Errors::Unauthorized.new("the message", nil) }.at_least(:once)
94
+ expect { provider.deploy }.to raise_error(DPL::Error, 'the message (wrong API key?)')
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ require 'dpl/provider'
3
+
4
+ describe DPL::Provider do
5
+ let(:example_provider) { Class.new(described_class)}
6
+ subject(:provider) { example_provider.new(nil, :app => 'example', :key_name => 'foo', :run => ["foo", "bar"]) }
7
+
8
+ before { described_class.const_set(:Example, example_provider) }
9
+ after { described_class.send(:remove_const, :Example) }
10
+
11
+ describe :new do
12
+ example { described_class.new(nil, :provider => "example") .should be_an(example_provider) }
13
+ example { described_class.new(nil, :provider => "Example") .should be_an(example_provider) }
14
+ example { described_class.new(nil, :provider => "exa_mple").should be_an(example_provider) }
15
+ example { described_class.new(nil, :provider => "exa-mple").should be_an(example_provider) }
16
+ end
17
+
18
+ describe :requires do
19
+ before do
20
+ example_provider.should_receive(:require).with("foo")
21
+ end
22
+
23
+ example "installed" do
24
+ example_provider.should_receive(:gem).with("foo", "~> 1.4")
25
+ example_provider.requires("foo", :version => "~> 1.4")
26
+ end
27
+
28
+ example "missing" do
29
+ example_provider.should_receive(:gem).with("foo", "~> 1.4").and_raise(LoadError)
30
+ example_provider.should_receive(:system).with('gem install foo -v "~> 1.4"')
31
+ example_provider.requires("foo", :version => "~> 1.4")
32
+ end
33
+ end
34
+
35
+ describe :pip do
36
+ example "installed" do
37
+ example_provider.should_receive(:`).with("which foo").and_return("/bin/foo\n")
38
+ example_provider.should_not_receive(:system)
39
+ example_provider.pip("foo")
40
+ end
41
+
42
+ example "missing" do
43
+ example_provider.should_receive(:`).with("which foo").and_return("")
44
+ example_provider.should_receive(:system).with("pip install foo")
45
+ example_provider.pip("foo")
46
+ end
47
+ end
48
+
49
+ describe :deploy do
50
+ before do
51
+ provider.should_receive(:check_auth)
52
+ provider.should_receive(:check_app)
53
+ provider.should_receive(:push_app)
54
+ provider.should_receive(:run).with("foo")
55
+ provider.should_receive(:run).with("bar")
56
+ end
57
+
58
+ example "needs key" do
59
+ provider.should_receive(:remove_key)
60
+ provider.should_receive(:create_key)
61
+ provider.should_receive(:setup_key)
62
+ provider.should_receive(:setup_git_ssh)
63
+ provider.deploy
64
+ end
65
+
66
+ example "does not need key" do
67
+ provider.stub(:needs_key?, false)
68
+ provider.deploy
69
+ end
70
+ end
71
+
72
+ describe :create_key do
73
+ example do
74
+ provider.should_receive(:system).with('ssh-keygen -t rsa -N "" -C foo -f thekey')
75
+ provider.create_key('thekey')
76
+ end
77
+ end
78
+
79
+ describe :setup_git_ssh do
80
+ after { FileUtils.rm ENV.delete('GIT_SSH') }
81
+
82
+ example do
83
+ provider.setup_git_ssh('foo', 'bar')
84
+ ENV['GIT_SSH'].should be == File.expand_path('foo')
85
+ end
86
+ end
87
+
88
+ describe :log do
89
+ example do
90
+ $stderr.should_receive(:puts).with("foo")
91
+ provider.log("foo")
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,8 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start do
4
+ coverage_dir '.coverage'
5
+
6
+ add_filter "/spec/"
7
+ add_group 'Library', 'lib'
8
+ end
metadata CHANGED
@@ -1,16 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dpl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Konstantin Haase
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-03 00:00:00.000000000 Z
13
- dependencies: []
11
+ date: 2013-07-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
14
55
  description: deploy tool abstraction for clients
15
56
  email: konstantin.mailinglists@googlemail.com
16
57
  executables:
@@ -20,7 +61,10 @@ extra_rdoc_files: []
20
61
  files:
21
62
  - .gitignore
22
63
  - .rspec
64
+ - .travis.yml
23
65
  - Gemfile
66
+ - README.md
67
+ - Rakefile
24
68
  - bin/dpl
25
69
  - dpl.gemspec
26
70
  - lib/dpl/cli.rb
@@ -29,31 +73,43 @@ files:
29
73
  - lib/dpl/provider/dot_cloud.rb
30
74
  - lib/dpl/provider/engine_yard.rb
31
75
  - lib/dpl/provider/heroku.rb
76
+ - lib/dpl/provider/heroku/anvil.rb
77
+ - lib/dpl/provider/heroku/git.rb
32
78
  - lib/dpl/version.rb
79
+ - notes/dotcloud.md
80
+ - notes/engine_yard.md
81
+ - notes/heroku.md
82
+ - spec/cli_spec.rb
83
+ - spec/provider/heroku_spec.rb
84
+ - spec/provider_spec.rb
85
+ - spec/spec_helper.rb
33
86
  homepage: https://github.com/rkh/dpl
34
87
  licenses:
35
88
  - MIT
89
+ metadata: {}
36
90
  post_install_message:
37
91
  rdoc_options: []
38
92
  require_paths:
39
93
  - lib
40
94
  required_ruby_version: !ruby/object:Gem::Requirement
41
- none: false
42
95
  requirements:
43
- - - ! '>='
96
+ - - '>='
44
97
  - !ruby/object:Gem::Version
45
98
  version: 1.8.7
46
99
  required_rubygems_version: !ruby/object:Gem::Requirement
47
- none: false
48
100
  requirements:
49
- - - ! '>='
101
+ - - '>='
50
102
  - !ruby/object:Gem::Version
51
103
  version: '0'
52
104
  requirements: []
53
105
  rubyforge_project:
54
- rubygems_version: 1.8.23
106
+ rubygems_version: 2.0.2
55
107
  signing_key:
56
- specification_version: 3
108
+ specification_version: 4
57
109
  summary: deploy tool
58
- test_files: []
110
+ test_files:
111
+ - spec/cli_spec.rb
112
+ - spec/provider/heroku_spec.rb
113
+ - spec/provider_spec.rb
114
+ - spec/spec_helper.rb
59
115
  has_rdoc: