automate 0.1.0 → 0.2.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: e38bf3bffda93393bdb00339a81883bb36d87609
4
+ data.tar.gz: 53250b0b10806d1ba84a17953b3a905206e9b679
5
+ SHA512:
6
+ metadata.gz: a824fcb818a73a39bafd3dd59c3c2f7fedd1af800d925dcaf0a6d56301134f256775ce47e354e273d3a294d336438605f19493b5bc9749e285cfc3db7d81d1fb
7
+ data.tar.gz: 9650cbef76835f99b082aeab526273186cbae3768eee91a1ed4729da9065005330bc16ae9977950e65a82e52f8e7d0e8349cc370aab7275b31da41a930b836cc
data/Gemfile CHANGED
@@ -2,13 +2,13 @@ source "http://rubygems.org"
2
2
 
3
3
  group :development do
4
4
  gem "minitest", ">= 0"
5
- gem "yard", "~> 0.8.5"
5
+ gem "yard"
6
6
  gem "redcarpet" # For YARD Markdown formatting
7
- gem "bundler", "~> 1.2.3"
8
- gem "jeweler", "~> 1.8.4"
9
- gem "simplecov", ">= 0"
7
+ gem "bundler"
8
+ gem "jeweler"
9
+ gem "simplecov"
10
10
  gem "minitest-reporters"
11
11
  gem "psych"
12
12
  end
13
13
 
14
- gem "rainbow"
14
+ gem "rainbow", "~> 2.0.0"
@@ -1,48 +1,80 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- ansi (1.4.3)
5
- builder (3.2.0)
6
- git (1.2.5)
7
- hashie (2.0.0)
8
- jeweler (1.8.4)
9
- bundler (~> 1.0)
4
+ addressable (2.3.8)
5
+ ansi (1.5.0)
6
+ builder (3.2.2)
7
+ descendants_tracker (0.0.4)
8
+ thread_safe (~> 0.3, >= 0.3.1)
9
+ docile (1.1.5)
10
+ faraday (0.9.1)
11
+ multipart-post (>= 1.2, < 3)
12
+ git (1.2.9.1)
13
+ github_api (0.12.3)
14
+ addressable (~> 2.3)
15
+ descendants_tracker (~> 0.0.4)
16
+ faraday (~> 0.8, < 0.10)
17
+ hashie (>= 3.3)
18
+ multi_json (>= 1.7.5, < 2.0)
19
+ nokogiri (~> 1.6.3)
20
+ oauth2
21
+ hashie (3.4.1)
22
+ highline (1.7.2)
23
+ jeweler (2.0.1)
24
+ builder
25
+ bundler (>= 1.0)
10
26
  git (>= 1.2.5)
27
+ github_api
28
+ highline (>= 1.6.15)
29
+ nokogiri (>= 1.5.10)
11
30
  rake
12
31
  rdoc
13
- json (1.7.7)
14
- minitest (4.6.1)
15
- minitest-reporters (0.14.7)
32
+ json (1.8.2)
33
+ jwt (1.5.0)
34
+ mini_portile (0.6.2)
35
+ minitest (5.6.1)
36
+ minitest-reporters (1.0.16)
16
37
  ansi
17
38
  builder
18
- minitest (>= 2.12, < 5.0)
19
- powerbar
20
- multi_json (1.6.1)
21
- powerbar (1.0.11)
22
- ansi (~> 1.4.0)
23
- hashie (>= 1.1.0)
24
- psych (1.3.4)
25
- rainbow (1.1.4)
26
- rake (10.0.3)
27
- rdoc (4.0.0)
39
+ minitest (>= 5.0)
40
+ ruby-progressbar
41
+ multi_json (1.11.0)
42
+ multi_xml (0.5.5)
43
+ multipart-post (2.0.0)
44
+ nokogiri (1.6.6.2)
45
+ mini_portile (~> 0.6.0)
46
+ oauth2 (1.0.0)
47
+ faraday (>= 0.8, < 0.10)
48
+ jwt (~> 1.0)
49
+ multi_json (~> 1.3)
50
+ multi_xml (~> 0.5)
51
+ rack (~> 1.2)
52
+ psych (2.0.13)
53
+ rack (1.6.1)
54
+ rainbow (2.0.0)
55
+ rake (10.4.2)
56
+ rdoc (4.2.0)
28
57
  json (~> 1.4)
