buildem 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ require 'autotest/growl'
2
+ require 'autotest/fsevent'
3
+
4
+ Autotest.add_hook(:initialize) {|at|
5
+ at.add_exception %r{^\.git}
6
+ at.add_exception %r{^./tmp}
7
+ at.clear_mappings
8
+ at.add_mapping(%r{^lib/buildem/.*\.rb$}) {|f, _|
9
+ item = f.split("/").last.gsub(".rb","")
10
+ Dir["spec/unit/#{item}_spec.rb"]
11
+ }
12
+ nil
13
+ }
@@ -0,0 +1,34 @@
1
+ Worker configuration, and unordered tasks
2
+ -----------------------------------------
3
+
4
+ $configuration.workers = 2
5
+
6
+ run "initialize.sh"
7
+ run "clean.sh"
8
+
9
+ unorderd do
10
+ queued_run "job1.sh"
11
+ queued_run "job2.sh"
12
+ queued_run "job3.sh"
13
+ run "some_task_in_the_middle_of_queue.sh" # this will block all of the queued_run calls after this
14
+ queued_run "job4.sh"
15
+ queued_run "job5.sh"
16
+ queued_run "job6.sh"
17
+ end
18
+
19
+ run "do_something_at_the_end.sh"
20
+ This example will execute job 1 - 3 in any order two at a time, hit some\_task\_in\_the\_middle\_of\_queue run that wait for it to complete and then continue executing job 4 - 6 two at a time.
21
+
22
+ ---
23
+
24
+
25
+ Worker configuration, and unordered tasks with options
26
+ ------------------------------------------------------
27
+
28
+ run "initialize.sh"
29
+ run "clean.sh", :retry_amount => 10 # The default exitstatus for commands is 0, when specifying retry amount of 10 if the run command does not return 0 it will retry up to 10 times.
30
+ run "do_something_at_the_end.sh", {:retry_amount => 10, :retry_condition => 99} # Same as above, but is considered successful if the exitstatus is 99 due to the supplied retry_condition.
31
+ run "danger_danger_danger", :quit_on_error => false # If a task has explosive behavior (It causes an exception) :quit_on_error => false can be supplied as an option to continue execution
32
+ # regardless of problems.
33
+
34
+ These options can be applied to both queued_run, and run jobs.
data/Gemfile CHANGED
@@ -2,3 +2,10 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in buildem.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem "rspec"
8
+ gem "autotest"
9
+ gem "autotest-growl"
10
+ gem "autotest-fsevent"
11
+ end
@@ -0,0 +1,54 @@
1
+ Build'em quick, Build'em right
2
+ ==============================
3
+
4
+ Build'em is a small little script parser that is intended for large build systems.
5
+ Build'em is still very young :) so be careful using it. Input is always welcome and if there is a feature that you just half to have i'd probably do it.
6
+
7
+
8
+ Features:
9
+ ---------
10
+
11
+ Execution:
12
+ Scripts go in a plain text file, I use my\_very\_important\_task.buildem
13
+ and then simply call buildem my\_very\_important\_task.buildem
14
+
15
+ * Build'em supports sequential tasks (tasks that go in order)
16
+
17
+ Example:
18
+ run "./task.sh"
19
+ run "./another.sh" #another.sh waits for task.sh to complete
20
+
21
+ * Build'em supports a work queue, what does this mean?
22
+ This means that you can run tasks concurrently, easily.
23
+
24
+ Example:
25
+
26
+ unorderd do
27
+ queued_run "./some_task.sh"
28
+ queued_run "./some_task1.sh" # All of these items will be executed at the same time
29
+ queued_run "./some_task2.sh"
30
+ end
31
+
32
+ *IMPORTANT* All queued\_run tasks must be inside of an unorderd block if you want them to run at the same time. If you use run for a task, it will block to complete.
33
+ That being said you can inject ordered tasks in the middle of unorderd tasks by using run instead of using qeueued_run if you wish to.
34
+
35
+ * Configuration
36
+ To set the worker amount for unorderd tasks before the unorderd block do $configuration.workers = 10 to get 10 nano-bots working for you.
37
+
38
+ Example:
39
+
40
+ $configuration.workers = 5
41
+ unorderd do
42
+ ....
43
+ end
44
+
45
+ This will give you 5 nano-bots for your unordered tasks
46
+
47
+
48
+ optional run and queued_run options
49
+ --------------------------
50
+ * :retry\_amount (Integer that specifies that you want to retry the execution of the provided command. Default is 1 execution.)
51
+ * :retry\_condition (Integer, regular expression, or string that specifies what a good execution is. Default is 0 if not specified.)
52
+ * :quit\_on\_error (Boolean that specifies if build'em should quit when an exception happens executing the provided command. Default is true)
53
+
54
+
@@ -3,6 +3,16 @@ require 'buildem'
3
3
  require 'fileutils'
4
4
  include FileUtils
5
5
 
6
+ module Kernel
7
+ def exitstatus
8
+ $?
9
+ end
10
+
11
+ def run_command(cmd)
12
+ `#{cmd}`
13
+ end
14
+ end
15
+
6
16
  def windows?
7
17
  return java.lang.System.get_property("os.name")[/windows/i] if RUBY_PLATFORM == "java"
8
18
  return RUBY_PLATFORM[/mswin/]
@@ -0,0 +1,15 @@
1
+ class BuildEm::ConditionMatcher
2
+ def match(return_code, output, condition)
3
+ case condition
4
+ when Regexp
5
+ return false unless output =~ condition
6
+ when String
7
+ return false unless output == condition
8
+ when Fixnum
9
+ return false unless return_code == condition
10
+ else
11
+ raise "unsupported type for condition"
12
+ end
13
+ return true
14
+ end
15
+ end
@@ -1,11 +1,14 @@
1
1
  require "buildem/base"
2
+ require "buildem/condition_matcher"
2
3
 
3
4
  class BuildEm::Executor
4
5
 
5
6
  attr_accessor :argz
6
7
 
7
- def initialize(args)
8
+ def initialize(args, kernel=Kernel, matcher=BuildEm::ConditionMatcher.new)
9
+ @kernel = kernel
8
10
  @argz ||= args
11
+ @matcher = matcher
9
12
  end
10
13
 
11
14
  def name
@@ -13,17 +16,32 @@ class BuildEm::Executor
13
16
  end
14
17
 
15
18
  def run
16
- # queued_run "publish.sh", :output => "publish_output.out", :errors => "publish_errors.out"
19
+ optz = argz[1]
20
+ quit_on_error = (optz[:quit_on_error].nil? ? true : optz[:quit_on_error])
21
+ retry_amount = (optz[:retry_amount].nil? ? 1 : optz[:retry_amount])
22
+ condition = (optz[:retry_condition].nil? ? 0 : optz[:retry_condition])
23
+ executions = 0
17
24
  begin
18
- puts `#{argz[0]} #{redirect_standard_err_and_out}`
25
+ puts "retrying command [#{argz[0]}]" if executions > 0
26
+ executions += 1
27
+ @comamnd_output = @kernel.run_command("#{argz[0]}")
28
+ @command_exitstatus = @kernel.exitstatus
29
+ match = @matcher.match(@command_exitstatus, @comamnd_output, condition)
30
+ puts @comamnd_output if match
31
+ return @command_exitstatus if match
19
32
  rescue Exception => e
20
- puts e
21
- end
33
+ if quit_on_error
34
+ raise e
35
+ else
36
+ #put to output log or specified log
37
+ end
38
+ end while executions < retry_amount
39
+ @command_exitstatus
22
40
  end
23
41
 
24
42
  private
25
43
 
26
- def redirect_standard_err_and_out
44
+ def redirect_standard_error_and_out
27
45
  ""
28
46
  end
29
47
 
@@ -15,10 +15,10 @@ module Kernel
15
15
  end
16
16
  $pool.start
17
17
  $pool.shutdown
18
+ puts "Finished #{$jobs.size} unordered jobs"
18
19
  end
19
20
 
20
21
  def queued_run(command, optz = {})
21
- optz = {:foo => "bar", :moo => "cow"}
22
22
  $jobs << BuildEm::Executor.new([command,optz])
23
23
  end
24
24
 
@@ -31,10 +31,13 @@ class BuildEm::Runner
31
31
  $jobs = []
32
32
  def self.start
33
33
  if ARGV.size == 1
34
- puts "running #{ARGV[0]}"
35
- $configuration = BuildEm::Configuration.new
36
- load ARGV[0]
37
- puts "finished #{ARGV[0]}"
34
+ begin
35
+ puts "running #{ARGV[0]}"
36
+ $configuration = BuildEm::Configuration.new
37
+ load ARGV[0]
38
+ ensure
39
+ puts "finished #{ARGV[0]}"
40
+ end
38
41
  else
39
42
  puts usage
40
43
  end
@@ -1,3 +1,3 @@
1
1
  class BuildEm
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -5,6 +5,8 @@ require 'rspec'
5
5
 
6
6
  $SPEC_ROOT = File.expand_path(File.dirname(__FILE__))
7
7
 
8
+ require "bundler/setup"
9
+
8
10
  def require_files filename
9
11
  filename.each do |file|
10
12
  require "#{$SPEC_ROOT}/../lib/buildem/#{file}"
@@ -24,8 +26,17 @@ RSpec.configure do |config|
24
26
  begin
25
27
  yield
26
28
  rescue Exception => e
27
- e.class.should == clazz
28
- return
29
+ case clazz
30
+ when String
31
+ e.message.should == clazz
32
+ return
33
+ when Regexp
34
+ e.message.should =~ clazz
35
+ return
36
+ else
37
+ e.class.should == clazz
38
+ return
39
+ end
29
40
  end
30
41
  fail "Did not throw an exception like intended"
31
42
  end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/../helper.rb")
2
+ require_files "condition_matcher"
3
+
4
+ describe BuildEm::ConditionMatcher, "match" do
5
+
6
+ before :each do
7
+ @matcher = BuildEm::ConditionMatcher.new
8
+ end
9
+
10
+ # match(return_code, output, condition)
11
+
12
+ it "raises an exception when an unsupported condition is supplied" do
13
+ unsupported_type = 1.00
14
+ expecting_exception("unsupported type for condition") { @matcher.match(0,"foo", unsupported_type) }
15
+ end
16
+
17
+ describe "output with string matching" do
18
+ it "returns true when it finds a match" do
19
+ @matcher.match(0,"foo", "foo").should == true
20
+ end
21
+ it "returns true when it can not find a match" do
22
+ @matcher.match(0,"foo", "bar").should == false
23
+ end
24
+ end
25
+
26
+ describe "output with regexp matching" do
27
+ it "returns true when it finds a match" do
28
+ @matcher.match(0,"very complex output", /\w+\s+complex\s+\w+/).should == true
29
+ end
30
+ it "returns true when it can not find a match" do
31
+ @matcher.match(0,"more [complex] output", /\w+\s+complex\s+\w+/).should == false
32
+ end
33
+ end
34
+
35
+ describe "return code matching" do
36
+ it "returns true when it finds a match" do
37
+ @matcher.match(0,"SUCCESS", 0).should == true
38
+ end
39
+ it "returns true when it can not find a match" do
40
+ @matcher.match(0,"FAILURE", 1).should == false
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/../helper.rb")
2
+ require_files "executor"
3
+
4
+ describe BuildEm::Executor, "run" do
5
+
6
+ before :each do
7
+ @mock_kernel = mock(Kernel)
8
+ @matcher = mock(BuildEm::ConditionMatcher)
9
+ end
10
+
11
+ describe "runs with default options" do
12
+
13
+ it "executes the provided command and quits if no retries supplied" do
14
+ command = "pinky and the brain"
15
+ executor = BuildEm::Executor.new([command,{}], @mock_kernel)
16
+ run_and_exitstatus_with(command, "FAILURE", 8675308)
17
+ executor.run.should == 8675308
18
+ end
19
+
20
+ it "raises an exception when something bad goes on" do
21
+ command = "foo bar"
22
+ executor = BuildEm::Executor.new([command, {}], @mock_kernel)
23
+ @mock_kernel.should_receive("run_command").with(command).and_raise("KA BOOM")
24
+ expecting_exception("KA BOOM") { executor.run }
25
+ end
26
+
27
+ end
28
+
29
+ describe "runs command with options" do
30
+
31
+ it "executes the provided command 10 times when condition is not met" do
32
+ command = "some really cool command"
33
+ executor = BuildEm::Executor.new([command, {:retry_amount => 10}], @mock_kernel)
34
+ 10.times do
35
+ run_and_exitstatus_with(command, "FAILURE", -1)
36
+ end
37
+ executor.run.should == -1
38
+ end
39
+
40
+ it "executes the provided command 3 times out of 10 when condition is met after 3 tries" do
41
+ command = "command_to_run"
42
+ executor = BuildEm::Executor.new([command, {:retry_amount => 10}], @mock_kernel)
43
+ 2.times do
44
+ run_and_exitstatus_with(command, "FAILURE", -1)
45
+ end
46
+ run_and_exitstatus_with(command, "WINNER", 0)
47
+ executor.run.should == 0
48
+ end
49
+
50
+ it "does not raise an exception when something bad goes on if :quit_on_error is false" do
51
+ argz = ["command_to_run", {:quit_on_error => false}]
52
+ executor = BuildEm::Executor.new(argz, @mock_kernel)
53
+ @mock_kernel.should_receive("run_command").with("command_to_run").and_raise("KA BOOM")
54
+ executor.run.should == nil
55
+ end
56
+
57
+ end
58
+
59
+ private
60
+ def run_and_exitstatus_with(command, output, exitstatus)
61
+ @mock_kernel.should_receive("run_command").with(command).and_return(output)
62
+ @mock_kernel.should_receive(:exitstatus).and_return(exitstatus)
63
+ end
64
+
65
+
66
+ end
@@ -3,6 +3,6 @@ require_files "version"
3
3
 
4
4
  describe BuildEm, "VERSION" do
5
5
  it "has the proper version number" do
6
- BuildEm::VERSION.should == "0.0.3"
6
+ BuildEm::VERSION.should == "0.0.4"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: buildem
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy W. Rowe
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-27 00:00:00 -04:00
18
+ date: 2011-04-02 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -58,15 +58,17 @@ extensions: []
58
58
  extra_rdoc_files: []
59
59
 
60
60
  files:
61
+ - .autotest
61
62
  - .gitignore
62
- - EXAMPLE
63
+ - EXAMPLES.md
63
64
  - Gemfile
64
- - README
65
+ - README.md
65
66
  - Rakefile
66
67
  - bin/buildem
67
68
  - buildem.gemspec
68
69
  - lib/buildem.rb
69
70
  - lib/buildem/base.rb
71
+ - lib/buildem/condition_matcher.rb
70
72
  - lib/buildem/configuration.rb
71
73
  - lib/buildem/executor.rb
72
74
  - lib/buildem/runner.rb
@@ -74,7 +76,9 @@ files:
74
76
  - lib/buildem/version.rb
75
77
  - spec/helper.rb
76
78
  - spec/unit/base_spec.rb
79
+ - spec/unit/condition_matcher_spec.rb
77
80
  - spec/unit/configuration_spec.rb
81
+ - spec/unit/executor_spec.rb
78
82
  - spec/unit/helper/examples/blank_file.buildem
79
83
  - spec/unit/helper/examples/everything.buildem
80
84
  - spec/unit/helper/examples/nonsequential.buildem
@@ -121,7 +125,9 @@ summary: A simple build script wrapper that allows for concurent tasks
121
125
  test_files:
122
126
  - spec/helper.rb
123
127
  - spec/unit/base_spec.rb
128
+ - spec/unit/condition_matcher_spec.rb
124
129
  - spec/unit/configuration_spec.rb
130
+ - spec/unit/executor_spec.rb
125
131
  - spec/unit/helper/examples/blank_file.buildem
126
132
  - spec/unit/helper/examples/everything.buildem
127
133
  - spec/unit/helper/examples/nonsequential.buildem
data/EXAMPLE DELETED
@@ -1,16 +0,0 @@
1
- $configuration.workers = 2
2
-
3
- run "initialize.sh"
4
- run "clean.sh"
5
-
6
- unorderd do
7
- queued_run "build.sh"
8
- queued_run "checkin.sh"
9
- queued_run "publish.sh"
10
- run "some_task_in_the_middle_of_queue.sh" # this will block all of the queued_run calls after this
11
- queued_run "build.sh"
12
- queued_run "checkin.sh"
13
- queued_run "publish.sh"
14
- end
15
-
16
- run "do_something_at_the_end.sh"
data/README DELETED
@@ -1,46 +0,0 @@
1
- Build'em quick, Build'em right
2
-
3
- Build'em is a small little script parser that is intended for large build systems.
4
- Build'em is still very young :) so be careful using it. Input is always welcome and if there is a feature that you just half to have i'd probably do it.
5
-
6
-
7
- Features:
8
-
9
- Execution:
10
- Scripts go in a plain text file, I use my_very_important_task.buildem
11
- and then simply call buildem my_very_important_task.buildem
12
-
13
- 1) Build'em supports sequential tasks (tasks that go in order)
14
-
15
- Example:
16
- run "./task.sh"
17
- run "./another.sh" #another.sh waits for task.sh to complete
18
-
19
- 2) Build'em supports a work queue, what does this mean?
20
- This means that you can run tasks concurrently, easily.
21
-
22
- Example:
23
-
24
- unorderd do
25
- queued_run "./some_task.sh"
26
- queued_run "./some_task1.sh" # All of these items will be executed at the same time
27
- queued_run "./some_task2.sh"
28
- end
29
-
30
-
31
- *IMPORTANT* All queued_run tasks must be inside of an unorderd block if you want them to run at the same time. If you use run for a task, it will block to complete.
32
- That being said you can inject ordered tasks in the middle of unorderd tasks by using run instead of using qeueued_run if you wish to.
33
-
34
-
35
- 3) Configuration
36
- To set the worker amount for unorderd tasks before the unorderd block do $configuration.workers = 10 to get 10 nano-bots working for you.
37
-
38
- Example:
39
- $configuration.workers = 5
40
- unorderd do
41
- ....
42
- end
43
-
44
- This will give you 5 nano-bots for your unordered tasks
45
-
46
-