buildem 0.0.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ coverage
data/Gemfile CHANGED
@@ -8,4 +8,6 @@ group :test do
8
8
  gem "autotest"
9
9
  gem "autotest-growl"
10
10
  gem "autotest-fsevent"
11
+ gem "flexmock"
12
+ gem "rcov"
11
13
  end
data/README.md CHANGED
@@ -2,7 +2,6 @@ Build'em quick, Build'em right
2
2
  ==============================
3
3
 
4
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
5
 
7
6
 
8
7
  Features:
@@ -44,11 +43,35 @@ Example:
44
43
 
45
44
  This will give you 5 nano-bots for your unordered tasks
46
45
 
47
-
48
46
  optional run and queued_run options
49
47
  --------------------------
50
48
  * :retry\_amount (Integer that specifies that you want to retry the execution of the provided command. Default is 1 execution.)
51
49
  * :retry\_condition (Integer, regular expression, or string that specifies what a good execution is. Default is 0 if not specified.)
52
50
  * :quit\_on\_error (Boolean that specifies if build'em should quit when an exception happens executing the provided command. Default is true)
53
51
 
52
+ **Notice** If the retry\_condition is not met within the retry\_amount interval an error will be throw unless :quit\_on\_error is set to false
53
+
54
+ Logging
55
+ -------
56
+ If you wish to log all of the output to a specific file you can do so with an output\_to block
57
+
58
+ Example:
59
+
60
+ output_to "my_nifty_output_file.txt" do
61
+ run "./task.sh"
62
+ run "./another.sh"
63
+ unordered do
64
+ queued_run "./some_task.sh"
65
+ queued_run "./some_task1.sh"
66
+ queued_run "./some_task2.sh"
67
+ end
68
+ end
69
+
70
+ * output\_to parameters
54
71
 
72
+ filename: The filename that you wish to output to (optional, default is output.log)
73
+ IO capture: possible values :stdout, :stderr etc (optional, default is :stdout)
74
+
75
+ output_to do ... will save all stdout output to output.log
76
+ output_to "another_file.txt" do ... same as above but would be saved to another_file.txt
77
+ output_to "err.txt", :stderr do ... will output all stderr to err
data/Rakefile CHANGED
@@ -6,14 +6,22 @@ namespace :spec do
6
6
 
7
7
  desc "Run all of the system specs. [spec=system/foo.rb]"
8
8
  RSpec::Core::RakeTask.new(:system) do |spec|
9
- spec.pattern = 'spec/system/*_spec.rb'
10
- spec.rspec_opts = ['--color']
9
+ spec.pattern = 'spec/system/*_spec.rb'
10
+ spec.rspec_opts = %w{--color'}
11
11
  end
12
12
 
13
13
  desc "Run all of the unit specs. [spec=unit/foo.rb]"
14
14
  RSpec::Core::RakeTask.new(:test) do |spec|
15
- spec.pattern = 'spec/unit/*_spec.rb'
16
- spec.rspec_opts = ['--color']
15
+ spec.pattern = 'spec/unit/*_spec.rb'
16
+ spec.rspec_opts = %w{--color -f d}
17
17
  end
18
18
 
19
- end
19
+ RSpec::Core::RakeTask.new('test:rcov') do |spec|
20
+ rm_f "coverage"
21
+ spec.pattern = 'spec/unit/*_spec.rb'
22
+ spec.rcov = true
23
+ spec.rspec_opts = %w{--color}
24
+ spec.rcov_opts = %w{--exclude spec,gems\/}
25
+ end
26
+
27
+ end
@@ -3,4 +3,4 @@
3
3
 
4
4
  require 'rubygems'
5
5
  require 'buildem/runner'
6
- BuildEm::Runner.start
6
+ BuildEm::Runner.new.start
@@ -13,11 +13,6 @@ module Kernel
13
13
  end
14
14
  end
15
15
 
16
- def windows?
17
- return java.lang.System.get_property("os.name")[/windows/i] if RUBY_PLATFORM == "java"
18
- return RUBY_PLATFORM[/mswin/]
19
- end
20
-
21
16
  def inside path
22
17
  cd path do
23
18
  yield
@@ -17,7 +17,7 @@ class BuildEm::Executor
17
17
 
18
18
  def run
19
19
  optz = argz[1]
20
- quit_on_error = (optz[:quit_on_error].nil? ? true : optz[:quit_on_error])
20
+ quit_on_error = (optz[:quit_on_error].nil? ? true : optz[:quit_on_error])
21
21
  retry_amount = (optz[:retry_amount].nil? ? 1 : optz[:retry_amount])
22
22
  condition = (optz[:retry_condition].nil? ? 0 : optz[:retry_condition])
23
23
  executions = 0
@@ -32,18 +32,10 @@ class BuildEm::Executor
32
32
  rescue Exception => e
33
33
  if quit_on_error
34
34
  raise e
35
- else
36
- #put to output log or specified log
37
35
  end
38
36
  end while executions < retry_amount
37
+ fail "Failed to execute [#{argz[0]}]. Tried #{retry_amount} time(s), expected match was [#{condition}] got [#{@command_exitstatus}]." if quit_on_error
39
38
  @command_exitstatus
40
39
  end
41
-
42
- private
43
-
44
- def redirect_standard_error_and_out
45
- ""
46
- end
47
-
48
-
40
+
49
41
  end
@@ -0,0 +1,22 @@
1
+ require 'stringio'
2
+ module Kernel
3
+
4
+ def output_to(filename="output.log", stream=:stdout)
5
+ if block_given?
6
+ begin
7
+ stream = stream.to_s
8
+ eval "$#{stream} = StringIO.new"
9
+ yield
10
+ result = eval("$#{stream}").string
11
+ ensure
12
+ eval("$#{stream} = #{stream.upcase}")
13
+ end
14
+ else
15
+ fail "output_to must be used in block format with a 'do' and 'end'."
16
+ end
17
+
18
+ File.open(filename, "w+") {|f| f.puts result }
19
+
20
+ end
21
+
22
+ end
@@ -3,6 +3,7 @@ require 'buildem/base'
3
3
  require 'buildem/configuration'
4
4
  require 'buildem/executor'
5
5
  require 'process_pool'
6
+ require 'buildem/logger'
6
7
 
7
8
  module Kernel
8
9
  def unordered
@@ -28,8 +29,28 @@ module Kernel
28
29
  end
29
30
 
30
31
  class BuildEm::Runner
32
+
31
33
  $jobs = []
32
- def self.start
34
+
35
+ def initialize(kernel = Kernel, argv = ARGV)
36
+ @kernel = kernel
37
+ @argv = argv
38
+ end
39
+
40
+ def process_standard_in
41
+ if @argv.empty?
42
+ output = []
43
+ while input = @kernel.gets and not input == "start\n"
44
+ output << input
45
+ end
46
+ unless output.empty?
47
+ output = output.join("\n")
48
+ @kernel.eval(output)
49
+ end
50
+ end
51
+ end
52
+
53
+ def start
33
54
  if ARGV.size == 1
34
55
  begin
35
56
  puts "running #{ARGV[0]}"
@@ -45,7 +66,7 @@ class BuildEm::Runner
45
66
 
46
67
  private
47
68
 
48
- def self.usage
69
+ def usage
49
70
  <<-USAGE
50
71
 
51
72
  -----------------------------------------------------------------
@@ -1,3 +1,3 @@
1
1
  class BuildEm
2
- VERSION = "0.0.5"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,12 +1,14 @@
1
+ require "bundler/setup"
1
2
  require 'fileutils'
2
3
  include FileUtils
3
4
  require 'buildem'
5
+
4
6
  require 'rspec'
7
+ require 'test/unit'
8
+ require 'flexmock/test_unit'
5
9
 
6
10
  $SPEC_ROOT = File.expand_path(File.dirname(__FILE__))
7
11
 
8
- require "bundler/setup"
9
-
10
12
  def require_files filename
11
13
  filename.each do |file|
12
14
  require "#{$SPEC_ROOT}/../lib/buildem/#{file}"
@@ -22,6 +24,8 @@ end
22
24
 
23
25
  RSpec.configure do |config|
24
26
 
27
+ config.mock_with :flexmock
28
+
25
29
  def expecting_exception(clazz)
26
30
  begin
27
31
  yield
@@ -27,4 +27,22 @@ describe "base" do
27
27
  end
28
28
  end
29
29
 
30
+ end
31
+
32
+ describe Kernel, "exitstatus" do
33
+
34
+ it "can get the exit status of the last ran application" do
35
+ capture(:stdout) { `pwd` }
36
+ Kernel.exitstatus.should == 0
37
+ end
38
+
39
+ end
40
+
41
+ describe Kernel, "run_command" do
42
+
43
+ it "can run a command" do
44
+ flexmock(Kernel) {|k| k.should_receive("`").with("awesome command").and_return("foo man shoe").once}
45
+ Kernel.run_command("awesome command").should == "foo man shoe"
46
+ end
47
+
30
48
  end
@@ -1,66 +1,84 @@
1
1
  require File.expand_path(File.dirname(__FILE__)+"/../helper.rb")
2
2
  require_files "executor"
3
3
 
4
+ describe BuildEm::Executor, "name" do
5
+ it "has the correct name" do
6
+ BuildEm::Executor.new(["command",{}]).name.should == BuildEm::Executor
7
+ end
8
+ end
9
+
4
10
  describe BuildEm::Executor, "run" do
5
11
 
6
12
  before :each do
7
- @mock_kernel = mock(Kernel)
8
- @matcher = mock(BuildEm::ConditionMatcher)
13
+ @mock_kernel = flexmock(Kernel)
14
+ @matcher = flexmock(BuildEm::ConditionMatcher.new)
9
15
  end
10
16
 
11
- describe "runs with default options" do
17
+ describe "with default options" do
12
18
 
13
19
  it "executes the provided command and quits if no retries supplied" do
14
20
  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
21
+ run_and_exitstatus_with(command, "FAILURE")
22
+ capture(:stdout) { BuildEm::Executor.new([command,{}], @mock_kernel, @matcher).run.should == 0 }
18
23
  end
19
24
 
20
25
  it "raises an exception when something bad goes on" do
21
26
  command = "foo bar"
22
- executor = BuildEm::Executor.new([command, {}], @mock_kernel)
23
27
  @mock_kernel.should_receive("run_command").with(command).and_raise("KA BOOM")
24
- expecting_exception("KA BOOM") { executor.run }
28
+ capture(:stdout) { expecting_exception("KA BOOM") { BuildEm::Executor.new([command, {}], @mock_kernel, @matcher).run } }
25
29
  end
26
30
 
27
31
  end
28
32
 
29
- describe "runs command with options" do
33
+ describe "command retry interactions" do
34
+
35
+ it "executes the provided command 50 times and raises an error when condition is not met" do
36
+ command = "urr"
37
+ 50.times { run_and_exitstatus_with(command, "FAILURE", -1) }
38
+ capture(:stdout) { expecting_exception("Failed to execute [urr]. Tried 50 time(s), expected match was [0] got [-1].") { BuildEm::Executor.new([command, {:retry_amount => 50, :quit_on_error => true}], @mock_kernel, @matcher).run.should == -1 } }
39
+ end
30
40
 
31
41
  it "executes the provided command 10 times when condition is not met" do
32
42
  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
43
+ 10.times { run_and_exitstatus_with(command, "FAILURE", -1) }
44
+ capture(:stdout) { BuildEm::Executor.new([command, {:retry_amount => 10, :quit_on_error => false}], @mock_kernel, @matcher).run.should == -1 }
38
45
  end
39
46
 
40
47
  it "executes the provided command 3 times out of 10 when condition is met after 3 tries" do
41
48
  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
49
+ 2.times { run_and_exitstatus_with(command, "FAILURE", -1) }
46
50
  run_and_exitstatus_with(command, "WINNER", 0)
47
- executor.run.should == 0
51
+ capture(:stdout) { BuildEm::Executor.new([command, {:retry_amount => 10}], @mock_kernel, @matcher).run.should == 0 }
48
52
  end
49
53
 
50
54
  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
55
  @mock_kernel.should_receive("run_command").with("command_to_run").and_raise("KA BOOM")
54
- executor.run.should == nil
56
+ capture(:stdout) { BuildEm::Executor.new(["command_to_run", {:quit_on_error => false}], @mock_kernel, @matcher).run.should == nil }
55
57
  end
56
58
 
57
59
  end
58
60
 
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)
61
+ describe "command can handle conditions" do
62
+
63
+ it "is successful when condition is met" do
64
+ command = "er powel"
65
+ run_and_exitstatus_with(command, "WINNER", 55, 55)
66
+ capture(:stdout) { BuildEm::Executor.new([command, {:retry_condition => 55}], @mock_kernel, @matcher).run.should == 55 }
67
+ end
68
+
69
+ it "executes the provided command raises an error when condition is not met" do
70
+ command = "fooz"
71
+ run_and_exitstatus_with(command, "FAILURE", -1)
72
+ capture(:stdout) { expecting_exception("Failed to execute [fooz]. Tried 1 time(s), expected match was [0] got [-1].") { BuildEm::Executor.new([command, {}], @mock_kernel, @matcher).run.should == -1 } }
73
+ end
74
+
63
75
  end
64
76
 
77
+ private
78
+ def run_and_exitstatus_with(command, output, exitstatus=0, condition = 0)
79
+ @mock_kernel.should_receive(:run_command).with(command).and_return(output).once.ordered
80
+ @mock_kernel.should_receive(:exitstatus).and_return(exitstatus).once.ordered
81
+ @matcher.should_receive(:match).with(exitstatus, output, condition).and_return(exitstatus == condition).once.ordered
82
+ end
65
83
 
66
84
  end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/../helper.rb")
2
+ require_files "logger"
3
+ require 'tempfile'
4
+
5
+ describe Kernel, "output_to" do
6
+
7
+ after :each do
8
+ rm_rf "output.log" if File.exist? "output.log"
9
+ end
10
+
11
+ it "captures multiple lines" do
12
+ output_to {
13
+ puts "hi"
14
+ puts "bye"
15
+ puts "wooh wooooooh"
16
+ }
17
+ File.open("output.log", "r") {|f| f.readlines.size.should == 3}
18
+ end
19
+
20
+ it "captures standard out" do
21
+ output_to("output.log", :stdout) {
22
+ puts `pwd`
23
+ }
24
+ File.open("output.log", "r") {|f| f.readline.should =~ /buildem/ }
25
+ end
26
+
27
+ it "captures standard error" do
28
+ output_to("output.log", :stderr) {
29
+ $stderr.puts "err"
30
+ }
31
+ File.open("output.log", "r") {|f| f.readlines.should == ["err\n"] }
32
+ end
33
+
34
+ it "captures standard out by default" do
35
+ output_to { puts "hi" }
36
+ File.open("output.log", "r") {|f| f.readlines.should == ["hi\n"] }
37
+ end
38
+
39
+ it "writes output to default filename of output.log" do
40
+ output_to { puts "hi" }
41
+ File.exist?("output.log").should == true
42
+ end
43
+
44
+ it "writes to a provided filename" do
45
+ output_to ("woowoo.txt") { puts "heee-che-bon" }
46
+ File.open("woowoo.txt", "r") {|f| f.readlines.should == ["heee-che-bon\n"] }
47
+ rm_rf "woowoo.txt"
48
+ end
49
+
50
+ it "throws an exception if a block is not given" do
51
+ expecting_exception("output_to must be used in block format with a 'do' and 'end'.") { Kernel.output_to }
52
+ end
53
+
54
+ end
@@ -1,29 +1,65 @@
1
1
  require File.expand_path(File.dirname(__FILE__)+"/../helper.rb")
2
2
  require_files "runner"
3
3
 
4
+ describe BuildEm::Runner, "process_standard_in" do
5
+
6
+ before :each do
7
+ @mock_kernel = flexmock(:kernel, Kernel)
8
+ @mock_argv = flexmock(:argv, ARGV)
9
+ end
10
+
11
+ it "can handle user arguments" do
12
+ @mock_argv.should_receive("empty?").and_return(false).once
13
+ BuildEm::Runner.new(@mock_kernel, @mock_argv).process_standard_in
14
+ end
15
+
16
+ it "can handle standard in with no value" do
17
+ @mock_argv.should_receive("empty?").and_return(true).once
18
+ @mock_kernel.should_receive(:gets).once
19
+ BuildEm::Runner.new(@mock_kernel, @mock_argv).process_standard_in
20
+ end
21
+
22
+ it "stops when the command 'start' is issued" do
23
+ @mock_argv.should_receive("empty?").and_return(true).once
24
+ @mock_kernel.should_receive(:gets).once
25
+ BuildEm::Runner.new(@mock_kernel, @mock_argv).process_standard_in
26
+ end
27
+
28
+ end
29
+
30
+ describe Kernel, "queued_run" do
31
+
32
+ it "has the correct number of jobs" do
33
+ 30.times { @mock_kernel.queued_run("foo",{}) }
34
+ $jobs.size.should == 30
35
+ $jobs = []
36
+ end
37
+
38
+ it "can add a job" do
39
+ 101.times { |t|
40
+ @mock_kernel.queued_run("foo",{})
41
+ $jobs.size.should == t+1
42
+ }
43
+ $jobs = []
44
+ end
45
+
46
+ end
47
+
4
48
  describe BuildEm::Runner, "start" do
5
49
 
6
50
  it "runs the program" do
7
51
  ARGV.replace ["#{here}/helper/examples/blank_file.buildem"]
8
- capture(:stdout) {BuildEm::Runner.start}.strip.should == "running #{here}/helper/examples/blank_file.buildem\nfinished #{here}/helper/examples/blank_file.buildem"
52
+ capture(:stdout) {BuildEm::Runner.new.start}.strip.should == "running #{here}/helper/examples/blank_file.buildem\nfinished #{here}/helper/examples/blank_file.buildem"
9
53
  end
10
54
 
11
55
  it "runs the program" do
12
56
  ARGV.replace ["#{here}/helper/examples/not_there.buildem"]
13
- lambda { capture(:stdout) {BuildEm::Runner.start} }.should raise_error(LoadError)
57
+ lambda { capture(:stdout) {BuildEm::Runner.new.start} }.should raise_error(LoadError)
14
58
  end
15
59
 
16
60
  it "spits out usage when the user doesn't supply a filename" do
17
61
  ARGV.replace []
18
- capture(:stdout) {BuildEm::Runner.start}.should == usage_banner
19
- end
20
-
21
- describe "execution flow" do
22
-
23
- before do
24
-
25
- end
26
-
62
+ capture(:stdout) {BuildEm::Runner.new.start}.should == usage_banner
27
63
  end
28
64
 
29
65
  private
@@ -1,8 +1,7 @@
1
1
  require File.expand_path(File.dirname(__FILE__)+"/../helper.rb")
2
- require_files "version"
3
2
 
4
3
  describe BuildEm, "VERSION" do
5
4
  it "has the proper version number" do
6
- BuildEm::VERSION.should == "0.0.5"
5
+ BuildEm::VERSION.should == "1.0.0"
7
6
  end
8
7
  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: 21
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
+ - 1
7
8
  - 0
8
9
  - 0
9
- - 5
10
- version: 0.0.5
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy W. Rowe
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-02 00:00:00 -04:00
19
- default_executable:
18
+ date: 2011-04-10 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: process_pool
@@ -71,8 +70,8 @@ files:
71
70
  - lib/buildem/condition_matcher.rb
72
71
  - lib/buildem/configuration.rb
73
72
  - lib/buildem/executor.rb
73
+ - lib/buildem/logger.rb
74
74
  - lib/buildem/runner.rb
75
- - lib/buildem/validator.rb
76
75
  - lib/buildem/version.rb
77
76
  - spec/helper.rb
78
77
  - spec/unit/base_spec.rb
@@ -86,9 +85,9 @@ files:
86
85
  - spec/unit/helper/examples/sequential.buildem
87
86
  - spec/unit/helper/examples/sequential_with_comments.buildem
88
87
  - spec/unit/helper/examples/sequential_with_config.buildem
88
+ - spec/unit/logger_spec.rb
89
89
  - spec/unit/runner_spec.rb
90
90
  - spec/unit/version_spec.rb
91
- has_rdoc: true
92
91
  homepage: http://github.com/jeremywrowe/buildem
93
92
  licenses: []
94
93
 
@@ -118,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
117
  requirements: []
119
118
 
120
119
  rubyforge_project: buildem
121
- rubygems_version: 1.6.2
120
+ rubygems_version: 1.7.2
122
121
  signing_key:
123
122
  specification_version: 3
124
123
  summary: A simple build script wrapper that allows for concurent tasks
@@ -135,5 +134,6 @@ test_files:
135
134
  - spec/unit/helper/examples/sequential.buildem
136
135
  - spec/unit/helper/examples/sequential_with_comments.buildem
137
136
  - spec/unit/helper/examples/sequential_with_config.buildem
137
+ - spec/unit/logger_spec.rb
138
138
  - spec/unit/runner_spec.rb
139
139
  - spec/unit/version_spec.rb
@@ -1,4 +0,0 @@
1
-
2
- class BuildEm::Validator
3
-
4
- end