29
- redcarpet (2.2.2)
30
- simplecov (0.7.1)
31
- multi_json (~> 1.0)
32
- simplecov-html (~> 0.7.1)
33
- simplecov-html (0.7.1)
34
- yard (0.8.5)
58
+ redcarpet (3.2.3)
59
+ ruby-progressbar (1.7.5)
60
+ simplecov (0.10.0)
61
+ docile (~> 1.1.0)
62
+ json (~> 1.8)
63
+ simplecov-html (~> 0.10.0)
64
+ simplecov-html (0.10.0)
65
+ thread_safe (0.3.5)
66
+ yard (0.8.7.6)
35
67
 
36
68
  PLATFORMS
37
69
  ruby
38
70
 
39
71
  DEPENDENCIES
40
- bundler (~> 1.2.3)
41
- jeweler (~> 1.8.4)
72
+ bundler
73
+ jeweler
42
74
  minitest
43
75
  minitest-reporters
44
76
  psych
45
- rainbow
77
+ rainbow (~> 2.0.0)
46
78
  redcarpet
47
79
  simplecov
48
- yard (~> 0.8.5)
80
+ yard
data/README.md CHANGED
@@ -11,35 +11,17 @@ These functionalities will improve as "automate" is being used, so if you see so
11
11
 
12
12
 
13
13
 
14
- ## Example
14
+ ## Examples
15
15
 
16
- Here's a very short example which creates a file and writes a random number into it (also to be found in `examples/simple.rb`):
17
-
18
- c = Automate::Chain.which("Serves as an example") do
19
-
20
- go "Create a file in the working directory" do
21
- demand :filename
22
- run "touch #{_filename}"
23
- end
24
-
25
- go "Write a random number into the file" do
26
- pass :number, Random.rand(100)
27
- run "echo #{_number} > #{_filename}"
28
- end
29
-
30
- go "Demonstrate a failed chain link" do
31
- run "this_command_doesnt_even_exist #{_number}"
32
- end
33
-
34
- end
16
+ Some simple examples can be found in the `examples/` directory.
35
17
 
36
18
 
37
19
 
38
20
  ## Usage
39
21
 
40
- To begin with, `Automate::Chain.which("Description of command chain") creates a new command chain, which is defined by the block passed to it.
22
+ To begin with, `Automate::Chain.which("Description of command chain")` creates a new command chain, which is defined by the block passed to it.
41
23
 
42
- Inside said block, "chain links" are defined using the `go` method. Each chain link should consist of an action which can be described in a few words, thus making the entire chain a series of atomic, or close to atomic operations:
24
+ Inside said block, "chain links" are defined using the `go` method. Each chain link should consist of an action which can be described in a few words, thus making the entire chain a series of small operations:
43
25
 
44
26
  # good
45
27
  go "Clone the git repository"
@@ -47,21 +29,62 @@ Inside said block, "chain links" are defined using the `go` method. Each chain l
47
29
  # bad
48
30
  go "Download, compile and install the linux kernel"
49
31
 
50
- The chain link block defines its behavior, and the following methods are available within:
32
+ The chain link block defines its behavior, and the following methods are available within (and should be used in this order):
51
33
 
52
34
  * `demand :parameter1, :parameter2` - Demand one or more parameters from the previous chain link (or if there is none, from the initial run command).
53
35
 
54
- * `pass :parameter, value` - Pass a parameter to the next chain link.
36
+ * `pass :parameter, <value>` - Pass a parameter to the next chain link.
37
+
38
+ * `error <msg>` - Abort the chain with the specified error message.
55
39
 
56
40
  * `run "some shell command"` - Invokes a shell command, returning its result (including everything written to stderr! If you don't want to capture stderr, pass "false" as `run's` second parameter)
57
41
 
