crazy_ivan 0.3.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +7 -3
- data/Rakefile +5 -1
- data/TODO +7 -1
- data/VERSION +1 -1
- data/bin/test_report2campfire +96 -0
- data/crazy_ivan.gemspec +19 -4
- data/lib/crazy_ivan/report_assembler.rb +74 -24
- data/lib/crazy_ivan/test_runner.rb +74 -28
- data/lib/crazy_ivan/vendor/open4-1.0.1/README +365 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/README.erb +365 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/Rakefile +225 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/lib/open4.rb +401 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/open4.gemspec +28 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/samples/bg.rb +21 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/samples/block.rb +19 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/samples/exception.rb +3 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/samples/simple.rb +15 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/samples/spawn.rb +16 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/samples/stdin_timeout.rb +9 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/samples/timeout.rb +37 -0
- data/lib/crazy_ivan/vendor/open4-1.0.1/white_box/leak.rb +17 -0
- data/lib/crazy_ivan/vendor/open4.rb +10 -0
- data/lib/crazy_ivan/version.rb +3 -3
- data/lib/crazy_ivan.rb +90 -42
- data/templates/css/ci.css +1 -0
- data/templates/index.html +40 -11
- data/test/crazy_ivan_test.rb +100 -18
- data/test/test_helper.rb +6 -0
- metadata +19 -3
data/lib/crazy_ivan.rb
CHANGED
@@ -1,73 +1,121 @@
|
|
1
|
+
require 'syslog'
|
1
2
|
require 'fileutils'
|
2
3
|
require 'crazy_ivan/report_assembler'
|
3
4
|
require 'crazy_ivan/test_runner'
|
4
5
|
require 'crazy_ivan/html_asset_crush'
|
5
6
|
require 'crazy_ivan/version'
|
6
7
|
require 'crazy_ivan/vendor/json'
|
8
|
+
require 'crazy_ivan/vendor/open4'
|
7
9
|
|
8
10
|
module CrazyIvan
|
9
11
|
def self.setup
|
12
|
+
puts
|
13
|
+
puts "Preparing per-project continuous integration configuration scripts"
|
14
|
+
puts
|
15
|
+
|
10
16
|
Dir['*'].each do |dir|
|
11
17
|
Dir.chdir(dir) do
|
12
18
|
FileUtils.mkdir_p('.ci')
|
13
19
|
|
14
20
|
Dir.chdir('.ci') do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
puts " #{dir}/.ci/update"
|
22
|
+
if File.exists?('version')
|
23
|
+
puts " #{' ' * (dir + "/.ci").size}/version already exists - skipping"
|
24
|
+
else
|
25
|
+
File.open('version', 'w+') do |f|
|
26
|
+
f.puts "#!/usr/bin/env ruby"
|
27
|
+
f.puts
|
28
|
+
f.puts "# This script grabs a unique version name from your version control system"
|
29
|
+
f.puts "#"
|
30
|
+
f.puts "# If you're not able to use a VCS, this script could just generate a timestamp."
|
31
|
+
f.puts
|
32
|
+
f.puts "puts `git show`[/^commit (.+)$/, 1]"
|
33
|
+
end
|
34
|
+
puts " #{' ' * (dir + "/.ci").size}/version -- created"
|
23
35
|
end
|
24
36
|
|
25
|
-
File.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
if File.exists?('update')
|
38
|
+
puts " #{' ' * (dir + "/.ci").size}/update already exists - skipping"
|
39
|
+
else
|
40
|
+
File.open('update', 'w+') do |f|
|
41
|
+
f.puts "#!/usr/bin/env bash"
|
42
|
+
f.puts
|
43
|
+
f.puts "# This script updates your code"
|
44
|
+
f.puts "#"
|
45
|
+
f.puts "# If you can’t use a version control system, this script could just do some"
|
46
|
+
f.puts "# some basic copying commands."
|
47
|
+
f.puts
|
48
|
+
f.puts "git pull"
|
49
|
+
end
|
50
|
+
puts " #{' ' * (dir + "/.ci").size}/update -- created"
|
34
51
|
end
|
35
52
|
|
36
|
-
File.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
53
|
+
if File.exists?('test')
|
54
|
+
puts " #{' ' * (dir + "/.ci").size}/test already exists -- skipping"
|
55
|
+
else
|
56
|
+
File.open('test', 'w+') do |f|
|
57
|
+
f.puts "#!/usr/bin/env bash"
|
58
|
+
f.puts
|
59
|
+
f.puts "# This script runs your testing suite. For a typical Ruby project running"
|
60
|
+
f.puts "# test-unit this is probably all you need."
|
61
|
+
f.puts
|
62
|
+
f.puts "rake"
|
63
|
+
end
|
64
|
+
puts " #{' ' * (dir + "/.ci").size}/test -- created"
|
65
|
+
end
|
66
|
+
|
67
|
+
if File.exists?('conclusion')
|
68
|
+
puts " #{' ' * (dir + "/.ci").size}/conclusion already exists -- skipping"
|
69
|
+
else
|
70
|
+
File.open('conclusion', 'w+') do |f|
|
71
|
+
f.puts "#!/usr/bin/env ruby"
|
72
|
+
f.puts
|
73
|
+
f.puts "# This script is piped the results of the testing suite run."
|
74
|
+
f.puts
|
75
|
+
f.puts "# If you're interested in bouncing the message to campfire, "
|
76
|
+
f.puts "# emailing, or otherwise sending notifications, this is the place to do it."
|
77
|
+
f.puts
|
78
|
+
f.puts "# To enable campfire notifications, uncomment the next lines:"
|
79
|
+
f.puts "# CAMPFIRE_ROOM_URL = 'http://your-company.campfirenow.com/room/265250'"
|
80
|
+
f.puts "# CAMPFIRE_API_KEY = '23b8al234gkj80a3e372133l4k4j34275f80ef8971'"
|
81
|
+
f.puts "# CRAZY_IVAN_REPORTS_URL = 'http://ci.your-projects.com'"
|
82
|
+
f.puts "# IO.popen(\"test_report2campfire \#{CAMPFIRE_ROOM_URL} \#{CAMPFIRE_API_KEY} \#{CRAZY_IVAN_REPORTS_URL}\", 'w') {|f| f.puts STDIN.read }"
|
83
|
+
f.puts
|
84
|
+
end
|
85
|
+
puts " #{' ' * (dir + "/.ci").size}/conclusion -- created"
|
43
86
|
end
|
87
|
+
puts
|
44
88
|
|
45
|
-
File.chmod 0755, 'update', 'version', 'test'
|
89
|
+
File.chmod 0755, 'update', 'version', 'test', 'conclusion'
|
46
90
|
end
|
47
|
-
|
48
|
-
puts
|
49
|
-
puts "Created #{dir}/.ci/update"
|
50
|
-
puts " #{' ' * (dir + "/.ci").size}/version"
|
51
|
-
puts " #{' ' * (dir + "/.ci").size}/test"
|
52
|
-
puts
|
53
|
-
puts "Take a look at those 3 scripts to make sure "
|
54
|
-
puts "they do the right thing for each case."
|
55
|
-
puts
|
56
91
|
end
|
57
92
|
end
|
93
|
+
|
94
|
+
puts "Take a look at those 4 scripts to make sure they each do the right thing."
|
95
|
+
puts
|
96
|
+
puts "When you're ready, run the following from the projects directory (here):"
|
97
|
+
puts
|
98
|
+
puts " crazy_ivan /path/to/directory/your/reports/go"
|
99
|
+
puts
|
100
|
+
puts "then look at index.html in that path to confirm that everything is ok."
|
101
|
+
puts
|
102
|
+
puts "If things look good, then set up a cron task or other script to run"
|
103
|
+
puts "crazy_ivan on a periodic basis."
|
104
|
+
puts
|
58
105
|
end
|
59
106
|
|
60
107
|
def self.generate_test_reports_in(output_directory)
|
108
|
+
Syslog.open('crazy_ivan', Syslog::LOG_PID | Syslog::LOG_CONS)
|
61
109
|
FileUtils.mkdir_p(output_directory)
|
62
|
-
report = ReportAssembler.new(output_directory)
|
63
|
-
|
64
|
-
Dir['*'].each do |dir|
|
65
|
-
if File.directory?(dir)
|
66
|
-
report.test_results << TestRunner.new(dir).invoke
|
67
|
-
end
|
68
|
-
end
|
69
110
|
|
111
|
+
report = ReportAssembler.new(Dir.pwd, output_directory)
|
70
112
|
report.generate
|
71
|
-
|
113
|
+
|
114
|
+
msg = "Generated test reports for #{report.runners.size} projects"
|
115
|
+
Syslog.info(msg)
|
116
|
+
puts msg
|
117
|
+
# REFACTOR to use a logger that spits out to both STDOUT and Syslog
|
118
|
+
ensure
|
119
|
+
Syslog.close
|
72
120
|
end
|
73
121
|
end
|
data/templates/css/ci.css
CHANGED
@@ -22,6 +22,7 @@ pre { margin: 0;}
|
|
22
22
|
|
23
23
|
.results .result { margin: 12px 18px 8px 18px;}
|
24
24
|
.results .result .timestamp { margin-right: 12px;}
|
25
|
+
.results .result .version { margin: 6px 0 6px 12px }
|
25
26
|
.results .result .update { margin: 6px 0 6px 12px }
|
26
27
|
.results .result .test { margin: 6px 0 6px 12px }
|
27
28
|
|
data/templates/index.html
CHANGED
@@ -33,7 +33,7 @@
|
|
33
33
|
return version_test_report(project_name, version);
|
34
34
|
})
|
35
35
|
|
36
|
-
project = {name: project_name, reports: reports};
|
36
|
+
project = {name: project_name, reports: reports.reverse(), build_in_progress: build_in_progress(project_name)};
|
37
37
|
projects.push(project);
|
38
38
|
})
|
39
39
|
|
@@ -64,6 +64,18 @@
|
|
64
64
|
return report;
|
65
65
|
}
|
66
66
|
|
67
|
+
var build_in_progress = function(project) {
|
68
|
+
var build_in_progress = {};
|
69
|
+
|
70
|
+
new Ajax.Request(project + '/currently_building.json', {
|
71
|
+
asynchronous: false,
|
72
|
+
onSuccess: function(transport) {
|
73
|
+
build_in_progress = transport.responseText.evalJSON();
|
74
|
+
}
|
75
|
+
});
|
76
|
+
return build_in_progress;
|
77
|
+
}
|
78
|
+
|
67
79
|
var expand = function(element) {
|
68
80
|
element.siblings().invoke('show');
|
69
81
|
element.remove();
|
@@ -77,10 +89,15 @@
|
|
77
89
|
{.repeated section @} \
|
78
90
|
<div class='project'> \
|
79
91
|
<h2>{name}</h2> \
|
92
|
+
{.section build_in_progress} \
|
93
|
+
{.section timestamp} \
|
94
|
+
<div>[build in progress – started at {start}]</div> \
|
95
|
+
{.end} \
|
96
|
+
{.end} \
|
80
97
|
<div class='tests'> \
|
81
98
|
{.section reports} \
|
82
99
|
{.repeated section @} \
|
83
|
-
<a class='test {.section
|
100
|
+
<a class='test {.section test} {.section exit_status} error {.end} {.end} {.section update} {.section exit_status} error {.end} {.end}' href='#'>{timestamp.finish}</a> \
|
84
101
|
{.end} \
|
85
102
|
{.end} \
|
86
103
|
</div> \
|
@@ -89,27 +106,39 @@
|
|
89
106
|
{.repeated section @} \
|
90
107
|
<div class='result'> \
|
91
108
|
<div> \
|
92
|
-
<span class='timestamp'>{timestamp}</span>
|
93
|
-
<span class='version'>{version}</span>
|
109
|
+
<span class='timestamp'>{timestamp.finish}</span> \
|
110
|
+
<span class='version'>{version.output}</span> \
|
94
111
|
</div> \
|
95
112
|
\
|
113
|
+
{.section version} \
|
114
|
+
{.section exit_status} \
|
115
|
+
<div class='version'> \
|
116
|
+
<pre class='error'>{error}</pre> \
|
117
|
+
</div> \
|
118
|
+
{.end} \
|
119
|
+
{.end} \
|
120
|
+
\
|
96
121
|
<div class='update'> \
|
97
|
-
<pre>{update}</pre>
|
98
|
-
{.section
|
99
|
-
|
122
|
+
<pre>{update.output}</pre> \
|
123
|
+
{.section update} \
|
124
|
+
{.section exit_status} \
|
125
|
+
<pre class='error'>{update.error}</pre> \
|
126
|
+
{.end} \
|
100
127
|
{.end} \
|
101
128
|
</div> \
|
102
129
|
\
|
103
130
|
<div class='test'> \
|
104
|
-
<pre>{test}</pre>
|
105
|
-
{.section
|
106
|
-
|
131
|
+
<pre>{test.output}</pre> \
|
132
|
+
{.section test} \
|
133
|
+
{.section exit_status} \
|
134
|
+
<pre class='error'>{test.error}</pre> \
|
135
|
+
{.end} \
|
107
136
|
{.end} \
|
108
137
|
</div> \
|
109
138
|
</div> \
|
110
139
|
{.end} \
|
111
140
|
{.or} \
|
112
|
-
<p>No test reports found. Please run
|
141
|
+
<p>No test reports found. Please run crazy_ivan.</p> \
|
113
142
|
{.end} \
|
114
143
|
</div> \
|
115
144
|
</div> \
|
data/test/crazy_ivan_test.rb
CHANGED
@@ -2,10 +2,18 @@ require 'test_helper'
|
|
2
2
|
require 'tmpdir'
|
3
3
|
|
4
4
|
class CrazyIvanTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@results = {:project_name => 'some-project',
|
7
|
+
:version => {:output => 'a-valid-version', :error => '', :exit_status => '0'},
|
8
|
+
:update => {:output => 'Updated successfully', :error => '', :exit_status => '0'},
|
9
|
+
:test => {:output => 'Some valid test results. No fails.', :error => '', :exit_status => '0'},
|
10
|
+
:timestamp => {:start => Time.now, :finish => nil}}
|
11
|
+
end
|
12
|
+
|
5
13
|
def test_setup
|
6
14
|
setup_crazy_ivan do
|
7
|
-
assert File.exists?('projects/some-project/.ci/version')
|
8
15
|
assert File.exists?('projects/some-project/.ci/update')
|
16
|
+
assert File.exists?('projects/some-project/.ci/version')
|
9
17
|
assert File.exists?('projects/some-project/.ci/test')
|
10
18
|
end
|
11
19
|
end
|
@@ -14,16 +22,12 @@ class CrazyIvanTest < Test::Unit::TestCase
|
|
14
22
|
setup_external_scripts_to_all_be_successful
|
15
23
|
|
16
24
|
setup_crazy_ivan do
|
17
|
-
|
18
|
-
|
19
|
-
# crazy_ivan runs from the projects directory
|
20
|
-
Dir.chdir('projects') do
|
21
|
-
CrazyIvan.generate_test_reports_in('../test-results')
|
22
|
-
end
|
25
|
+
run_crazy_ivan
|
23
26
|
|
24
27
|
assert File.exists?('test-results/index.html')
|
25
28
|
assert File.exists?('test-results/projects.json')
|
26
29
|
assert File.exists?('test-results/some-project/recent.json')
|
30
|
+
assert File.exists?('test-results/some-project/currently_building.json')
|
27
31
|
|
28
32
|
projects = JSON.parse(File.open('test-results/projects.json').read)["projects"]
|
29
33
|
recent_versions = JSON.parse(File.open('test-results/some-project/recent.json').read)["recent_versions"]
|
@@ -34,44 +38,122 @@ class CrazyIvanTest < Test::Unit::TestCase
|
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
41
|
+
# FIX Does this test really work? Doesn't look like it
|
37
42
|
def test_external_scripts_not_overwritten
|
38
43
|
setup_external_scripts_to_all_be_successful
|
39
44
|
|
40
45
|
setup_crazy_ivan do
|
41
|
-
CrazyIvan.setup
|
42
|
-
|
43
46
|
File.open('projects/some-project/.ci/version', 'a') do |file|
|
44
47
|
file << "a change to the script"
|
45
48
|
end
|
46
49
|
|
47
50
|
FileUtils.copy('projects/some-project/.ci/version', 'projects/some-project/.ci/version_original')
|
48
51
|
|
49
|
-
CrazyIvan.setup
|
50
|
-
|
52
|
+
do_silently { CrazyIvan.setup }
|
51
53
|
assert FileUtils.compare_file('projects/some-project/.ci/version_original', 'projects/some-project/.ci/version')
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
57
|
+
def test_nil_reports_not_created
|
58
|
+
Open4.stubs(:popen4).with('.ci/update').yields(stub(),
|
59
|
+
stub(:close),
|
60
|
+
stub(:read => @results[:update][:output]),
|
61
|
+
stub(:read => @results[:update][:error])).returns(stub(:exitstatus => '0'))
|
62
|
+
Open4.stubs(:popen4).with('.ci/version').yields(stub(),
|
63
|
+
stub(:close),
|
64
|
+
stub(:read => ''),
|
65
|
+
stub(:read => 'could not find the command you were looking for')).returns(stub(:exitstatus => '1'))
|
66
|
+
Open4.stubs(:popen4).with('.ci/conclusion').yields(stub(),
|
67
|
+
stub(:puts => true, :close => true),
|
68
|
+
stub(),
|
69
|
+
stub(:read => '')).returns(stub(:exitstatus => '0'))
|
70
|
+
|
71
|
+
setup_crazy_ivan do
|
72
|
+
Dir.chdir('projects') do
|
73
|
+
do_silently { CrazyIvan.generate_test_reports_in('../test-results') }
|
74
|
+
end
|
75
|
+
|
76
|
+
assert !File.exists?('test-results/some-project/nil.json')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_conclusion_executed
|
81
|
+
Open4.stubs(:popen4).with('.ci/update').yields(stub(),
|
82
|
+
stub(:close),
|
83
|
+
stub(:read => @results[:update][:output]),
|
84
|
+
stub(:read => @results[:update][:error])).returns(stub(:exitstatus => '0'))
|
85
|
+
Open4.stubs(:popen4).with('.ci/version').yields(stub(),
|
86
|
+
stub(:close),
|
87
|
+
stub(:read => @results[:version][:output]),
|
88
|
+
stub(:read => @results[:version][:error])).returns(stub(:exitstatus => '0'))
|
89
|
+
Open4.stubs(:popen4).with('.ci/test').yields(stub(),
|
90
|
+
stub(:close),
|
91
|
+
stub(:read => @results[:test][:output]),
|
92
|
+
stub(:read => @results[:test][:error])).returns(stub(:exitstatus => '0'))
|
93
|
+
|
94
|
+
@results[:timestamp][:start] = Time.now
|
95
|
+
@results[:timestamp][:finish] = @results[:timestamp][:start]
|
96
|
+
Time.stubs(:now => @results[:timestamp][:start])
|
97
|
+
|
98
|
+
fake_stdin = mock()
|
99
|
+
|
100
|
+
fake_stdin.expects(:puts).with(@results.to_json).at_least_once
|
101
|
+
fake_stdin.expects(:close)
|
102
|
+
|
103
|
+
Open4.stubs(:popen4).with('.ci/conclusion').yields(stub(), fake_stdin, stub(), stub(:read => '')).returns(stub(:exitstatus => '0'))
|
104
|
+
|
105
|
+
setup_crazy_ivan(false) do
|
106
|
+
run_crazy_ivan
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# def test_report_in_progress_json_created
|
111
|
+
# setup_crazy_ivan do
|
112
|
+
# run_crazy_ivan
|
113
|
+
# end
|
114
|
+
# end
|
115
|
+
|
55
116
|
private
|
56
117
|
|
57
|
-
def setup_crazy_ivan
|
118
|
+
def setup_crazy_ivan(with_multiple_projects = true)
|
58
119
|
Dir.mktmpdir('continuous-integration') do |tmpdir|
|
59
120
|
Dir.chdir(tmpdir)
|
60
121
|
|
61
122
|
Dir.mkdir('projects')
|
62
123
|
Dir.chdir('projects') do |projects_dir|
|
63
124
|
Dir.mkdir('some-project')
|
64
|
-
Dir.mkdir('some-other-project')
|
65
|
-
CrazyIvan.setup
|
125
|
+
Dir.mkdir('some-other-project') if with_multiple_projects
|
126
|
+
do_silently { CrazyIvan.setup }
|
66
127
|
end
|
67
128
|
|
68
|
-
yield
|
129
|
+
yield
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def run_crazy_ivan
|
134
|
+
# crazy_ivan runs from the projects directory
|
135
|
+
Dir.chdir('projects') do
|
136
|
+
do_silently { CrazyIvan.generate_test_reports_in('../test-results') }
|
69
137
|
end
|
70
138
|
end
|
71
139
|
|
72
140
|
def setup_external_scripts_to_all_be_successful
|
73
|
-
|
74
|
-
|
75
|
-
|
141
|
+
Open4.stubs(:popen4).with('.ci/update').yields(stub(),
|
142
|
+
stub(:close),
|
143
|
+
stub(:read => @results[:update][:output]),
|
144
|
+
stub(:read => @results[:update][:error])).returns(stub(:exitstatus => '0'))
|
145
|
+
Open4.stubs(:popen4).with('.ci/version').yields(stub(),
|
146
|
+
stub(:close),
|
147
|
+
stub(:read => @results[:version][:output]),
|
148
|
+
stub(:read => @results[:version][:error])).returns(stub(:exitstatus => '0'))
|
149
|
+
Open4.stubs(:popen4).with('.ci/test').yields(stub(),
|
150
|
+
stub(:close),
|
151
|
+
stub(:read => @results[:test][:output]),
|
152
|
+
stub(:read => @results[:test][:error])).returns(stub(:exitstatus => '0'))
|
153
|
+
|
154
|
+
Open4.stubs(:popen4).with('.ci/conclusion').yields(stub(),
|
155
|
+
stub(:puts => true, :close => true),
|
156
|
+
stub(),
|
157
|
+
stub(:read => '')).returns(stub(:exitstatus => '0'))
|
76
158
|
end
|
77
159
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crazy_ivan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edward Ocampo-Gooding
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-10 00:00:00 -05:00
|
13
13
|
default_executable: crazy_ivan
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -19,12 +19,13 @@ description: |-
|
|
19
19
|
By keeping test reports in json, per-project CI configuration in 3 probably-one-line scripts, things are kept simple, quick, and super extensible.
|
20
20
|
|
21
21
|
Want to use git, svn, or hg? No problem.
|
22
|
-
Need to fire off results to
|
22
|
+
Need to fire off results to Campfire? It's built-in.
|
23
23
|
|
24
24
|
CI depends on cron.
|
25
25
|
email: edward@edwardog.net
|
26
26
|
executables:
|
27
27
|
- crazy_ivan
|
28
|
+
- test_report2campfire
|
28
29
|
extensions: []
|
29
30
|
|
30
31
|
extra_rdoc_files:
|
@@ -39,6 +40,7 @@ files:
|
|
39
40
|
- TODO
|
40
41
|
- VERSION
|
41
42
|
- bin/crazy_ivan
|
43
|
+
- bin/test_report2campfire
|
42
44
|
- crazy_ivan.gemspec
|
43
45
|
- lib/crazy_ivan.rb
|
44
46
|
- lib/crazy_ivan/html_asset_crush.rb
|
@@ -159,6 +161,20 @@ files:
|
|
159
161
|
- lib/crazy_ivan/vendor/json-1.1.7/tools/fuzz.rb
|
160
162
|
- lib/crazy_ivan/vendor/json-1.1.7/tools/server.rb
|
161
163
|
- lib/crazy_ivan/vendor/json.rb
|
164
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/README
|
165
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/README.erb
|
166
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/Rakefile
|
167
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/lib/open4.rb
|
168
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/open4.gemspec
|
169
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/samples/bg.rb
|
170
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/samples/block.rb
|
171
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/samples/exception.rb
|
172
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/samples/simple.rb
|
173
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/samples/spawn.rb
|
174
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/samples/stdin_timeout.rb
|
175
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/samples/timeout.rb
|
176
|
+
- lib/crazy_ivan/vendor/open4-1.0.1/white_box/leak.rb
|
177
|
+
- lib/crazy_ivan/vendor/open4.rb
|
162
178
|
- lib/crazy_ivan/version.rb
|
163
179
|
- templates/css/ci.css
|
164
180
|
- templates/index.html
|