scripted 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +6 -0
  5. data/MIT-LICENSE +22 -0
  6. data/README.md +423 -0
  7. data/Rakefile +39 -0
  8. data/bin/scripted +67 -0
  9. data/cucumber.yml +3 -0
  10. data/examples/important.rb +31 -0
  11. data/examples/parallel.rb +30 -0
  12. data/examples/pride.rb +37 -0
  13. data/examples/websockets.png +0 -0
  14. data/examples/websockets.rb +37 -0
  15. data/examples/websockets/public/ansiparse.js +156 -0
  16. data/examples/websockets/server.rb +32 -0
  17. data/examples/websockets/server.ru +10 -0
  18. data/examples/websockets/views/_client.handlebars +47 -0
  19. data/examples/websockets/views/app.coffee +210 -0
  20. data/examples/websockets/views/index.erb +1 -0
  21. data/examples/websockets/views/layout.erb +14 -0
  22. data/examples/websockets/views/style.sass +61 -0
  23. data/features/controlling_exit_status.feature +124 -0
  24. data/features/formatters.feature +142 -0
  25. data/features/rake_integration.feature +86 -0
  26. data/features/running_commands_in_parallel.feature +27 -0
  27. data/features/running_from_command_line.feature +56 -0
  28. data/features/running_from_ruby.feature +38 -0
  29. data/features/running_groups.feature +39 -0
  30. data/features/specifying_which_commands_to_run.feature +122 -0
  31. data/features/steps/scripted_steps.rb +25 -0
  32. data/features/support/aruba.rb +5 -0
  33. data/features/support/env.rb +2 -0
  34. data/install +5 -0
  35. data/lib/scripted.rb +28 -0
  36. data/lib/scripted/command.rb +82 -0
  37. data/lib/scripted/commands/rake.rb +25 -0
  38. data/lib/scripted/commands/ruby.rb +22 -0
  39. data/lib/scripted/commands/shell.rb +28 -0
  40. data/lib/scripted/configuration.rb +103 -0
  41. data/lib/scripted/error.rb +13 -0
  42. data/lib/scripted/formatters/announcer.rb +39 -0
  43. data/lib/scripted/formatters/blank.rb +97 -0
  44. data/lib/scripted/formatters/default.rb +62 -0
  45. data/lib/scripted/formatters/human_status.rb +38 -0
  46. data/lib/scripted/formatters/stats.rb +38 -0
  47. data/lib/scripted/formatters/table.rb +99 -0
  48. data/lib/scripted/formatters/websocket.rb +137 -0
  49. data/lib/scripted/group.rb +49 -0
  50. data/lib/scripted/output/command_logger.rb +42 -0
  51. data/lib/scripted/output/logger.rb +139 -0
  52. data/lib/scripted/rake_task.rb +24 -0
  53. data/lib/scripted/runner.rb +19 -0
  54. data/lib/scripted/running/execute.rb +16 -0
  55. data/lib/scripted/running/run_command.rb +101 -0
  56. data/lib/scripted/running/run_commands.rb +98 -0
  57. data/lib/scripted/running/select_commands.rb +22 -0
  58. data/lib/scripted/version.rb +3 -0
  59. data/scripted.gemspec +35 -0
  60. data/scripted.rb +16 -0
  61. data/spec/scripted/command_spec.rb +72 -0
  62. data/spec/scripted/commands/ruby_spec.rb +10 -0
  63. data/spec/scripted/commands/shell_spec.rb +18 -0
  64. data/spec/scripted/configuration_spec.rb +50 -0
  65. data/spec/scripted/formatters/websocket_spec.rb +14 -0
  66. data/spec/scripted/group_spec.rb +49 -0
  67. data/spec/scripted/running/run_command_spec.rb +157 -0
  68. data/spec/scripted/running/run_commands_spec.rb +150 -0
  69. data/spec/scripted/running/select_commands_spec.rb +28 -0
  70. data/spec/spec_helper.rb +15 -0
  71. data/spec/support/expect_to_receive.rb +17 -0
  72. data/spec/support/io_capture.rb +50 -0
  73. metadata +340 -0