42
+ One can also create "deferred" chain links. These are executed (in reverse order) as soon as all regular commands have been executed, but also if any of them fails:
43
+
44
+ go "Create temporary file" do
45
+ demand :tmpfile
46
+
47
+ defer "Delete temporary file" do
48
+ run "rm #{_tmpfile}"
49
+ end
50
+
51
+ run "touch #{_tmpfile}"
52
+ end
53
+
54
+
55
+ ### Running a command chain
56
+
57
+ After creation, a chain can be run like so:
58
+
59
+ c = Automate::Chain.which("...") do
60
+ [...]
61
+ end
62
+
63
+ result = c.run({:param1 => 123, :param2 => "foobar"})
64
+
65
+ The result will be a hash containing all parameters passed to the initial chain or passed by any of the chain links, or `false` in case of an error in the chain.
66
+
67
+
68
+
69
+ ## Other features
70
+
71
+ * You can step through all chain links by setting the `AUTOMATE_STEP` environment variable
72
+
73
+
74
+
75
+ ## Caveats
76
+
77
+ * `defer` blocks MUST be defined before any command that might fail. This is a result of the current implementation of `automate`, and might be improved in a future version. Until then, the way is to put any `defer` block right at the start of a command, after any `demand` invocations.
78
+
79
+
58
80
 
81
+ ## Feature ideas
59
82
 
83
+ * "Literate automate", e.g. generating a automate-based ruby script from a markdown (or similar) file to properly self-documenting scripts.
60
84
 
61
- ## Future features
85
+ * make it possible to write "plugins" that provide pre-defined commands, e.g. "create_file" could automatically run "touch file", check if the file has actually been crated and create a defer for "rm file".
62
86
 
63
- * Stepping through the script, i.e. execute link by link (especially useful for debugging)
64
- * Add roll back actions for a link, which are only executed if said link fails.
87
+ * `run` should not return `false` on error. Perhaps a `:chain_error` element in the hash should be set or something.
65
88
 
66
89
 
67
90
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -0,0 +1,81 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: automate 0.2.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "automate"
9
+ s.version = "0.2.0"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Lucas Jen\u{df}"]
14
+ s.date = "2015-05-22"
15
+ s.description = "The automate Gem provides a very simple DSL for writing command line automations, providing nice-to-have features such as error handling so that you don't have to implement it over and over again :)"
16
+ s.email = "public@x3ro.de"
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.md",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "automate.gemspec",
30
+ "examples/git-copy-repo.rb",
31
+ "examples/simple.rb",
32
+ "lib/automate.rb",
33
+ "lib/automate/chain.rb",
34
+ "lib/automate/chain_link.rb",
35
+ "lib/automate/errors.rb",
36
+ "lib/automate/messenger.rb",
37
+ "test/helper.rb",
38
+ "test/test_automate.rb"
39
+ ]
40
+ s.homepage = "http://github.com/x3ro/automate"
41
+ s.licenses = ["MIT"]
42
+ s.rubygems_version = "2.2.2"
43
+ s.summary = "Automate helps you automating all your favorite shell tasks"
44
+
45
+ if s.respond_to? :specification_version then
46
+ s.specification_version = 4
47
+
48
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
+ s.add_runtime_dependency(%q<rainbow>, ["~> 2.0.0"])
50
+ s.add_development_dependency(%q<minitest>, [">= 0"])
51
+ s.add_development_dependency(%q<yard>, [">= 0"])
52
+ s.add_development_dependency(%q<redcarpet>, [">= 0"])
53
+ s.add_development_dependency(%q<bundler>, [">= 0"])
54
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
55
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
56
+ s.add_development_dependency(%q<minitest-reporters>, [">= 0"])
57
+ s.add_development_dependency(%q<psych>, [">= 0"])
58
+ else
59
+ s.add_dependency(%q<rainbow>, ["~> 2.0.0"])
60
+ s.add_dependency(%q<minitest>, [">= 0"])
61
+ s.add_dependency(%q<yard>, [">= 0"])
62
+ s.add_dependency(%q<redcarpet>, [">= 0"])
63
+ s.add_dependency(%q<bundler>, [">= 0"])
64
+ s.add_dependency(%q<jeweler>, [">= 0"])
65
+ s.add_dependency(%q<simplecov>, [">= 0"])
66
+ s.add_dependency(%q<minitest-reporters>, [">= 0"])
67
+ s.add_dependency(%q<psych>, [">= 0"])
68
+ end
69
+ else
70
+ s.add_dependency(%q<rainbow>, ["~> 2.0.0"])
71
+ s.add_dependency(%q<minitest>, [">= 0"])
72
+ s.add_dependency(%q<yard>, [">= 0"])
73
+ s.add_dependency(%q<redcarpet>, [">= 0"])
74
+ s.add_dependency(%q<bundler>, [">= 0"])
75
+ s.add_dependency(%q<jeweler>, [">= 0"])
76
+ s.add_dependency(%q<simplecov>, [">= 0"])
77
+ s.add_dependency(%q<minitest-reporters>, [">= 0"])
78
+ s.add_dependency(%q<psych>, [">= 0"])
79
+ end
80
+ end
81
+
@@ -7,17 +7,37 @@ require 'automate'
7
7
 
