egads 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/egads CHANGED
@@ -1,5 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
- # TODO: remove this
3
- $: << './lib'
4
2
  require 'egads'
5
3
  Egads::Command.start
@@ -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
@@ -2,9 +2,11 @@ require 'yaml'
2
2
  require 'fog'
3
3
  require 'thor'
4
4
  require 'benchmark'
5
+ require 'pathname'
5
6
 
6
7
  module Egads; end
7
8
 
9
+ require 'egads/version'
8
10
  require 'egads/config'
9
11
  require 'egads/s3_tarball'
10
12
  require 'egads/group'
@@ -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.check
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 "Checks that a deployable tarball is on S3; creates it if missing"
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
@@ -1,53 +1,76 @@
1
1
  module Egads
2
2
  class Build < Group
3
3
  include Thor::Actions
4
- include Egads::LocalHelpers
4
+ include LocalHelpers
5
5
 
6
- desc "[local] Compiles a deployable tarball of the current commit and uploads it to S3"
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, "Tarball for #{sha} already exists. Pass --force to rebuild."
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 make_git_archive
24
- say_status :build, "Making tarball for #{sha}", :yellow
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 append_revision_file
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 run_after_build_hooks
35
- run_hooks_for(:build,:after)
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 append_extra_paths
39
- extra_paths = Config.build_extra_paths
40
- if extra_paths.any?
41
- run_with_code "tar -uf #{tarball.local_tar_path} #{extra_paths * " "}"
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 gzip_archive
46
- run_with_code "gzip -9f #{tarball.local_tar_path}"
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", capture: true).strip
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 download
14
- if should_download?
15
- say_status :download, "Downloading tarball for #{sha}", :yellow
16
- FileUtils.mkdir_p(release_dir)
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(path, 'w') {|f| f << tarball.contents }
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, "Tarball already downloaded. Use --force to overwrite"
70
+ say_status :done, "#{type} tarball already downloaded. Use --force to overwrite"
24
71
  end
25
72
  end
26
73
 
27
- def extract
28
- # Check revision file to see if tarball is already extracted
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
- inside(release_dir) { run_with_code "tar -zxf #{path} 2>/dev/null" }
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
- def mark_as_extracted
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
- def path
48
- File.join(release_dir, "#{sha}.tar.gz")
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 tarball
52
- @tarball ||= S3Tarball.new(sha, true)
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.exists?(extract_flag_path)
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
- symlink_directory(dir, release_to)
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
@@ -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
 
@@ -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
- dirs = Dir.glob('*').sort_by{|path| File.mtime(path) }.reverse[n..-1].to_a
10
- dirs.each do |dir|
11
- say_status :trim, "Deleting #{dir}"
12
- FileUtils.rm_rf(dir)
13
- end
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
 
@@ -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.local_gzipped_path
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, config={})
8
- result = nil
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
- result = run(command, config.merge(capture: true))
11
- end
12
- say_status :done, "Finished in %.1f seconds" % duration
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
- if $? != 0
15
- raise CommandError.new("`#{command}` failed with exit status #{$?.exitstatus.inspect}")
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
- result
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
- say run_with_code(command, capture: true)
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
- FileUtils.ln_s(src, dest)
50
+ File.symlink(src, dest)
37
51
  end
38
52
 
39
53
  def symlink(src, dest)
@@ -1,5 +1,5 @@
1
1
  module Egads
2
- # Some helper methods for `check` and `upload`
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
@@ -1,9 +1,10 @@
1
1
  module Egads
2
2
  class S3Tarball
3
- attr_reader :sha, :remote
4
- def initialize(sha, remote = false)
5
- @sha = 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
- [config.s3_prefix, "#{sha}.tar.gz"].compact * '/'
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 local_gzipped_path
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
@@ -1,3 +1,3 @@
1
1
  module Egads
2
- VERSION = '2.0.0'
2
+ VERSION = '3.0.0'
3
3
  end
@@ -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 make_git_archive append_revision_file run_after_build_hooks append_extra_paths gzip_archive upload)
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
@@ -0,0 +1,8 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe "Egads::Command" do
4
+ subject { Egads::Command }
5
+ it 'should exit on failure' do
6
+ subject.exit_on_failure?.must_equal true
7
+ end
8
+ end
@@ -5,6 +5,6 @@ describe "Egads::Extract" do
5
5
  subject { Egads::Extract }
6
6
 
7
7
  it 'should run the correct tasks' do
8
- subject.commands.keys.must_equal %w(setup_environment download extract mark_as_extracted)
8
+ subject.commands.keys.must_equal %w(setup_environment extract)
9
9
  end
10
10
  end
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: 2.0.0
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-07-11 00:00:00.000000000 Z
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: 2.0.2
147
+ rubygems_version: 1.8.25
137
148
  signing_key:
138
- specification_version: 4
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