@@ -0,0 +1,16 @@
1
+ formatter "default"
2
+ formatter "table"
3
+ formatter "announcer"
4
+
5
+ parallel do
6
+
7
+ run "rspec" do
8
+ `rspec -f Fivemat`
9
+ end
10
+
11
+ `cucumber`
12
+
13
+ end
14
+
15
+ # because cucumber accesses the file system, it cannot run two at the same time
16
+ `cucumber -p wip`
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scripted::Command do
4
+
5
+ let(:command) { Scripted::Command.new("foo") }
6
+
7
+ it "has a name" do
8
+ expect(command.name).to eq "foo"
9
+ end
10
+
11
+ it "uses the name as shell function if no other command was specified" do
12
+ expect(command.executable).to be_a Scripted::Commands::Shell
13
+ end
14
+
15
+ specify "the sh method overrides the command to be run" do
16
+ command.define do
17
+ sh "bar"
18
+ end
19
+ expect(command.executable).to be_a Scripted::Commands::Shell
20
+ end
21
+
22
+ specify "the backtics also do a shell command" do
23
+ command.define do
24
+ `bar`
25
+ end
26
+ expect(command.executable).to be_a Scripted::Commands::Shell
27
+ end
28
+
29
+ specify "the rake method overrides the command to be run" do
30
+ command.define do
31
+ rake "db:migrate"
32
+ end
33
+ expect(command.executable).to be_a Scripted::Commands::Rake
34
+ end
35
+
36
+ specify "the ruby method stores a block" do
37
+ command.define do
38
+ ruby { 1 + 1 }
39
+ end
40
+ expect(command.executable).to be_a Scripted::Commands::Ruby
41
+ end
42
+
43
+ it "can be important" do
44
+ expect(command).not_to be_important
45
+ command.important!
46
+ expect(command).to be_important
47
+ end
48
+
49
+ it "can be unimportant" do
50
+ expect(command).not_to be_unimportant
51
+ command.unimportant!
52
+ expect(command).to be_unimportant
53
+ end
54
+
55
+ it "can be forced" do
56
+ expect(command).not_to be_forced
57
+ command.forced!
58
+ expect(command).to be_forced
59
+ end
60
+
61
+ it "can be only when failed" do
62
+ expect(command).not_to be_only_when_failed
63
+ command.only_when_failed!
64
+ expect(command).to be_only_when_failed
65
+ end
66
+
67
+ it "can be parallel" do
68
+ command = Scripted::Command.new("true", :parallel_id => 10)
69
+ expect(command.parallel_id).to eq 10
70
+ end
71
+
72
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scripted::Commands::Ruby do
4
+
5
+ it "evaluates a block" do
6
+ ruby = Scripted::Commands::Ruby.new(lambda { 1 })
7
+ expect(ruby.execute!).to eq 1
8
+ end
9
+
10
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scripted::Commands::Shell do
4
+
5
+ it "executes a shell command" do
6
+ shell = Scripted::Commands::Shell.new("echo this is a test in capturing output")
7
+ r = with_io do |io|
8
+ shell.execute!(io)
9
+ end
10
+ expect(r.strip).to eq "this is a test in capturing output"
11
+ end
12
+
13
+ it "can fail" do
14
+ shell = Scripted::Commands::Shell.new("false")
15
+ expect{shell.execute!}.to raise_error Scripted::CommandFailed
16
+ end
17
+
18
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scripted::Configuration do
4
+
5
+ it "can define groups" do
6
+ subject.group :foo
7
+ subject.group :bar
8
+ expect(subject).to have(2).groups
9
+ end
10
+
11
+ it "defines commands on the default group" do
12
+ subject.run "foo"
13
+ expect(subject).to have(1).groups
14
+ end
15
+
16
+ it "handles non existing files" do
17
+ subject.config_file "non-existing.rb"
18
+ expect { subject.load_files }.to raise_error Scripted::ConfigFileNotFound
19
+ end
20
+
21
+ it "adds the default file on demand" do
22
+ expect {
23
+ subject.with_default_config_file!
24
+ }.to change { subject.config_files }.to ["scripted.rb"]
25
+ end
26
+
27
+ it "does not allow setting out without a formatter" do
28
+ expect { subject.out "foo" }.to raise_error Scripted::NoFormatterForOutput
29
+ end
30
+
31
+ it "changes the last formatter to use a different output" do
32
+ subject.formatter :table, :out => "old.log"
33
+ expect { subject.out "new.log" }.to change { subject.formatters.first[:out] }.to "new.log"
34
+ end
35
+
36
+ it "can set multple formatter" do
37
+ subject.formatter :table, :out => "old.log"
38
+ subject.formatter :websocket
39
+ expect(subject).to have(2).formatters
40
+ end
41
+
42
+ it "reraises all configuration errors so they are easily rescued" do
43
+ expect {
44
+ subject.evaluate do
45
+ fooasdad
46
+ end
47
+ }.to raise_error Scripted::ConfigurationSyntaxError
48
+ end
49
+
50
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'scripted/formatters/websocket'
3
+
4
+ describe Scripted::Formatters::Websocket do
5
+
6
+ it "uses websocket" do
7
+ pending "this test just puts the output for the moment"
8
+ command = Scripted::Commands::Shell.new(%~ruby -e "20.times { |i| print i; sleep 0.1 }"~)
9
+ Scripted::Formatters::Websocket.new("ws://....") do |log|
10
+ command.execute!(log)
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scripted::Group do
4
+
5
+ let(:group) { Scripted::Group.new("foo") }
6
+
7
+ it "has a name" do
8
+ expect(group.name).to eq "foo"
9
+ end
10
+
11
+ it "defines commands" do
12
+ group.define do
13
+ run "echo 1"
14
+ end
15
+ expect(group.commands.first.name).to eq "echo 1"
16
+ end
17
+
18
+ it "can define multiple parallel blocks" do
19
+ command1 = command2 = command3 = command4 = nil
20
+
21
+ group.define do
22
+ parallel do
23
+ run("one") { command1 = self }
24
+ run("two") { command2 = self }
25
+ end
26
+ parallel do
27
+ run("three") { command3 = self }
28
+ end
29
+ run("four") { command4 = self }
30
+ end
31
+
32
+ expect(command1).to be_run_in_parallel_with(command2)
33
+ expect(command2).to be_run_in_parallel_with(command1)
34
+
35
+ expect(command3).not_to be_run_in_parallel_with(command1)
36
+ expect(command3).not_to be_run_in_parallel_with(command2)
37
+
38
+ expect(command1).not_to be_run_in_parallel_with(command3)
39
+ expect(command2).not_to be_run_in_parallel_with(command3)
40
+
41
+ expect(command4).not_to be_run_in_parallel_with(command1)
42
+ expect(command4).not_to be_run_in_parallel_with(command2)
43
+ expect(command4).not_to be_run_in_parallel_with(command3)
44
+ expect(command1).not_to be_run_in_parallel_with(command4)
45
+ expect(command2).not_to be_run_in_parallel_with(command4)
46
+ expect(command3).not_to be_run_in_parallel_with(command4)
47
+ end
48
+
49
+ end
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scripted::Running::RunCommand do
4
+
5
+ let(:command) { stub(:command, :unimportant? => false, :forced? => false, :important? => false, :only_when_failed? => false) }
6
+ let(:delegate) { mock :stub, :done => true, :halt! => true }
7
+ subject(:run_command) { Scripted::Running::RunCommand.new(command, logger) }
8
+ let(:logger) { mock(:logger).as_null_object }
9
+
10
+ def run
11
+ run_command.execute!(delegate)
12
+ end
13
+
14
+ context "when a command runs successfully" do
15
+
16
+ before do
17
+ Scripted::Running::Execute.stub :call do |command, delegate|
18
+ delegate.success!
19
+ end
20
+ end
21
+
22
+ it "notifies the delegate" do
23
+ expect(delegate).to receive(:done).once.with(run_command)
24
+ expect(delegate).to receive(:halt!).never
25
+ run
26
+ end
27
+
28
+ it "should be successful" do
29
+ run
30
+ expect(run_command).to be_success
31
+ end
32
+
33
+ it "should have executed" do
34
+ run
35
+ expect(run_command).to be_executed
36
+ end
37
+
38
+ it "should not be running" do
39
+ run
40
+ expect(run_command).not_to be_running
41
+ end
42
+
43
+ it "should not have halted" do
44
+ run
45
+ expect(run_command).not_to be_halted
46
+ end
47
+
48
+ it "should not have failed" do
49
+ run
50
+ expect(run_command).not_to be_failed
51
+ end
52
+
53
+ it "should have no exception" do
54
+ run
55
+ expect(run_command).not_to be_nil
56
+ end
57
+
58
+ it "should not be failed but unimportant" do
59
+ run
60
+ expect(run_command).not_to be_failed_but_unimportant
61
+ end
62
+
63
+ end
64
+
65
+ context "when a normal command fails" do
66
+
67
+ before do
68
+ Scripted::Running::Execute.stub :call do |command, delegate|
69
+ delegate.failed!(exception)
70
+ end
71
+ end
72
+
73
+ let(:exception) { RuntimeError.new("OH NOES") }
74
+
75
+ it "notifies the delegate" do
76
+ expect(delegate).to receive(:done).with(run_command)
77
+ run
78
+ end
79
+
80
+ it "should not be successful" do
81
+ run
82
+ expect(run_command).not_to be_success
83
+ end
84
+
85
+ it "should have executed" do
86
+ run
87
+ expect(run_command).to be_executed
88
+ end
89
+
90
+ it "should not be running" do
91
+ run
92
+ expect(run_command).not_to be_running
93
+ end
94
+
95
+ it "should have failed" do
96
+ run
97
+ expect(run_command).to be_failed
98
+ end
99
+
100
+ it "should not have halted" do
101
+ run
102
+ expect(run_command).not_to be_halted
103
+ end
104
+
105
+ it "should have a exception" do
106
+ run
107
+ expect(run_command).not_to be exception
108
+ end
109
+
110
+ it "should not be failed but unimportant" do
111
+ run
112
+ expect(run_command).not_to be_failed_but_unimportant
113
+ end
114
+
115
+ context "when the command is important" do
116
+
117
+ before do
118
+ command.stub(:important?).and_return(true)
119
+ end
120
+
121
+ it "should tell the delegate to halt" do
122
+ expect(delegate).to receive(:halt!)
123
+ run
124
+ end
125
+
126
+ it "should be halted" do
127
+ run
128
+ expect(run_command).to be_halted
129
+ end
130
+
131
+ end
132
+
133
+ context "when the command is unimportant" do
134
+
135
+ before do
136
+ command.stub(:unimportant?).and_return(true)
137
+ end
138
+
139
+ it "should be unimportant" do
140
+ expect(run_command).to be_unimportant
141
+ end
142
+
143
+ it "should not be failed" do
144
+ run
145
+ expect(run_command).not_to be_failed
146
+ end
147
+
148
+ it "should be failed but important" do
149
+ run
150
+ expect(run_command).to be_failed_but_unimportant
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1,150 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe Scripted::Running::RunCommands do
5
+
6
+ let(:run_commands) { Scripted::Running::RunCommands.new(logger) }
7
+ let(:logger) { mock(:logger).as_null_object }
8
+
9
+ def parallel_id
10
+ @parallel_id ||= 0
11
+ @parallel_id += 1
12
+ @parallel_id
13
+ end
14
+
15
+ def run_command(options = {})
16
+ command = OpenStruct.new({:parallel_id => parallel_id}.merge(options))
17
+ Scripted::Running::RunCommand.new(command, logger)
18
+ end
19
+
20
+ before do
21
+ Scripted::Running::Execute.stub(:call) do |command, delegate|
22
+ if command.failed?
23
+ delegate.failed!(RuntimeError.new)
24
+ else
25
+ delegate.success!
26
+ end
27
+ end
28
+ end
29
+
30
+ context "with normal commands" do
31
+
32
+ it "executes them all" do
33
+
34
+ command1 = run_command
35
+ command2 = run_command
36
+
37
+ run_commands.run [ command1, command2 ]
38
+
39
+ expect(command1).to be_executed
40
+ expect(command2).to be_executed
41
+
42
+ expect(run_commands).not_to be_failed
43
+
44
+ end
45
+
46
+ it "executes them all, even if one failed" do
47
+
48
+ command1 = run_command(:failed? => true)
49
+ command2 = run_command
50
+
51
+ run_commands.run [ command1, command2 ]
52
+
53
+ expect(command1).to be_executed
54
+ expect(command2).to be_executed
55
+
56
+ expect(run_commands).to be_failed
57
+
58
+ end
59
+
60
+ end
61
+
62
+ context "with important commands" do
63
+
64
+ it "stops executing when an important command failed" do
65
+
66
+ command1 = run_command(:failed? => true, :important? => true)
67
+ command2 = run_command
68
+
69
+ run_commands.run [ command1, command2 ]
70
+
71
+ expect(command1).to be_executed
72
+ expect(command2).not_to be_executed
73
+
74
+ expect(run_commands).to be_failed
75
+
76
+ end
77
+
78
+ it "still executes a forced command when an important command failed" do
79
+
80
+ command1 = run_command(:failed? => true, :important? => true)
81
+ command2 = run_command(:forced? => true)
82
+
83
+ run_commands.run [ command1, command2 ]
84
+
85
+ expect(command1).to be_executed
86
+ expect(command2).to be_executed
87
+
88
+ expect(run_commands).to be_failed
89
+
90
+ end
91
+
92
+ end
93
+
94
+ context "with unimportant commands" do
95
+
96
+ it "is still successful when unimportant command fails" do
97
+ command1 = run_command(:failed? => true, :unimportant? => true)
98
+ command2 = run_command
99
+
100
+ run_commands.run [ command1, command2 ]
101
+
102
+ expect(command1).to be_executed
103
+ expect(command2).to be_executed
104
+
105
+ expect(run_commands).not_to be_failed
106
+ end
107
+
108
+ end
109
+
110
+ context "with only_when_failed commands" do
111
+
112
+ it "doesn't execute only_when_failed-commands when nothing fails" do
113
+ command1 = run_command
114
+ command2 = run_command(:only_when_failed? => true)
115
+
116
+ run_commands.run [ command1, command2 ]
117
+
118
+ expect(command1).to be_executed
119
+ expect(command2).not_to be_executed
120
+
121
+ expect(run_commands).not_to be_failed
122
+ end
123
+
124
+ it "executes only_when_failed-commands when another command failed" do
125
+ command1 = run_command(:failed? => true)
126
+ command2 = run_command(:only_when_failed? => true)
127
+
128
+ run_commands.run [ command1, command2 ]
129
+
130
+ expect(command1).to be_executed
131
+ expect(command2).to be_executed
132
+
133
+ expect(run_commands).to be_failed
134
+ end
135
+
136
+ it "executes only_when_failed-commands when another command halted" do
137
+ command1 = run_command(:important? => true, :failed? => true)
138
+ command2 = run_command(:only_when_failed? => true)
139
+
140
+ run_commands.run [ command1, command2 ]
141
+
142
+ expect(command1).to be_executed
143
+ expect(command2).to be_executed
144
+
145
+ expect(run_commands).to be_failed
146
+ end
147
+
148
+ end
149
+
150
+ end