8
8
  c = Automate::Chain.which("Serves as an example") do
9
9
 
10
+ go "Make sure the target does not exist yet" do
11
+ run "[[ ! -e #{_filename} ]]"
12
+ end
13
+
10
14
  go "Create a file in the working directory" do
11
15
  demand :filename
16
+ defer "Clean up temporary file" do
17
+ run "rm #{_filename}"
18
+ end
19
+
12
20
  run "touch #{_filename}"
13
21
  end
14
22
 
15
- go "Write a random number into the file" do
23
+ go "Generate random number" do
16
24
  pass :number, Random.rand(100)
25
+ end
26
+
27
+ go "Write a random number into the file" do
17
28
  run "echo #{_number} > #{_filename}"
18
29
  end
19
30
 
31
+ # A raised exception will also be caught, letting the chain fail.
32
+ # go "raise something" do
33
+ # raise "oh noes"
34
+ # end
35
+
20
36
  go "Demonstrate a failed chain link" do
37
+ defer "Demonstrate defer" do
38
+ run "echo 'Look ma, defer'"
39
+ end
40
+
21
41
  run "this_command_doesnt_even_exist #{_number}"
22
42
  end
23
43
 
@@ -26,29 +26,70 @@ module Automate
26
26
  def run(args = {})
27
27
  notice "About to run command chain which '#{@task}'"
28
28
 
29
- @cmd_list.each_with_index do |cmd, index|
29
+ success = true
30
+ begin
31
+ args = run_command_list(@cmd_list, args)
32
+ rescue ChainFailedError => e
33
+ fail("Chain link ##{e.chain} (#{e.description}) failed.")
34
+ success = false
35
+ end
36
+
37
+ notice "Running deferred commands"
38
+
39
+ # Note that deferred commands are executed in reverse order, so that
40
+ # the cleanup actions for the last command is executed first.
41
+ # E.g. if the definition order is as follows:
42
+ #
43
+ # C1, C1_defer, C2, C3, C4, C4_defer
44
+ #
45
+ # The execution order will be
46
+ #
47
+ # C1, C2, C3, C4, C4_defer, C1_defer
48
+ #
49
+ args = run_command_list(@defer_list.reverse, args)
50
+ if !success
51
+ false
52
+ else
53
+ args
54
+ end
55
+
56
+ rescue ChainFailedError => e
57
+ fail("Defer command ##{e.chain} (#{e.description}) failed.")
58
+ false
59
+ end
60
+
61
+
62
+ def run_command_list(list, args)
63
+ list.each_with_index do |cmd, index|
30
64
  desc, proc = cmd
31
65
  success "#{timestamp} // Running link ##{index+1} - #{desc}"
32
66
 
33
67
  error = false
34
68
  begin
35
- ret, out = ChainLink.invoke(proc, args)
36
- rescue ChainFailedError, ChainLinkFailedError => e
69
+ ret, out, chain_link_defer = ChainLink.invoke(proc, args)
70
+ @defer_list += chain_link_defer
71
+ rescue ChainLinkFailedError => e
72
+ # TODO: Storing the defer_list in the ChainLinkFailedError is awful,
73
+ # and shall be fixed when there's time to remove this entire exception-based
74
+ # "communication" between chain and chain link.
75
+ @defer_list += e.defer_list
37
76
  error = true
