punt 0.0.1 → 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 +4 -4
- data/assets/init/puntfile.yml +5 -1
- data/lib/punt/asset_helper.rb +17 -0
- data/lib/punt/cmd/cmd.rb +0 -9
- data/lib/punt/cmd/cmd_deploy.rb +155 -0
- data/lib/punt/cmd/cmd_init.rb +3 -23
- data/lib/punt/cmd/cmd_remote.rb +104 -0
- data/lib/punt/puntfile.rb +27 -0
- data/lib/punt.rb +9 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 731663b7801f951ac4b5913b4da4231a4137ab7c
|
4
|
+
data.tar.gz: 22006967717d5085d4428d0f444083b980b7e39b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63f5af91463635ac47acf3e29e2310f0166835d6e88d75be4d2acc1598bfce278d221987cdfecdcacb45921dcee946a629af16141af7e62fcccef3abd85312f4
|
7
|
+
data.tar.gz: d4ba0c991da8054a27edd14ceebacb5e34f7bc9aa0554da9f5c1411ed9ff6cbe7270cb782b98a2b78950ff199b53a6037078bd0a7139239fd03335f918fade53
|
data/assets/init/puntfile.yml
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
module AssetHelper
|
2
|
+
def copy_without_overwriting(src: nil, dst: nil)
|
3
|
+
FileUtils.cp(src_path(src), dst_path(dst)) unless File.exists?(dst_path(dst))
|
4
|
+
end
|
5
|
+
|
6
|
+
def src_path(*asset)
|
7
|
+
asset_path(asset)
|
8
|
+
end
|
9
|
+
|
10
|
+
def dst_path(*asset)
|
11
|
+
File.join(asset)
|
12
|
+
end
|
13
|
+
|
14
|
+
def asset_path(*path)
|
15
|
+
return File.join(File.dirname(__FILE__), "..", "..", "assets", path)
|
16
|
+
end
|
17
|
+
end
|
data/lib/punt/cmd/cmd.rb
CHANGED
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
class CmdDeploy < Cmd
|
5
|
+
include Puntfile
|
6
|
+
|
7
|
+
tag name: "deploy"
|
8
|
+
tag summary: "Deploy to the specified environment"
|
9
|
+
|
10
|
+
def run(argv)
|
11
|
+
opts = parse_opts(argv)
|
12
|
+
|
13
|
+
if (opts[:dry_run])
|
14
|
+
puts "Dry Run! Nothing will be deployed or modified. All commands that would cause side-effects will be printed below"
|
15
|
+
end
|
16
|
+
|
17
|
+
env = argv.shift
|
18
|
+
ref = argv.shift
|
19
|
+
|
20
|
+
|
21
|
+
env = puntfile.first.first unless env
|
22
|
+
|
23
|
+
environment = puntfile[env] if env
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
if (!environment)
|
28
|
+
raise "No environment #{env} was found in the puntfile"
|
29
|
+
end
|
30
|
+
|
31
|
+
mode = environment["mode"]
|
32
|
+
|
33
|
+
if mode != "scp"
|
34
|
+
raise "No mode available for the given mode '#{mode}'"
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# Some Git Stuff
|
39
|
+
repo = environment["repo"]
|
40
|
+
if (repo != "git")
|
41
|
+
raise "No repo available for the given repository type #{repo}"
|
42
|
+
end
|
43
|
+
|
44
|
+
original_head = `git rev-parse --short HEAD`.strip
|
45
|
+
original_branch = `git rev-parse --abbrev-ref HEAD`.strip
|
46
|
+
|
47
|
+
ref = original_head unless ref
|
48
|
+
ref = `git rev-parse --short --verify #{ref}`.strip
|
49
|
+
ref_full = `git rev-parse --verify #{ref}`.strip
|
50
|
+
|
51
|
+
# TODO: Check to see if there are any changes! Yell and complain if there are any changes
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
puts "Deploying #{ref} to #{env}"
|
56
|
+
puts ""
|
57
|
+
|
58
|
+
# Checkout the code
|
59
|
+
if ref != original_head
|
60
|
+
if opts[:dry_run]
|
61
|
+
puts "git checkout #{ref}"
|
62
|
+
else
|
63
|
+
`git checkout #{ref}`
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Upload Version File
|
68
|
+
scp_versionfile(ref_full, "start", environment, dry_run: opts[:dry_run] || false)
|
69
|
+
if environment["files"]
|
70
|
+
environment["files"].each do |key, value|
|
71
|
+
scp_upload(key, value, environment, dry_run: opts[:dry_run] || false)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
scp_versionfile(ref_full, "success", environment, dry_run: opts[:dry_run] || false)
|
75
|
+
|
76
|
+
# Revert to our previous checkout
|
77
|
+
if ref != original_head
|
78
|
+
if opts[:dry_run]
|
79
|
+
puts "git checkout #{original_branch}"
|
80
|
+
else
|
81
|
+
`git checkout #{original_branch}`
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def scp_versionfile(ref, version_name, environment, dry_run: false)
|
89
|
+
|
90
|
+
if (!dry_run)
|
91
|
+
versionfile = Tempfile.new('foo')
|
92
|
+
versionfile.write("#{ref}")
|
93
|
+
versionfile.close()
|
94
|
+
|
95
|
+
scp_upload(versionfile.path, ".punt_#{version_name}", environment, dry_run: dry_run)
|
96
|
+
|
97
|
+
versionfile.unlink
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def scp_upload(local_file, remote, environment, dry_run: false)
|
102
|
+
scp_args = ["scp"]
|
103
|
+
scp = scp_opts(environment, scp_args)
|
104
|
+
|
105
|
+
if (File.directory?(local_file))
|
106
|
+
scp << "-r"
|
107
|
+
end
|
108
|
+
|
109
|
+
scp << local_file
|
110
|
+
scp << scp_remote_file(remote, environment)
|
111
|
+
|
112
|
+
scp_command = scp.join(" ")
|
113
|
+
|
114
|
+
puts scp_command
|
115
|
+
`#{scp_command}` unless dry_run
|
116
|
+
end
|
117
|
+
|
118
|
+
def scp_opts(environment, scp_args)
|
119
|
+
if (environment["ssh_key"])
|
120
|
+
scp_args << "-i"
|
121
|
+
scp_args << environment["ssh_key"]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def scp_remote_file(remote, environment)
|
126
|
+
if !remote.start_with?("/") && !remote.start_with?("~")
|
127
|
+
remote = File.join(environment["remote_base"], remote)
|
128
|
+
end
|
129
|
+
|
130
|
+
return "#{scp_host(environment)}#{remote}"
|
131
|
+
end
|
132
|
+
|
133
|
+
def scp_host(environment)
|
134
|
+
arg = "#{environment["host"]}:"
|
135
|
+
arg = "#{environment["username"]}@#{arg}" if environment["username"]
|
136
|
+
|
137
|
+
return arg
|
138
|
+
end
|
139
|
+
|
140
|
+
def parse_opts(argv)
|
141
|
+
options = {}
|
142
|
+
|
143
|
+
opt_parser = OptionParser.new do |opts|
|
144
|
+
opts.banner = "Usage: punt deploy [options] [environment [git-ref]]"
|
145
|
+
|
146
|
+
opts.on("-d", "--dry-run", "Show the commands that punt would execute, but don't actually do anything.") do |d|
|
147
|
+
options[:dry_run] = d
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
opt_parser.parse!(argv)
|
152
|
+
|
153
|
+
return options
|
154
|
+
end
|
155
|
+
end
|
data/lib/punt/cmd/cmd_init.rb
CHANGED
@@ -1,30 +1,10 @@
|
|
1
1
|
class CmdInit < Cmd
|
2
|
+
include AssetHelper
|
3
|
+
|
2
4
|
tag name: "init"
|
3
5
|
tag summary: "Initializes the directory with a basic puntfile.yml"
|
4
6
|
|
5
7
|
def run(argv)
|
6
|
-
copy_without_overwriting "puntfile.yml"
|
7
|
-
end
|
8
|
-
|
9
|
-
private
|
10
|
-
|
11
|
-
def copy_without_overwriting(*asset)
|
12
|
-
p = paths(asset)
|
13
|
-
FileUtils.cp(p[:src], p[:dst]) unless File.exists?(p[:dst])
|
14
|
-
end
|
15
|
-
|
16
|
-
def paths(*asset)
|
17
|
-
{
|
18
|
-
src: src_path(asset),
|
19
|
-
dst: dst_path(asset)
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
|
-
def src_path(*asset)
|
24
|
-
asset_path("init", asset)
|
25
|
-
end
|
26
|
-
|
27
|
-
def dst_path(*asset)
|
28
|
-
File.join(asset)
|
8
|
+
copy_without_overwriting src: ["init", "puntfile.yml"], dst: ["puntfile.yml"]
|
29
9
|
end
|
30
10
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
class CmdRemote < Cmd
|
4
|
+
include Puntfile
|
5
|
+
|
6
|
+
tag name: "remote"
|
7
|
+
tag summary: "Return the SHA1 of the version deployed to the remote"
|
8
|
+
|
9
|
+
def run(argv)
|
10
|
+
env = argv.shift
|
11
|
+
env = puntfile.first.first unless env
|
12
|
+
|
13
|
+
environment = puntfile[env] if env
|
14
|
+
|
15
|
+
if (!environment)
|
16
|
+
raise "No environment #{env} was found in the puntfile"
|
17
|
+
end
|
18
|
+
|
19
|
+
mode = environment["mode"]
|
20
|
+
|
21
|
+
if mode != "scp"
|
22
|
+
raise "No mode available for the given mode '#{mode}'"
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Fetching Version for #{env}"
|
26
|
+
puts ""
|
27
|
+
|
28
|
+
# Upload Version File
|
29
|
+
start_version = scp_fetch_versionfile("start", environment)
|
30
|
+
success_version = scp_fetch_versionfile("success", environment)
|
31
|
+
|
32
|
+
if (success_version == start_version)
|
33
|
+
puts "Currently deployed version: #{success_version}"
|
34
|
+
else
|
35
|
+
puts "An aborted deployement was detected!"
|
36
|
+
puts "\tLast Success: #{success_version}"
|
37
|
+
puts "\tLast Attempt: #{start_version}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def scp_fetch_versionfile(version_name, environment)
|
44
|
+
versionfile = Tempfile.new('foo')
|
45
|
+
|
46
|
+
scp_download(versionfile.path, ".punt_#{version_name}", environment)
|
47
|
+
|
48
|
+
version = versionfile.read
|
49
|
+
|
50
|
+
versionfile.unlink
|
51
|
+
|
52
|
+
return version.strip
|
53
|
+
end
|
54
|
+
|
55
|
+
def scp_versionfile(ref, version_name, environment, dry_run: false)
|
56
|
+
|
57
|
+
if (!dry_run)
|
58
|
+
versionfile = Tempfile.new('foo')
|
59
|
+
versionfile.write("#{ref}")
|
60
|
+
|
61
|
+
scp_upload(versionfile.path, ".punt_#{version_name}", environment, dry_run: dry_run)
|
62
|
+
|
63
|
+
versionfile.unlink
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def scp_download(local_file, remote, environment, dry_run: false)
|
68
|
+
scp_args = ["scp"]
|
69
|
+
scp = scp_opts(environment, scp_args)
|
70
|
+
|
71
|
+
if (File.directory?(local_file))
|
72
|
+
scp << "-r"
|
73
|
+
end
|
74
|
+
|
75
|
+
scp << scp_remote_file(remote, environment)
|
76
|
+
scp << local_file
|
77
|
+
|
78
|
+
scp_command = scp.join(" ")
|
79
|
+
|
80
|
+
`#{scp_command}` unless dry_run
|
81
|
+
end
|
82
|
+
|
83
|
+
def scp_opts(environment, scp_args)
|
84
|
+
if (environment["ssh_key"])
|
85
|
+
scp_args << "-i"
|
86
|
+
scp_args << environment["ssh_key"]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def scp_remote_file(remote, environment)
|
91
|
+
if !remote.start_with?("/") && !remote.start_with?("~")
|
92
|
+
remote = File.join(environment["remote_base"], remote)
|
93
|
+
end
|
94
|
+
|
95
|
+
return "#{scp_host(environment)}#{remote}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def scp_host(environment)
|
99
|
+
arg = "#{environment["host"]}:"
|
100
|
+
arg = "#{environment["username"]}@#{arg}" if environment["username"]
|
101
|
+
|
102
|
+
return arg
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Puntfile
|
2
|
+
|
3
|
+
SUPPORTED_PUNTFILES = ["puntfile.yml", "puntfile.yaml", "Puntfile.yml", "Puntfile.yaml", "puntfile", "Puntfile"]
|
4
|
+
|
5
|
+
def puntfile
|
6
|
+
load_puntfile
|
7
|
+
|
8
|
+
return @@puntfile
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def load_puntfile
|
14
|
+
return if defined?(@@puntfile)
|
15
|
+
|
16
|
+
SUPPORTED_PUNTFILES.each do |puntfile|
|
17
|
+
if File.exists?(puntfile)
|
18
|
+
@@puntfile = YAML.load_file(puntfile)
|
19
|
+
return
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
raise "We couldn't find puntfile.yml in the current directory"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
end
|
data/lib/punt.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
|
+
require 'punt/asset_helper'
|
4
|
+
require 'punt/puntfile'
|
5
|
+
|
3
6
|
require 'punt/cmd/cmd'
|
4
7
|
require 'punt/cmd/cmd_init'
|
8
|
+
require 'punt/cmd/cmd_deploy'
|
9
|
+
require 'punt/cmd/cmd_remote'
|
5
10
|
|
6
11
|
class Punt
|
7
|
-
CMDS = [CmdInit.new
|
12
|
+
CMDS = [CmdInit.new,
|
13
|
+
CmdDeploy.new,
|
14
|
+
CmdRemote.new,
|
15
|
+
].sort { |first, second| first.name <=> second.name }
|
8
16
|
|
9
17
|
def self.cmd(argv)
|
10
18
|
first = argv.shift
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: punt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Callaway
|
@@ -21,8 +21,12 @@ files:
|
|
21
21
|
- assets/init/puntfile.yml
|
22
22
|
- bin/punt
|
23
23
|
- lib/punt.rb
|
24
|
+
- lib/punt/asset_helper.rb
|
24
25
|
- lib/punt/cmd/cmd.rb
|
26
|
+
- lib/punt/cmd/cmd_deploy.rb
|
25
27
|
- lib/punt/cmd/cmd_init.rb
|
28
|
+
- lib/punt/cmd/cmd_remote.rb
|
29
|
+
- lib/punt/puntfile.rb
|
26
30
|
homepage: http://rubygems.org/gems/punt
|
27
31
|
licenses:
|
28
32
|
- MIT
|