dpl 0.1.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.
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Gemfile +7 -0
- data/bin/dpl +5 -0
- data/dpl.gemspec +18 -0
- data/lib/dpl/cli.rb +48 -0
- data/lib/dpl/error.rb +3 -0
- data/lib/dpl/provider.rb +84 -0
- data/lib/dpl/provider/heroku.rb +49 -0
- data/lib/dpl/version.rb +3 -0
- metadata +57 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/bin/dpl
ADDED
data/dpl.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
require "dpl/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "dpl"
|
6
|
+
s.version = DPL::VERSION
|
7
|
+
s.author = "Konstantin Haase"
|
8
|
+
s.email = "konstantin.mailinglists@googlemail.com"
|
9
|
+
s.homepage = "https://github.com/rkh/dpl"
|
10
|
+
s.summary = %q{deploy tool}
|
11
|
+
s.description = %q{deploy tool abstraction for clients}
|
12
|
+
s.license = 'MIT'
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_path = 'lib'
|
17
|
+
s.required_ruby_version = '>= 1.8.7'
|
18
|
+
end
|
data/lib/dpl/cli.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'dpl/error'
|
2
|
+
require 'dpl/provider'
|
3
|
+
|
4
|
+
module DPL
|
5
|
+
class CLI
|
6
|
+
def self.run(*args)
|
7
|
+
new(args).run
|
8
|
+
end
|
9
|
+
|
10
|
+
OPTION_PATTERN = /\A--([a-z][a-z_\-]*)(?:=(.+))?\z/
|
11
|
+
attr_accessor :options
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
options = {}
|
15
|
+
args.flatten.each do |arg|
|
16
|
+
next options.update(arg) if arg.is_a? Hash
|
17
|
+
die("invalid option %p" % arg) unless match = OPTION_PATTERN.match(arg)
|
18
|
+
key = match[1].tr('-', '_').to_sym
|
19
|
+
if options.include? key
|
20
|
+
options[key] = Array(options[key]) << match[2]
|
21
|
+
else
|
22
|
+
options[key] = match[2] || true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
self.options = default_options.merge(options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
provider = Provider.new(self, options)
|
31
|
+
provider.deploy
|
32
|
+
rescue Error => error
|
33
|
+
options[:debug] ? raise(error) : die(error.message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def default_options
|
37
|
+
{
|
38
|
+
:app => File.basename(Dir.pwd),
|
39
|
+
:key_name => %x[hostname].strip
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def die(message)
|
44
|
+
$stderr.puts(message)
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/dpl/error.rb
ADDED
data/lib/dpl/provider.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'dpl/error'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module DPL
|
5
|
+
class Provider
|
6
|
+
include FileUtils
|
7
|
+
|
8
|
+
autoload :Heroku, 'dpl/provider/heroku'
|
9
|
+
|
10
|
+
def self.new(context, options)
|
11
|
+
return super if self < Provider
|
12
|
+
name = super.option(:provider).to_s.downcase.gsub(/[^a-z]/, '')
|
13
|
+
raise Error, 'could not find provider %p' % options[:provider] unless name = constants.detect { |c| c.to_s.downcase == name }
|
14
|
+
const_get(name).new(context, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.requires(name, version = "> 0")
|
18
|
+
gem(name, version)
|
19
|
+
rescue LoadError
|
20
|
+
system("gem install %s -v %p" % [name, version])
|
21
|
+
Gem.clear_paths
|
22
|
+
ensure
|
23
|
+
require name
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :context, :options
|
27
|
+
|
28
|
+
def initialize(context, options)
|
29
|
+
@context, @options = context, options
|
30
|
+
end
|
31
|
+
|
32
|
+
def option(name)
|
33
|
+
options.fetch(name) { raise Error, "missing #{name}" }
|
34
|
+
end
|
35
|
+
|
36
|
+
def deploy
|
37
|
+
rm_rf ".dpl"
|
38
|
+
mkdir_p ".dpl"
|
39
|
+
|
40
|
+
check_auth
|
41
|
+
check_app
|
42
|
+
|
43
|
+
if needs_key?
|
44
|
+
create_key(".dpl/id_rsa")
|
45
|
+
setup_key(".dpl/id_rsa.pub")
|
46
|
+
setup_git_ssh(".dpl/git-ssh", ".dpl/id_rsa")
|
47
|
+
end
|
48
|
+
|
49
|
+
push_app
|
50
|
+
|
51
|
+
Array(options[:run]).each do |command|
|
52
|
+
run(command)
|
53
|
+
end
|
54
|
+
ensure
|
55
|
+
remove_key if needs_key?
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def needs_key?
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_key(file)
|
64
|
+
system "ssh-keygen -t rsa -N \"\" -C #{option(:key_name)} -f #{file}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def setup_git_ssh(path, key_path)
|
68
|
+
key_path = File.expand_path(key_path)
|
69
|
+
path = File.expand_path(path)
|
70
|
+
|
71
|
+
File.open(path, 'w') do |file|
|
72
|
+
file.write "#!/bin/sh\n"
|
73
|
+
file.write "exec ssh -o StrictHostKeychecking=no -o CheckHostIP=no -o UserKnownHostsFile=/dev/null -i #{key_path} -- \"$@\"\n"
|
74
|
+
end
|
75
|
+
|
76
|
+
chmod(0740, path)
|
77
|
+
ENV['GIT_SSH'] = path
|
78
|
+
end
|
79
|
+
|
80
|
+
def log(message)
|
81
|
+
$stderr.puts(message)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module DPL
|
2
|
+
class Provider
|
3
|
+
class Heroku < Provider
|
4
|
+
requires 'heroku-api'
|
5
|
+
requires 'rendezvous'
|
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
|
39
|
+
|
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
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/dpl/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dpl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Konstantin Haase
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-27 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: deploy tool abstraction for clients
|
15
|
+
email: konstantin.mailinglists@googlemail.com
|
16
|
+
executables:
|
17
|
+
- dpl
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- .rspec
|
23
|
+
- Gemfile
|
24
|
+
- bin/dpl
|
25
|
+
- dpl.gemspec
|
26
|
+
- lib/dpl/cli.rb
|
27
|
+
- lib/dpl/error.rb
|
28
|
+
- lib/dpl/provider.rb
|
29
|
+
- lib/dpl/provider/heroku.rb
|
30
|
+
- lib/dpl/version.rb
|
31
|
+
homepage: https://github.com/rkh/dpl
|
32
|
+
licenses:
|
33
|
+
- MIT
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.8.7
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.8.23
|
53
|
+
signing_key:
|
54
|
+
specification_version: 3
|
55
|
+
summary: deploy tool
|
56
|
+
test_files: []
|
57
|
+
has_rdoc:
|