38
77
  end
39
78
  raise ChainFailedError.new(index + 1, desc) if ret == false || error == true
40
79
 
41
-
42
80
  # Pass the arguments from the last iteration, overwriting everything that
43
81
  # was passed from the current one.
44
82
  args.merge! out
83
+
84
+ # Make it possible to run commands step by step
85
+ if !ENV["AUTOMATE_STEP"].nil?
86
+ puts "Press a key to continue..."
87
+ $stdin.gets
88
+ puts "\n"
89
+ end
45
90
  end
46
91
 
47
92
  args
48
-
49
- rescue ChainFailedError => e
50
- fail("Chain link ##{e.chain} (#{e.description}) failed. Aborting.")
51
- false
52
93
  end
53
94
 
54
95
 
@@ -62,6 +103,7 @@ module Automate
62
103
  def initialize(task)
63
104
  @task = task
64
105
  @cmd_list = []
106
+ @defer_list = []
65
107
  end
66
108
 
67
109
  def timestamp
@@ -20,18 +20,19 @@ module Automate
20
20
  #
21
21
  def invoke(proc)
22
22
  ret = instance_exec(&proc)
23
- [ret, @out_args]
23
+ [ret, @out_args, @defer_list]
24
24
 
25
25
  rescue UnmetDemandError => e
26
26
  fail "Required argument '#{e.demand}', but was not given."
27
- raise ChainLinkFailedError.new
27
+ raise ChainLinkFailedError.new(@defer_list)
28
28
  rescue CmdFailedError => e
29
29
  fail e.message
30
- raise ChainLinkFailedError.new
30
+ raise ChainLinkFailedError.new(@defer_list)
31
+ rescue => e
32
+ fail "Chain link raised an exception: \n #{e} \n #{e.backtrace.join("\n")}"
33
+ raise ChainLinkFailedError.new(@defer_list)
31
34
  end
32
35
 
33
-
34
-
35
36
  # ==========
36
37
  # Public API
37
38
  # ==========
@@ -50,7 +51,7 @@ module Automate
50
51
  end
51
52
  end
52
53
 
53
- raise CmdFailedError.new("Command '#{cmd}' had exit status != 0.") if $? != 0
54
+ raise CmdFailedError.new("Command '#{cmd}' had exit status #{$?.to_i}") if $? != 0
54
55
  out
55
56
  end
56
57
 
@@ -67,6 +68,15 @@ module Automate
67
68
  end
68
69
  end
69
70
 
71
+ # Manually abort a chain because of an error
72
+ def error(msg)
73
+ raise CmdFailedError.new(msg)
74
+ end
75
+
76
+ def defer(desc, &block)
77
+ @defer_list.push [desc, block]
78
+ end
79
+
70
80
  # Implement method_missing so that we can address passed variables using the
71
81
  # `_variablename` shorthand within a chain link.
72
82
  def method_missing(method, *args, &block)
@@ -98,6 +108,7 @@ module Automate
98
108
  def initialize(args)
99
109
  @in_args = args
100
110
  @out_args = {}
111
+ @defer_list = []
101
112
  end
102
113
 
103
114
  end
@@ -1,6 +1,13 @@
1
1
  module Automate
2
2
 
3
- class ChainLinkFailedError < Exception; end
3
+ class ChainLinkFailedError < Exception
4
+ attr_reader :defer_list
5
+ def initialize(defer_list)
6
+ super
7
+ @defer_list = defer_list
8
+ end
9
+ end
10
+
4
11
  class CmdFailedError < Exception; end
5
12
 
6
13
  class ChainFailedError < Exception
@@ -1,3 +1,5 @@
1
+ require 'rainbow/ext/string'
2
+
1
3
  module Automate
2
4
 
3
5
  module Messenger
@@ -1,6 +1,7 @@
1
- require 'rubygems'
2
-
1
+ require 'simplecov'
2
+ SimpleCov.start
3
3
 
4
+ require 'rubygems'
4
5
  require 'bundler'
5
6
  begin
6
7
  Bundler.setup(:default, :development)
