scripted 0.0.1
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/.gitignore +19 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/Gemfile +6 -0
- data/MIT-LICENSE +22 -0
- data/README.md +423 -0
- data/Rakefile +39 -0
- data/bin/scripted +67 -0
- data/cucumber.yml +3 -0
- data/examples/important.rb +31 -0
- data/examples/parallel.rb +30 -0
- data/examples/pride.rb +37 -0
- data/examples/websockets.png +0 -0
- data/examples/websockets.rb +37 -0
- data/examples/websockets/public/ansiparse.js +156 -0
- data/examples/websockets/server.rb +32 -0
- data/examples/websockets/server.ru +10 -0
- data/examples/websockets/views/_client.handlebars +47 -0
- data/examples/websockets/views/app.coffee +210 -0
- data/examples/websockets/views/index.erb +1 -0
- data/examples/websockets/views/layout.erb +14 -0
- data/examples/websockets/views/style.sass +61 -0
- data/features/controlling_exit_status.feature +124 -0
- data/features/formatters.feature +142 -0
- data/features/rake_integration.feature +86 -0
- data/features/running_commands_in_parallel.feature +27 -0
- data/features/running_from_command_line.feature +56 -0
- data/features/running_from_ruby.feature +38 -0
- data/features/running_groups.feature +39 -0
- data/features/specifying_which_commands_to_run.feature +122 -0
- data/features/steps/scripted_steps.rb +25 -0
- data/features/support/aruba.rb +5 -0
- data/features/support/env.rb +2 -0
- data/install +5 -0
- data/lib/scripted.rb +28 -0
- data/lib/scripted/command.rb +82 -0
- data/lib/scripted/commands/rake.rb +25 -0
- data/lib/scripted/commands/ruby.rb +22 -0
- data/lib/scripted/commands/shell.rb +28 -0
- data/lib/scripted/configuration.rb +103 -0
- data/lib/scripted/error.rb +13 -0
- data/lib/scripted/formatters/announcer.rb +39 -0
- data/lib/scripted/formatters/blank.rb +97 -0
- data/lib/scripted/formatters/default.rb +62 -0
- data/lib/scripted/formatters/human_status.rb +38 -0
- data/lib/scripted/formatters/stats.rb +38 -0
- data/lib/scripted/formatters/table.rb +99 -0
- data/lib/scripted/formatters/websocket.rb +137 -0
- data/lib/scripted/group.rb +49 -0
- data/lib/scripted/output/command_logger.rb +42 -0
- data/lib/scripted/output/logger.rb +139 -0
- data/lib/scripted/rake_task.rb +24 -0
- data/lib/scripted/runner.rb +19 -0
- data/lib/scripted/running/execute.rb +16 -0
- data/lib/scripted/running/run_command.rb +101 -0
- data/lib/scripted/running/run_commands.rb +98 -0
- data/lib/scripted/running/select_commands.rb +22 -0
- data/lib/scripted/version.rb +3 -0
- data/scripted.gemspec +35 -0
- data/scripted.rb +16 -0
- data/spec/scripted/command_spec.rb +72 -0
- data/spec/scripted/commands/ruby_spec.rb +10 -0
- data/spec/scripted/commands/shell_spec.rb +18 -0
- data/spec/scripted/configuration_spec.rb +50 -0
- data/spec/scripted/formatters/websocket_spec.rb +14 -0
- data/spec/scripted/group_spec.rb +49 -0
- data/spec/scripted/running/run_command_spec.rb +157 -0
- data/spec/scripted/running/run_commands_spec.rb +150 -0
- data/spec/scripted/running/select_commands_spec.rb +28 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/expect_to_receive.rb +17 -0
- data/spec/support/io_capture.rb +50 -0
- metadata +340 -0
data/scripted.rb
ADDED
@@ -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,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
|