automate 0.1.0 → 0.2.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.
@@ -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: []