@@ -11,21 +12,17 @@ rescue Bundler::BundlerError => e
11
12
  end
12
13
 
13
14
 
14
- require 'minitest/unit'
15
+ require 'minitest/autorun'
15
16
  require "minitest/reporters"
16
17
  MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new
17
18
 
18
19
 
19
- require 'simplecov'
20
- SimpleCov.start
21
-
22
-
23
20
  $LOAD_PATH.unshift(File.dirname(__FILE__))
24
21
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
25
22
  require 'automate'
26
23
 
27
24
 
28
- class MiniTest::Unit::TestCase
25
+ class MiniTest::Test
29
26
  def setup
30
27
  @original_stdout = $stdout
31
28
  $stdout = StringIO.new
@@ -37,4 +34,4 @@ class MiniTest::Unit::TestCase
37
34
  end
38
35
 
39
36
 
40
- MiniTest::Unit.autorun
37
+ MiniTest.autorun
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestAutomate < MiniTest::Unit::TestCase
3
+ class TestAutomate < MiniTest::Test
4
4
 
5
5
  def test_single_element_chain
6
6
  c = Automate::Chain.which("Has a single element") do
@@ -75,15 +75,13 @@ class TestAutomate < MiniTest::Unit::TestCase
75
75
  end
76
76
 
77
77
 
78
- def test_method_missing_in_chain_link
79
- assert_raises(NameError) do
80
- c = Automate::Chain.which("checks method missing") do
81
- go "Raise name error" do
82
- wobblewobble
83
- end
78
+ def test_exception_in_chain_link
79
+ c = Automate::Chain.which("checks method missing") do
80
+ go "Raise name error" do
81
+ wobblewobble
84
82
  end
85
- c.run
86
83
  end
84
+ assert_equal false, c.run
87
85
  end
88
86
 
89
87
 
@@ -99,6 +97,17 @@ class TestAutomate < MiniTest::Unit::TestCase
99
97
  assert_equal "4242", result[:output]
100
98
  end
101
99
 
100
+ def test_parameter_passed_through
101
+ c = Automate::Chain.which("...") do
102
+ go "..." do
103
+ demand :input
104
+ end
105
+ end
106
+
107
+ result = c.run({:input => 42})
108
+ assert_equal({:input => 42}, result)
109
+ end
110
+
102
111
 
103
112
  def test_access_variables_just_passed
104
113
  c = Automate::Chain.which("Run shell command") do
@@ -112,4 +121,92 @@ class TestAutomate < MiniTest::Unit::TestCase
112
121
  assert_equal 43, result[:output]
113
122
  end
114
123
 
124
+
125
+ def test_manually_abort_chain_with_error
126
+ proc = lambda { error "test" }
127
+ assert_raises(Automate::ChainLinkFailedError) do
128
+ Automate::ChainLink.invoke(proc, [])
129
+ end
130
+ end
131
+
132
+
133
+ def test_defer_invocation
134
+ c = Automate::Chain.which("Has a single element + defer") do
135
+ go "Set some variable" do
136
+ defer "Alter the variable" do
137
+ pass :foo, 24
138
+ end
139
+
140
+ pass :foo, 42
141
+ end
142
+ end
143
+ assert_equal({:foo => 24}, c.run)
144
+ end
145
+
146
+
147
+ def test_defer_invocation_order
148
+ c = Automate::Chain.which("Test chain") do
149
+ go "Set some variable" do
150
+ defer "Change that variable, this should run last" do
151
+ pass :foo, 1000
152
+ end
153
+
154
+ pass :foo, 42
155
+ end
156
+
157
+ go "This sets the variable too" do
158
+ defer "This should have no effect on foo's return" do
159
+ pass :foo, 9999
160
+ end
161
+
162
+ pass :foo, 24
163
+ end
164
+ end
165
+ assert_equal({:foo => 1000}, c.run)
166
+ end
167
+
168
+
169
+ def test_failing_defer_command
170
+ c = Automate::Chain.which("Has an error") do
171
+ go "This works" do
172
+ defer "But this doesn't" do
173
+ run "this_doesnt_even_exist___"
174
+ end
175
+
176
+ run "echo -n 'hi'"
177
+ end
178
+ end
179
+
180
+ assert_equal false, c.run
181
+ end
182
+
183
+
184
+ def test_dont_execute_defer_for_untouched_chain
185
+ should_be_invoked = nil
186
+ should_not_be_invoked = false
187
+
188
+ c = Automate::Chain.which("Test chain") do
189
+ go "Set some variable" do
190
+ defer "this should run last" do
191
+ should_be_invoked = true
192
+ end
193
+
194
+ run "this_doesnt_even_exist___"
195
+ end
196
+
197
+ go "Chain that is never executed" do
198
+ defer "This should have no effect on foo's return" do
199
+ should_not_be_invoked = true
200
+ pass :ohnoes, true
201
+ end
202
+
203
+ pass :foo, 42
204
+ end
205
+ end
206
+
207
+ assert_equal(false, c.run)
208
+ assert_equal(false, should_not_be_invoked)
209
+ assert_equal(true, should_be_invoked)
210
+ end
211
+
115
212
  end
