buildem 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +13 -0
- data/EXAMPLES.md +34 -0
- data/Gemfile +7 -0
- data/README.md +54 -0
- data/lib/buildem/base.rb +10 -0
- data/lib/buildem/condition_matcher.rb +15 -0
- data/lib/buildem/executor.rb +24 -6
- data/lib/buildem/runner.rb +8 -5
- data/lib/buildem/version.rb +1 -1
- data/spec/helper.rb +13 -2
- data/spec/unit/condition_matcher_spec.rb +44 -0
- data/spec/unit/executor_spec.rb +66 -0
- data/spec/unit/version_spec.rb +1 -1
- metadata +12 -6
- data/EXAMPLE +0 -16
- data/README +0 -46
data/.autotest
ADDED
@@ -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
|
+
}
|
data/EXAMPLES.md
ADDED
@@ -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
data/README.md
ADDED
@@ -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
|
+
|
data/lib/buildem/base.rb
CHANGED
@@ -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
|
data/lib/buildem/executor.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
-
|
21
|
-
|
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
|
44
|
+
def redirect_standard_error_and_out
|
27
45
|
""
|
28
46
|
end
|
29
47
|
|
data/lib/buildem/runner.rb
CHANGED
@@ -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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
data/lib/buildem/version.rb
CHANGED
data/spec/helper.rb
CHANGED
@@ -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
|
-
|
28
|
-
|
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
|
data/spec/unit/version_spec.rb
CHANGED
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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-
|
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
|
-
-
|
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
|
-
|