crazy_ivan 0.3.3 → 1.0.0
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/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
|