metadata CHANGED
@@ -1,158 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: automate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Lucas Jenß
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-25 00:00:00.000000000 Z
11
+ date: 2015-05-22 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rainbow
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '0'
19
+ version: 2.0.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '0'
26
+ version: 2.0.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: minitest
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: yard
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
- version: 0.8.5
47
+ version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
- version: 0.8.5
54
+ version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: redcarpet
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: bundler
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ~>
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
- version: 1.2.3
75
+ version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ~>
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
- version: 1.2.3
82
+ version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: jeweler
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ~>
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
- version: 1.8.4
89
+ version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ~>
94
+ - - ">="
108
95
  - !ruby/object:Gem::Version
109
- version: 1.8.4
96
+ version: '0'
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: simplecov
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - ! '>='
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
103
  version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ! '>='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
110
  version: '0'
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: minitest-reporters
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - ! '>='
115
+ - - ">="
132
116
  - !ruby/object:Gem::Version
133
117
  version: '0'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - ! '>='
122
+ - - ">="
140
123
  - !ruby/object:Gem::Version
141
124
  version: '0'
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: psych
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
- - - ! '>='
129
+ - - ">="
148
130
  - !ruby/object:Gem::Version
149
131
  version: '0'
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
- - - ! '>='
136
+ - - ">="
156
137
  - !ruby/object:Gem::Version
157
138
  version: '0'
158
139
  description: The automate Gem provides a very simple DSL for writing command line
@@ -165,13 +146,14 @@ extra_rdoc_files:
165
146
  - LICENSE.txt
166
147
  - README.md
167
148
  files:
168
- - .document
149
+ - ".document"
169
150
  - Gemfile
170
151
  - Gemfile.lock
171
152
  - LICENSE.txt
172
153
  - README.md
173
154
  - Rakefile
174
155
  - VERSION
156
+ - automate.gemspec
175
157
  - examples/git-copy-repo.rb
176
158
  - examples/simple.rb
177
159
  - lib/automate.rb
@@ -184,29 +166,25 @@ files:
184
166
  homepage: http://github.com/x3ro/automate
185
167
  licenses:
186
168
  - MIT
169
+ metadata: {}
187
170
  post_install_message:
188
171
  rdoc_options: []
189
172
  require_paths:
190
173
  - lib
191
174
  required_ruby_version: !ruby/object:Gem::Requirement
192
- none: false
193
175
  requirements:
194
- - - ! '>='
176
+ - - ">="
195
177
  - !ruby/object:Gem::Version
196
178
  version: '0'
197
- segments:
198
- - 0
199
- hash: 3608312016429537767
200
179
  required_rubygems_version: !ruby/object:Gem::Requirement
201
- none: false
202
180
  requirements:
203
- - - ! '>='
181
+ - - ">="
204
182
  - !ruby/object:Gem::Version
205
183
  version: '0'
206
184
  requirements: []
207
185
  rubyforge_project:
208
- rubygems_version: 1.8.24
186
+ rubygems_version: 2.2.2
209
187
  signing_key:
210
- specification_version: 3
188
+ specification_version: 4
211
189
  summary: Automate helps you automating all your favorite shell tasks
212
190
  test_files: []