egads 2.0.0 → 3.0.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/bin/egads +0 -2
- data/example/egads_remote.yml +5 -0
- data/lib/egads.rb +2 -0
- data/lib/egads/capistrano.rb +10 -2
- data/lib/egads/command.rb +12 -0
- data/lib/egads/command/build.rb +52 -21
- data/lib/egads/command/extract.rb +68 -29
- data/lib/egads/command/release.rb +15 -2
- data/lib/egads/command/stage.rb +1 -1
- data/lib/egads/command/trim.rb +17 -6
- data/lib/egads/command/upload.rb +6 -3
- data/lib/egads/config.rb +8 -0
- data/lib/egads/group.rb +26 -12
- data/lib/egads/local_helpers.rb +2 -2
- data/lib/egads/s3_tarball.rb +12 -12
- data/lib/egads/version.rb +1 -1
- data/spec/egads_build_spec.rb +4 -1
- data/spec/egads_command_spec.rb +8 -0
- data/spec/egads_extract_spec.rb +1 -1
- metadata +17 -5
- checksums.yaml +0 -7
data/bin/egads
CHANGED
data/example/egads_remote.yml
CHANGED
@@ -5,8 +5,13 @@ s3:
|
|
5
5
|
secret_key: mysecret
|
6
6
|
prefix: my_project # Optional prefix for S3 paths
|
7
7
|
|
8
|
+
# Path where seed files are cached
|
9
|
+
cache_seeds_to: /var/apps/my_project/seeds
|
10
|
+
|
8
11
|
# Path where tarballs are extracted
|
9
12
|
extract_to: /var/apps/my_project/releases
|
13
|
+
|
14
|
+
# Path where the currently running version is symlinked
|
10
15
|
release_to: /var/apps/my_project/current
|
11
16
|
|
12
17
|
restart_command: /etc/init.d/rails_services restart
|
data/lib/egads.rb
CHANGED
data/lib/egads/capistrano.rb
CHANGED
@@ -9,7 +9,7 @@ Capistrano::Configuration.instance.load do
|
|
9
9
|
namespace :deploy do
|
10
10
|
desc "Deploy"
|
11
11
|
task :default do
|
12
|
-
deploy.
|
12
|
+
deploy.build
|
13
13
|
deploy.stage
|
14
14
|
deploy.release
|
15
15
|
end
|
@@ -31,7 +31,15 @@ Capistrano::Configuration.instance.load do
|
|
31
31
|
run "egads release #{egads_options} #{full_sha}"
|
32
32
|
end
|
33
33
|
|
34
|
-
desc "
|
34
|
+
desc "Builds a deployable tarball and uploads it to S3"
|
35
|
+
task :build do
|
36
|
+
logger.info "Building tarball for #{full_sha}"
|
37
|
+
`bundle exec egads build #{full_sha}`
|
38
|
+
abort "Failed to build" if $?.exitstatus != 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# Not used by default. Here for convenience
|
42
|
+
desc "Checks that a deployable tarball is on S3; waits for it to exist if missing"
|
35
43
|
task :check do
|
36
44
|
logger.info "Checking tarball for #{full_sha}"
|
37
45
|
logger.info "To build the tarball locally, run `bundle exec egads build #{full_sha}"
|
data/lib/egads/command.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
module Egads
|
2
2
|
class Command < Thor
|
3
|
+
|
4
|
+
# Always exit on failure
|
5
|
+
def self.exit_on_failure?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
|
3
9
|
require 'egads/local_helpers'
|
4
10
|
require 'egads/command/check'
|
5
11
|
require 'egads/command/build'
|
@@ -17,5 +23,11 @@ module Egads
|
|
17
23
|
register(Release, 'release', 'release SHA', '[remote, plumbing] Downloads tarball for SHA from S3 and extracts it to the filesystem')
|
18
24
|
register(Trim, 'trime', 'trim [N]', "[remote, plumbing] Deletes old releases, keeping the N most recent (by mtime)")
|
19
25
|
|
26
|
+
map '--version' => :version
|
27
|
+
desc :version, "Prints the version"
|
28
|
+
def version
|
29
|
+
puts "#{File.basename($0)} #{VERSION}"
|
30
|
+
end
|
31
|
+
|
20
32
|
end
|
21
33
|
end
|
data/lib/egads/command/build.rb
CHANGED
@@ -1,53 +1,76 @@
|
|
1
1
|
module Egads
|
2
2
|
class Build < Group
|
3
3
|
include Thor::Actions
|
4
|
-
include
|
4
|
+
include LocalHelpers
|
5
5
|
|
6
|
-
desc "[local] Compiles a deployable
|
6
|
+
desc "[local] Compiles a deployable patch of the current commit and uploads it to S3"
|
7
7
|
class_option :force, type: :boolean, aliases: '-f', default: false, banner: "Build and overwrite existing tarball on S3"
|
8
|
+
class_option :seed, type: :boolean, default: false, banner: "Builds and tags a complete tarball for more efficient patches"
|
8
9
|
class_option 'no-upload', type: :boolean, default: false, banner: "Don't upload the tarball to S3"
|
9
10
|
argument :rev, type: :string, default: 'HEAD', desc: 'git revision to build'
|
10
11
|
|
12
|
+
attr_accessor :build_sha
|
13
|
+
|
11
14
|
def check_build
|
12
15
|
say_status :rev, "#{rev} parsed to #{sha}"
|
13
16
|
|
14
17
|
unless should_build?
|
15
|
-
say_status :done, "
|
18
|
+
say_status :done, "#{build_type} tarball for #{sha} already exists. Pass --force to rebuild."
|
16
19
|
exit 0
|
17
20
|
end
|
18
21
|
|
19
|
-
say_status :rev, "#{rev} parsed to #{sha}"
|
20
22
|
exit 1 unless can_build?
|
23
|
+
say_status :build, "Making #{build_type} tarball for #{sha}", :yellow
|
21
24
|
end
|
22
25
|
|
23
|
-
def
|
24
|
-
|
25
|
-
FileUtils.mkdir_p(File.dirname(tarball.local_tar_path))
|
26
|
-
run_with_code "git archive #{sha} --format=tar > #{tarball.local_tar_path}"
|
26
|
+
def run_before_build_hooks
|
27
|
+
run_hooks_for(:build, :before)
|
27
28
|
end
|
28
29
|
|
29
|
-
def
|
30
|
+
def write_revision_file
|
30
31
|
File.open('REVISION', 'w') {|f| f << sha + "\n" }
|
31
|
-
run_with_code "tar -uf #{tarball.local_tar_path} REVISION"
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
|
34
|
+
def commit_extra_paths
|
35
|
+
extra_paths = ["REVISION"]
|
36
|
+
extra_paths += Config.build_extra_paths
|
37
|
+
run_with_code("git add -f #{extra_paths * ' '} && git commit --no-verify -m 'egads build'")
|
38
|
+
# Get the build SHA
|
39
|
+
self.build_sha = run_with_code("git rev-parse --verify HEAD").strip
|
40
|
+
run_with_code "git reset #{sha}" # Reset to original SHA
|
41
|
+
|
36
42
|
end
|
37
43
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
run_with_code "
|
44
|
+
def make_tarball
|
45
|
+
if options[:seed]
|
46
|
+
# Seed tarball
|
47
|
+
run_with_code "git archive #{build_sha} --output #{tarball.local_tar_path}"
|
48
|
+
else
|
49
|
+
# Patch tarball
|
50
|
+
seed_ref = "refs/tags/#{Config.seed_tag}"
|
51
|
+
# NB: the seed tarball is named after the parent of seed tag
|
52
|
+
seed_parent = run_with_code("git rev-parse --verify #{seed_ref}^").strip
|
53
|
+
File.open('egads-seed', 'w') {|f| f << seed_parent + "\n" }
|
54
|
+
patch_files = [patch_path, 'egads-seed']
|
55
|
+
run_with_code "git diff --binary #{seed_ref} #{build_sha} > #{patch_path}"
|
56
|
+
run_with_code "tar -zcf #{tarball.local_tar_path} #{patch_files * ' '}"
|
57
|
+
patch_files.each {|f| File.delete(f) }
|
42
58
|
end
|
59
|
+
|
43
60
|
end
|
44
61
|
|
45
|
-
def
|
46
|
-
|
62
|
+
def run_after_build_hooks
|
63
|
+
run_hooks_for(:build, :after)
|
47
64
|
end
|
48
65
|
|
49
66
|
def upload
|
50
|
-
invoke(Egads::Upload, [sha]) unless options['no-upload']
|
67
|
+
invoke(Egads::Upload, [sha], force: options[:force], seed: options[:seed]) unless options['no-upload']
|
68
|
+
end
|
69
|
+
|
70
|
+
def tag_seed
|
71
|
+
if options[:seed]
|
72
|
+
run_with_code "git tag -f -a -m 'egads seed' #{Config.seed_tag} #{build_sha} && git push -f origin tag #{Config.seed_tag}"
|
73
|
+
end
|
51
74
|
end
|
52
75
|
|
53
76
|
module BuildHelpers
|
@@ -60,7 +83,7 @@ module Egads
|
|
60
83
|
end
|
61
84
|
|
62
85
|
def sha_is_checked_out?
|
63
|
-
head = run_with_code("git rev-parse --verify HEAD"
|
86
|
+
head = run_with_code("git rev-parse --verify HEAD").strip
|
64
87
|
short_head = head[0,7]
|
65
88
|
head == sha or error [
|
66
89
|
"Cannot build #{short_sha} because #{short_head} is checked out.",
|
@@ -76,6 +99,14 @@ module Egads
|
|
76
99
|
]
|
77
100
|
end
|
78
101
|
|
102
|
+
def patch_path
|
103
|
+
"#{sha}.patch"
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_type
|
107
|
+
options[:seed] ? 'seed' : 'patch'
|
108
|
+
end
|
109
|
+
|
79
110
|
def error(message)
|
80
111
|
lines = Array(message)
|
81
112
|
say_status :error, lines.shift, :red
|
@@ -83,8 +114,8 @@ module Egads
|
|
83
114
|
|
84
115
|
false
|
85
116
|
end
|
86
|
-
|
87
117
|
end
|
88
118
|
include BuildHelpers
|
119
|
+
|
89
120
|
end
|
90
121
|
end
|
@@ -3,65 +3,104 @@ module Egads
|
|
3
3
|
include Thor::Actions
|
4
4
|
|
5
5
|
desc "[remote, plumbing] Downloads tarball for SHA from S3 and extracts it to the filesystem"
|
6
|
-
class_option :force, type: :boolean, default: false, banner: "Overwrite existing files"
|
6
|
+
class_option :force, type: :boolean, aliases: '-f', default: false, banner: "Overwrite existing files"
|
7
7
|
argument :sha, type: :string, required: true, desc: 'git SHA to download and extract'
|
8
8
|
|
9
|
+
attr_accessor :seed_sha, :seed_path
|
10
|
+
|
9
11
|
def setup_environment
|
10
12
|
RemoteConfig.setup_environment
|
11
13
|
end
|
12
14
|
|
13
|
-
def
|
14
|
-
if
|
15
|
-
|
16
|
-
|
15
|
+
def extract
|
16
|
+
if should_extract?
|
17
|
+
# Download_patch
|
18
|
+
do_download(sha, File.join(patch_dir, "#{sha}.tar.gz"), 'patch')
|
19
|
+
|
20
|
+
do_extract patch_path
|
21
|
+
|
22
|
+
# Download seed
|
23
|
+
self.seed_sha = Pathname.new(patch_dir).join("egads-seed").read.strip
|
24
|
+
self.seed_path = File.join(RemoteConfig.seed_dir, "#{seed_sha}.tar.gz")
|
25
|
+
do_download(seed_sha, seed_path, 'seed')
|
26
|
+
|
27
|
+
do_extract seed_path
|
28
|
+
|
29
|
+
apply_patch
|
30
|
+
finish_extraction
|
31
|
+
else
|
32
|
+
say_status :done, "#{sha} already extracted. Use --force to overwrite"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
def apply_patch
|
38
|
+
inside patch_dir do
|
39
|
+
run_with_code "git apply --whitespace=nowarn < #{sha}.patch"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def finish_extraction
|
44
|
+
if options[:force]
|
45
|
+
say_status :delete, "Removing release dir #{release_dir} if exists", :yellow
|
46
|
+
FileUtils.rm_rf(release_dir)
|
47
|
+
end
|
48
|
+
|
49
|
+
say_status :extract, "Moving #{patch_dir} to #{release_dir}"
|
50
|
+
File.rename patch_dir, release_dir
|
51
|
+
say_status :done, "Extraction complete"
|
52
|
+
rescue Errno::ENOTEMPTY
|
53
|
+
say_status :error, "#{release_dir} already exists! Did another process create it?", :red
|
54
|
+
raise
|
55
|
+
end
|
56
|
+
|
57
|
+
def do_download(sha, path, type='patch')
|
58
|
+
if should_download?(path)
|
59
|
+
say_status :download, "Downloading #{type} tarball for #{sha}", :yellow
|
60
|
+
FileUtils.mkdir_p(File.dirname(path))
|
61
|
+
tarball = S3Tarball.new(sha, remote: true, seed: 'seed' == type)
|
62
|
+
tmp_path = [path, 'tmp', rand(2**32)] * '.' # Use tmp path for atomicity
|
17
63
|
duration = Benchmark.realtime do
|
18
|
-
File.open(
|
64
|
+
File.open(tmp_path, 'w') {|f| f << tarball.contents }
|
19
65
|
end
|
66
|
+
File.rename(tmp_path, path)
|
20
67
|
size = File.size(path)
|
21
68
|
say_status :done, "Downloaded in %.1f seconds (%.1f KB/s)" % [duration, (size.to_f / 2**10) / duration]
|
22
69
|
else
|
23
|
-
say_status :done, "
|
70
|
+
say_status :done, "#{type} tarball already downloaded. Use --force to overwrite"
|
24
71
|
end
|
25
72
|
end
|
26
73
|
|
27
|
-
def
|
28
|
-
|
29
|
-
if should_extract?
|
74
|
+
def do_extract(path)
|
75
|
+
inside(patch_dir) do
|
30
76
|
# Silence stderr warnings "Ignoring unknown extended header keyword"
|
31
|
-
# due to BSD/GNU tar.
|
32
|
-
|
33
|
-
else
|
34
|
-
say_status :done, "Tarball already extracted. Use --force to overwrite"
|
77
|
+
# due to BSD/GNU tar differences.
|
78
|
+
run_with_code "tar -zxf #{path} 2>/dev/null"
|
35
79
|
end
|
36
80
|
end
|
37
81
|
|
38
|
-
|
39
|
-
FileUtils.touch(extract_flag_path)
|
40
|
-
end
|
41
|
-
|
42
|
-
protected
|
82
|
+
# Directory created upon successful extraction
|
43
83
|
def release_dir
|
44
84
|
RemoteConfig.release_dir(sha)
|
45
85
|
end
|
46
86
|
|
47
|
-
|
48
|
-
|
87
|
+
# Directory where in-progress extraction occurs
|
88
|
+
# Avoids troublesome edge cases where a patch may not not have applied cleanly,
|
89
|
+
# or egads crashes during the extraction process
|
90
|
+
def patch_dir
|
91
|
+
@patch_dir ||= [release_dir, 'extracting', Time.now.strftime("%Y%m%d%H%M%S")] * '.'
|
49
92
|
end
|
50
93
|
|
51
|
-
def
|
52
|
-
|
94
|
+
def patch_path
|
95
|
+
File.join(patch_dir, "#{sha}.tar.gz")
|
53
96
|
end
|
54
97
|
|
55
|
-
def should_download?
|
98
|
+
def should_download?(path)
|
56
99
|
options[:force] || File.zero?(path) || !File.exists?(path)
|
57
100
|
end
|
58
101
|
|
59
|
-
def extract_flag_path
|
60
|
-
File.join(release_dir, '.egads-extract-success')
|
61
|
-
end
|
62
|
-
|
63
102
|
def should_extract?
|
64
|
-
options[:force] || !File.
|
103
|
+
options[:force] || !File.directory?(release_dir)
|
65
104
|
end
|
66
105
|
|
67
106
|
end
|
@@ -20,7 +20,7 @@ module Egads
|
|
20
20
|
|
21
21
|
def symlink_release
|
22
22
|
return unless should_release?
|
23
|
-
|
23
|
+
atomic_symlink(dir, release_to)
|
24
24
|
end
|
25
25
|
|
26
26
|
def restart
|
@@ -28,7 +28,7 @@ module Egads
|
|
28
28
|
|
29
29
|
inside release_to do
|
30
30
|
# Restart services
|
31
|
-
run_with_code(RemoteConfig.restart_command)
|
31
|
+
run_with_code(RemoteConfig.restart_command, stream: true)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -60,5 +60,18 @@ module Egads
|
|
60
60
|
@should_release = options[:force] || dir != current_symlink_destination unless defined?(@should_release)
|
61
61
|
@should_release
|
62
62
|
end
|
63
|
+
|
64
|
+
# Symlinks src to dest, even if dest is an existing directory symlink
|
65
|
+
# NB that `ln -f` doesn't work with directories.
|
66
|
+
# Use an extra temporary symlink for atomicity (equivalent to `mv -T`)
|
67
|
+
def atomic_symlink(src, dest)
|
68
|
+
raise ArgumentError.new("#{src} is not a directory") unless File.directory?(src)
|
69
|
+
say_status :symlink, "from #{src} to #{dest}"
|
70
|
+
tmp = "#{dest}-new-#{rand(2**32)}"
|
71
|
+
# Make a temporary symlink
|
72
|
+
File.symlink(src, tmp)
|
73
|
+
# Atomically rename the symlink, possibly overwriting an existing symlink
|
74
|
+
File.rename(tmp, dest)
|
75
|
+
end
|
63
76
|
end
|
64
77
|
end
|
data/lib/egads/command/stage.rb
CHANGED
@@ -24,7 +24,7 @@ module Egads
|
|
24
24
|
return unless should_stage?
|
25
25
|
|
26
26
|
inside(dir) do
|
27
|
-
run_with_code("bundle install #{RemoteConfig.bundler_options}") if File.readable?("Gemfile")
|
27
|
+
run_with_code("bundle install #{RemoteConfig.bundler_options}", stream: true) if File.readable?("Gemfile")
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
data/lib/egads/command/trim.rb
CHANGED
@@ -3,14 +3,25 @@ module Egads
|
|
3
3
|
include Thor::Actions
|
4
4
|
|
5
5
|
|
6
|
-
desc "[remote, plumbing] Deletes old releases, keeping the N most recent (by mtime)"
|
6
|
+
desc "[remote, plumbing] Deletes old releases and seeds, keeping the N most recent (by mtime)"
|
7
7
|
def trim(n=4)
|
8
|
+
# Trim old releases
|
8
9
|
inside RemoteConfig.extract_to do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
trim_glob('*', n)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Trim seeds
|
14
|
+
inside RemoteConfig.seed_dir do
|
15
|
+
trim_glob('*.tar.gz', n)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
def trim_glob(glob, n)
|
21
|
+
paths = Dir.glob(glob).sort_by{|path| File.mtime(path) }.reverse[n..-1].to_a
|
22
|
+
paths.each do |path|
|
23
|
+
say_status :trim, "Deleting #{path}"
|
24
|
+
FileUtils.rm_rf(path)
|
14
25
|
end
|
15
26
|
end
|
16
27
|
|
data/lib/egads/command/upload.rb
CHANGED
@@ -4,13 +4,16 @@ module Egads
|
|
4
4
|
|
5
5
|
desc "[local, plumbing] Uploads a tarball for SHA to S3"
|
6
6
|
argument :sha, type: :string, required: true, desc: 'git SHA to upload'
|
7
|
+
class_option :seed, type: :boolean, default: false, banner: "Uploads a seed tarball"
|
8
|
+
|
7
9
|
|
8
10
|
attr_reader :sha
|
9
11
|
def upload
|
10
12
|
@sha = sha
|
11
13
|
size = File.size(path)
|
14
|
+
type = options[:seed] ? 'seed' : 'patch'
|
12
15
|
|
13
|
-
say_status :upload, "Uploading tarball (%.1f MB)" % (size.to_f / 2**20), :yellow
|
16
|
+
say_status :upload, "Uploading #{type} tarball (%.1f MB)" % (size.to_f / 2**20), :yellow
|
14
17
|
duration = Benchmark.realtime do
|
15
18
|
tarball.upload(path)
|
16
19
|
end
|
@@ -21,11 +24,11 @@ module Egads
|
|
21
24
|
|
22
25
|
private
|
23
26
|
def tarball
|
24
|
-
@tarball ||= S3Tarball.new(sha)
|
27
|
+
@tarball ||= S3Tarball.new(sha, seed: options[:seed])
|
25
28
|
end
|
26
29
|
|
27
30
|
def path
|
28
|
-
tarball.
|
31
|
+
tarball.local_tar_path
|
29
32
|
end
|
30
33
|
|
31
34
|
end
|
data/lib/egads/config.rb
CHANGED
@@ -42,6 +42,10 @@ module Egads
|
|
42
42
|
def self.build_extra_paths
|
43
43
|
config['build'] && Array(config['build']['extra_paths'])
|
44
44
|
end
|
45
|
+
|
46
|
+
def self.seed_tag
|
47
|
+
config['seed_tag'] || "egads-seed"
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
# Remote config for the extract command (before data in tarball is available)
|
@@ -64,6 +68,10 @@ module Egads
|
|
64
68
|
config['extract_to']
|
65
69
|
end
|
66
70
|
|
71
|
+
def self.seed_dir
|
72
|
+
config['cache_seeds_to']
|
73
|
+
end
|
74
|
+
|
67
75
|
def self.release_dir(sha)
|
68
76
|
File.join(config['extract_to'], sha)
|
69
77
|
end
|
data/lib/egads/group.rb
CHANGED
@@ -1,20 +1,35 @@
|
|
1
|
+
require 'open3'
|
1
2
|
module Egads
|
2
3
|
class CommandError < Thor::Error; end
|
3
4
|
|
4
5
|
class Group < Thor::Group
|
5
6
|
|
7
|
+
# Always exit on failure
|
8
|
+
def self.exit_on_failure?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
6
12
|
protected
|
7
|
-
def run_with_code(command,
|
8
|
-
|
13
|
+
def run_with_code(command, options={})
|
14
|
+
|
15
|
+
say_status :run, "#{command}", options.fetch(:verbose, true)
|
16
|
+
|
17
|
+
capture = []
|
9
18
|
duration = Benchmark.realtime do
|
10
|
-
|
11
|
-
|
12
|
-
|
19
|
+
Open3.popen2e(command) do |_, out, thread|
|
20
|
+
out.each do |line|
|
21
|
+
puts line if options[:stream]
|
22
|
+
capture << line
|
23
|
+
end
|
13
24
|
|
14
|
-
|
15
|
-
|
25
|
+
unless thread.value == 0
|
26
|
+
raise CommandError.new("`#{command}` failed with exit status #{thread.value.exitstatus.inspect}")
|
27
|
+
end
|
28
|
+
end
|
16
29
|
end
|
17
|
-
|
30
|
+
say_status :done, "Finished in %.1f seconds" % duration, options.fetch(:verbose, true)
|
31
|
+
|
32
|
+
capture.join
|
18
33
|
end
|
19
34
|
|
20
35
|
# Run command hooks from config file
|
@@ -22,18 +37,17 @@ module Egads
|
|
22
37
|
def run_hooks_for(cmd, hook)
|
23
38
|
say_status :hooks, "Running #{cmd} #{hook} hooks"
|
24
39
|
Config.hooks_for(cmd, hook).each do |command|
|
25
|
-
|
40
|
+
run_with_code(command, stream: true)
|
26
41
|
end
|
27
42
|
end
|
28
43
|
|
29
|
-
# Symlinks a directory
|
44
|
+
# Symlinks a directory (not atomically)
|
30
45
|
# NB that `ln -f` doesn't work with directories.
|
31
|
-
# This is not atomic.
|
32
46
|
def symlink_directory(src, dest)
|
33
47
|
raise ArgumentError.new("#{src} is not a directory") unless File.directory?(src)
|
34
48
|
say_status :symlink, "from #{src} to #{dest}"
|
35
49
|
FileUtils.rm_rf(dest)
|
36
|
-
|
50
|
+
File.symlink(src, dest)
|
37
51
|
end
|
38
52
|
|
39
53
|
def symlink(src, dest)
|
data/lib/egads/local_helpers.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Egads
|
2
|
-
# Some helper methods for
|
2
|
+
# Some helper methods for all local commands
|
3
3
|
module LocalHelpers
|
4
4
|
def sha
|
5
5
|
@sha ||= run_with_code("git rev-parse --verify #{rev}").strip
|
@@ -10,7 +10,7 @@ module Egads
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def tarball
|
13
|
-
@tarball ||= S3Tarball.new(sha)
|
13
|
+
@tarball ||= S3Tarball.new(sha, seed: options[:seed])
|
14
14
|
end
|
15
15
|
|
16
16
|
end
|
data/lib/egads/s3_tarball.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Egads
|
2
2
|
class S3Tarball
|
3
|
-
attr_reader :sha, :remote
|
4
|
-
def initialize(sha,
|
5
|
-
@sha
|
6
|
-
@remote = remote
|
3
|
+
attr_reader :sha, :remote, :seed
|
4
|
+
def initialize(sha, options = {})
|
5
|
+
@sha = sha
|
6
|
+
@remote = options[:remote]
|
7
|
+
@seed = options[:seed]
|
7
8
|
end
|
8
9
|
|
9
10
|
def config
|
@@ -11,7 +12,11 @@ module Egads
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def key
|
14
|
-
[
|
15
|
+
[
|
16
|
+
config.s3_prefix,
|
17
|
+
seed ? 'seeds' : nil,
|
18
|
+
"#{sha}.tar.gz"
|
19
|
+
].compact * '/'
|
15
20
|
end
|
16
21
|
|
17
22
|
def exists?
|
@@ -19,14 +24,10 @@ module Egads
|
|
19
24
|
end
|
20
25
|
|
21
26
|
def local_tar_path
|
22
|
-
"tmp/#{sha}.tar"
|
27
|
+
"tmp/#{sha}.tar.gz"
|
23
28
|
end
|
24
29
|
|
25
|
-
def
|
26
|
-
"#{local_tar_path}.gz"
|
27
|
-
end
|
28
|
-
|
29
|
-
def upload(path=local_gzipped_path)
|
30
|
+
def upload(path=local_tar_path)
|
30
31
|
File.open(path) {|f|
|
31
32
|
bucket.files.create(key: key, body: f)
|
32
33
|
}
|
@@ -42,4 +43,3 @@ module Egads
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|
45
|
-
|
data/lib/egads/version.rb
CHANGED
data/spec/egads_build_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe "Egads::Build" do
|
|
5
5
|
subject { Egads::Build }
|
6
6
|
|
7
7
|
it 'should run the correct tasks' do
|
8
|
-
subject.commands.keys.must_equal %w(check_build
|
8
|
+
subject.commands.keys.must_equal %w(check_build run_before_build_hooks write_revision_file commit_extra_paths make_tarball run_after_build_hooks upload tag_seed)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'takes one argument' do
|
@@ -18,6 +18,9 @@ describe "Egads::Build" do
|
|
18
18
|
rev.required.must_equal false
|
19
19
|
end
|
20
20
|
|
21
|
+
it "exits on failure" do
|
22
|
+
subject.exit_on_failure?.must_equal true
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
describe "Egags::Build instance" do
|
data/spec/egads_extract_spec.rb
CHANGED
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: egads
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Aaron Suggs
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-08-11 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: fog
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - '>='
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - '>='
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: thor
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - '>='
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - '>='
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: rake
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - '>='
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - '>='
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -55,6 +62,7 @@ dependencies:
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: minitest
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
67
|
- - '>='
|
60
68
|
- !ruby/object:Gem::Version
|
@@ -62,6 +70,7 @@ dependencies:
|
|
62
70
|
type: :development
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
75
|
- - '>='
|
67
76
|
- !ruby/object:Gem::Version
|
@@ -105,6 +114,7 @@ files:
|
|
105
114
|
- lib/egads/version.rb
|
106
115
|
- spec/egads_build_spec.rb
|
107
116
|
- spec/egads_check_spec.rb
|
117
|
+
- spec/egads_command_spec.rb
|
108
118
|
- spec/egads_config_spec.rb
|
109
119
|
- spec/egads_extract_spec.rb
|
110
120
|
- spec/egads_release_spec.rb
|
@@ -115,31 +125,33 @@ files:
|
|
115
125
|
- spec/spec_helper.rb
|
116
126
|
homepage: https://github.com/kickstarter/egads
|
117
127
|
licenses: []
|
118
|
-
metadata: {}
|
119
128
|
post_install_message:
|
120
129
|
rdoc_options:
|
121
130
|
- --charset=UTF-8
|
122
131
|
require_paths:
|
123
132
|
- lib
|
124
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
125
135
|
requirements:
|
126
136
|
- - '>='
|
127
137
|
- !ruby/object:Gem::Version
|
128
138
|
version: '0'
|
129
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
130
141
|
requirements:
|
131
142
|
- - '>='
|
132
143
|
- !ruby/object:Gem::Version
|
133
144
|
version: '0'
|
134
145
|
requirements: []
|
135
146
|
rubyforge_project:
|
136
|
-
rubygems_version:
|
147
|
+
rubygems_version: 1.8.25
|
137
148
|
signing_key:
|
138
|
-
specification_version:
|
149
|
+
specification_version: 3
|
139
150
|
summary: Extensible Git Archive Deploy Strategy
|
140
151
|
test_files:
|
141
152
|
- spec/egads_build_spec.rb
|
142
153
|
- spec/egads_check_spec.rb
|
154
|
+
- spec/egads_command_spec.rb
|
143
155
|
- spec/egads_config_spec.rb
|
144
156
|
- spec/egads_extract_spec.rb
|
145
157
|
- spec/egads_release_spec.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 528b9ad77f674b120f2e3d8b64a72e24a4d16f59
|
4
|
-
data.tar.gz: db4985e423a4d2d265f259c4e457423264ed3dd0
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 14506e0b510f897e04de81aa7805719675a79456d933f1bdf59ae3f0b5e9e5dcaca4fdc2416e1f40d48d2c397213e64b5c3a62b70e87125a9f00018a7a70d958
|
7
|
-
data.tar.gz: e4c504af004f30c2bdc69f6f8a883a7c66b865f79f77f2a844019078afbc43d47fe9a3c7f95874fcffe8a0e9b2bcca7a2b79e00bde2f8ae1b7cdd21480b25899
|