crazy_ivan 1.2.2 → 1.2.3

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/bin/crazy_ivan CHANGED
@@ -16,7 +16,6 @@ require "logger"
16
16
  Syslog.open('crazy_ivan', Syslog::LOG_PID | Syslog::LOG_CONS)
17
17
 
18
18
  Signal.trap("INT") do
19
- # Syslog.debug("Interrupted - Now dropping a note in the test output and exiting.")
20
19
  Syslog.debug("Interrupted - exiting.")
21
20
  CrazyIvan.interrupt_test
22
21
  ProcessManager.unlock
@@ -94,9 +94,12 @@ Campfire.basic_auth ARGV[1], 'x'
94
94
  campfire_room_id = campfire_url.path[/\d+/]
95
95
  campfire_room = Campfire.room(campfire_room_id)
96
96
 
97
- exit_status = report['test']['exit_status']
97
+ exit_status = report['test']['exit_status']
98
+ version = report['version']['output'][0...5]
99
+ version << '...' if report['version']['output'].size > 5
100
+
98
101
  if exit_status == "0" || exit_status.nil?
99
- campfire_room.message "#{report['project_name']} #{report['version']['output']} built happily: #{ARGV[2]}"
102
+ campfire_room.message "PASS: #{report['project_name']} #{version} built happily: #{ARGV[2]}"
100
103
  else
101
- campfire_room.message "#{report['project_name']} #{report['version']['output']} broke. Please take a look at #{ARGV[2]}"
104
+ campfire_room.message "FAIL: #{report['project_name']} #{version} broke. Please take a look at #{ARGV[2]}"
102
105
  end
@@ -34,7 +34,7 @@ class ProcessManager
34
34
  end
35
35
  else
36
36
  if ci_already_running?
37
- msg = "Detected another running CI process #{pid} - terminating myself"
37
+ msg = "Detected another running CI process #{pid} - interrupting and terminating myself"
38
38
  Syslog.warning msg
39
39
  puts msg
40
40
  Process.kill("INT", 0)
@@ -6,19 +6,11 @@ class ReportAssembler
6
6
 
7
7
  def initialize(projects_directory, output_directory)
8
8
  @runners = []
9
+ @projects = {}
9
10
  @projects_directory = projects_directory
10
11
  @output_directory = File.expand_path(output_directory, projects_directory)
11
12
  end
12
13
 
13
- def different_than_last_version?(runner)
14
- project_path = File.join(@output_directory, runner.project_name)
15
-
16
- Dir.chdir(project_path) do
17
- version = runner.results[:version][:output]
18
- Dir["#{version}.json"].size == 0
19
- end
20
- end
21
-
22
14
  def generate
23
15
  Dir.chdir(@projects_directory) do
24
16
  Dir['*'].each do |dir|
@@ -29,109 +21,126 @@ class ReportAssembler
29
21
  end
30
22
 
31
23
  Dir.chdir(@output_directory) do
24
+ # Write out the index.html file
32
25
  update_index
26
+
27
+ # Write out the projects.json file and the reports.json in each
33
28
  update_projects
29
+ init_project_reports
30
+
31
+ get_project_reports
34
32
 
35
33
  runners.each do |runner|
36
34
  # REFACTOR to run this block in multiple threads to have multi-project testing
37
-
35
+
38
36
  # Write the first version of the report with just the start time to currently_building.json
39
37
  runner.start!
40
- update_project(runner)
41
-
38
+ update_currently_building(runner)
39
+
42
40
  # Update the report in currently_building.json with the update output and error
43
41
  runner.update!
44
- update_project(runner)
45
-
42
+ update_currently_building(runner)
43
+
46
44
  # Update the report in currently_building.json with the version output and error
47
45
  runner.version!
48
- update_project(runner)
46
+ update_currently_building(runner)
49
47
 
50
- if different_than_last_version?(runner)
51
- # Empty the currently_building.json and add to recents.json this new report with the test output and error
52
- runner.test! # update_project will be called from within the runner to stream the test output
53
- update_project(runner)
54
- else
55
- flush_build_progress(runner)
48
+ if already_tested?(runner)
56
49
  Syslog.debug("Already tested #{runner.project_name} version #{runner.results[:version][:output]} - skipping test")
50
+ else
51
+ # update_project will be called from within the runner to stream the test output
52
+ runner.test!
53
+ update_project(runner)
57
54
  end
55
+ flush_build_progress(runner)
58
56
  end
59
57
  end
60
58
  end
61
59
 
62
- def filename_from_version(string)
63
- s = string[0..240]
60
+ def update_index
61
+ FileUtils.cp(File.expand_path("index.html", TEMPLATES_PATH), 'index.html')
62
+ FileUtils.mkdir_p('javascript')
63
+ FileUtils.cp(File.expand_path("date.js", File.join(TEMPLATES_PATH, 'javascript')), 'javascript/date.js')
64
+ end
65
+
66
+ def update_projects
67
+ projects = @runners.map {|r| r.project_name }
64
68
 
65
- return s
69
+ File.open('projects.json', 'w+') do |f|
70
+ f.print({"projects" => projects}.to_json)
71
+ end
66
72
  end
67
73
 
68
- def flush_build_progress(runner)
69
- project_results_path = File.join(@output_directory, runner.project_name)
74
+ def init_project_reports
75
+ projects = @runners.map {|r| r.project_name }
70
76
 
71
- Dir.chdir(project_results_path) do
72
- File.open("currently_building.json", 'w+') do |f|
73
- f.puts({}.to_json)
77
+ projects.each do |project_name|
78
+ FileUtils.mkdir_p(project_name)
79
+ Dir.chdir(project_name) do
80
+ if !File.exists?('reports.json')
81
+ File.open('reports.json', 'w+') do |f|
82
+ f.puts [].to_json
83
+ end
84
+ end
74
85
  end
75
86
  end
76
87
  end
77
88
 
78
- def update_project(runner)
89
+ def get_project_reports
90
+ projects = @runners.map {|r| r.project_name }
91
+
92
+ Dir.chdir(@output_directory) do
93
+ projects.each do |project_name|
94
+ reports = JSON.parse(File.read(File.expand_path('reports.json', project_name)))
95
+ @projects[project_name] = reports
96
+ end
97
+ end
98
+ end
99
+
100
+ def update_currently_building(runner)
79
101
  project_path = File.expand_path(runner.project_name, @output_directory)
80
- FileUtils.mkdir_p(project_path)
81
102
 
82
103
  Dir.chdir(project_path) do
83
- filename = ''
84
-
85
- if runner.still_building?
86
- filename = 'currently_building'
87
- else
88
- if runner.results[:version][:exit_status] == '0'
89
- filename = filename_from_version(runner.results[:version][:output])
90
- else
91
- filename = filename_from_version(runner.results[:version][:error])
92
- end
93
- end
94
-
95
- File.open("#{filename}.json", 'w+') do |f|
104
+ File.open('currently_building.json', 'w+') do |f|
96
105
  f.puts runner.results.to_json
97
106
  end
98
-
99
- if runner.finished?
100
- Syslog.debug "Runner is FINISHED"
101
- flush_build_progress(runner)
102
- update_recent(runner.results, filename)
103
- end
104
107
  end
105
108
  end
106
109
 
107
- def update_recent(result, filename)
108
- recent_versions_json = File.open('recent.json', File::RDWR | File::CREAT).read
109
-
110
- recent_versions = []
110
+ def already_tested?(runner)
111
+ project_path = File.join(@output_directory, runner.project_name)
111
112
 
112
- if !recent_versions_json.empty?
113
- recent_versions = JSON.parse(recent_versions_json)["recent_versions"]
113
+ Dir.chdir(project_path) do
114
+ version = runner.results[:version][:output]
115
+ tested_versions = @projects[runner.project_name].map {|r| r['version']['output'] }
116
+ tested_versions.include?(version)
114
117
  end
118
+ end
119
+
120
+ def update_project(runner)
121
+ project_path = File.expand_path(runner.project_name, @output_directory)
115
122
 
116
- recent_versions << filename
117
- recent_versions.shift if recent_versions.size > MAXIMUM_RECENTS
123
+ @projects[runner.project_name] << runner.results
124
+ cull_old_reports(runner.project_name)
118
125
 
119
- File.open('recent.json', 'w+') do |f|
120
- f.print({"recent_versions" => recent_versions}.to_json)
126
+ Dir.chdir(project_path) do
127
+ File.open("reports.json", 'w+') do |f|
128
+ f.puts @projects[runner.project_name].to_json
129
+ end
121
130
  end
122
131
  end
123
132
 
124
- def update_projects
125
- projects = @runners.map {|r| r.project_name }
126
-
127
- File.open('projects.json', 'w+') do |f|
128
- f.print({"projects" => projects}.to_json)
129
- end
133
+ def cull_old_reports(project_name)
134
+ @projects[project_name].shift if @projects[project_name].size > MAXIMUM_RECENTS
130
135
  end
131
136
 
132
- def update_index
133
- FileUtils.cp(File.expand_path("index.html", TEMPLATES_PATH), 'index.html')
134
- FileUtils.mkdir_p('javascript')
135
- FileUtils.cp(File.expand_path("date.js", File.join(TEMPLATES_PATH, 'javascript')), 'javascript/date.js')
137
+ def flush_build_progress(runner)
138
+ project_results_path = File.join(@output_directory, runner.project_name)
139
+
140
+ Dir.chdir(project_results_path) do
141
+ File.open("currently_building.json", 'w+') do |f|
142
+ f.puts({}.to_json)
143
+ end
144
+ end
136
145
  end
137
146
  end
@@ -63,9 +63,9 @@
63
63
  .project h2 { margin: 12px 0 0 0;}
64
64
 
65
65
  .tests { margin: 0 0 0 18px;}
66
- .tests .test { font-size: 80%; margin-right: 8px}
66
+ .tests .test { margin-right: 8px}
67
67
  .tests a.test:hover { text-decoration: underline;}
68
- .tests .test:first-child { font-size: 100%;}
68
+ .tests .test.first { font-size: 100%;}
69
69
  .tests .test.active { font-weight: bold;}
70
70
 
71
71
  .result .timestamp { margin-right: 12px;}
@@ -98,16 +98,22 @@
98
98
  <h2><%= projectName %></h2>
99
99
 
100
100
  <div class="tests"></div>
101
+ <div style="clear: left"></div>
101
102
  <div class="results"></div>
102
103
  <div>
103
104
  </script>
104
105
 
105
106
  <!-- test link template -->
106
107
  <script type="text/html" id="resultLinkTemplate">
107
- <a id="<%= projectDomId %>-<%= version.output %>" class="test"><%= shortTimeStamp %></a>
108
+ <div style="float: left; margin-right: 8px">
109
+ <div style="float:left; height: 1.2em; font-size: 84%"><%= longTimeStamp %></div>
110
+ <div style="clear: left">
111
+ <a id="<%= projectDomId %>-<%= version.output %>" class="test"><%= shortTimeStamp %></a>
112
+ </div>
113
+ </div>
108
114
  </script>
109
115
 
110
- <!-- build result holder -->
116
+ <!-- build rult holder -->
111
117
  <script type="text/html" id="resultTemplate">
112
118
  <div class="result <%= projectDomId %>-<%= version.output %>" style="display: none">
113
119
  <div>
@@ -133,9 +139,11 @@
133
139
 
134
140
  <script type="text/javascript" charset="utf-8">
135
141
  var json = {projects: []};
142
+ var projectNames;
136
143
 
137
144
  jQuery(document).ready(function($) {
138
145
  $.getJSON("projects.json", function(data) {
146
+ projectNames = data.projects;
139
147
  jQuery.each(data.projects, function(i, projectName) {
140
148
  addProjectToJson(projectName);
141
149
  });
@@ -143,66 +151,71 @@
143
151
  });
144
152
 
145
153
  function addProjectToJson(name) {
146
- var project = {'name': name, reports: []};
147
- var recentVersionsJsonPath = name + "/recent.json";
148
-
149
- jQuery.getJSON(recentVersionsJsonPath, function(data) {
150
- jQuery.each(data.recent_versions, function(i, version) {
151
- addReportToProject(project, version);
152
- });
153
- });
154
+ var projectJsonPath = name + "/reports.json";
154
155
 
155
- json.projects.push(project);
156
- }
157
-
158
- function addReportToProject(project, version) {
159
- var name = project.name;
160
- var resultJsonPath = name + "/" + version + ".json";
161
- jQuery.getJSON(resultJsonPath, function(data) {
162
- project.reports.push(data);
156
+ jQuery.getJSON(projectJsonPath, function(data) {
157
+ json.projects.push({'name': name, reports: data});
163
158
  trigger_render();
164
159
  });
165
160
  }
166
161
 
167
- function sortReports(reports) {
168
- return reports.sort(function(report_a, report_b) {
169
- // Not sure why providing a 3-letter day trips up Date.js sometimes
170
- a = Date.parse(report_a.timestamp.finish.substring(4));
171
- b = Date.parse(report_b.timestamp.finish.substring(4));
172
-
173
- return Date.compare(a, b);
174
- });
175
- }
176
-
177
162
  var timeout = null;
178
163
  function trigger_render() {
179
164
  if (timeout) { clearTimeout(timeout) }
180
165
  timeout = setTimeout(render, 50);
181
166
  }
182
167
 
168
+ function orderedProjects(projects) {
169
+ var orderedProjects = [];
170
+
171
+ // order the projects by what the projects.json returns
172
+ for(var name in projectNames) {
173
+ for(var project in projects) {
174
+ if(projects[project].name == projectNames[name]) {
175
+ orderedProjects.push(projects[project]);
176
+ break;
177
+ }
178
+ }
179
+ }
180
+ return orderedProjects;
181
+ }
182
+
183
183
  var render = function() {
184
184
  $('#projects').empty();
185
185
 
186
- jQuery.each(json.projects, function(i, project) {
186
+ var sortedProjects = orderedProjects(json.projects);
187
+
188
+ jQuery.each(sortedProjects, function(i, project) {
187
189
  var name = project.name;
188
190
  var domId = name.replace(/\./g, ""); // remove . from id name
189
191
 
190
192
  // create project holder div
191
193
  $('#projects').append(tmpl("projectTemplate", {projectName: name, projectId: domId}));
192
194
 
193
- project.reports = sortReports(project.reports);
194
-
195
- jQuery.each(project.reports, function(i, report) {
195
+ jQuery.each(project.reports.reverse(), function(i, report) {
196
196
  var version = report.version.output;
197
197
  var resultJsonPath = name + "/" + version + ".json";
198
198
  var domId = name.replace(/\./g, ""); // remove . from id name
199
199
 
200
+ var timestamp = report.timestamp.finish;
201
+ report["longTimeStamp"] = Date.parse(timestamp.substring(4)).toString("MMM d");
202
+
203
+ // To group the long time stamps (e.g. Feb 8)
204
+ if(project.reports[i - 1] != undefined) {
205
+ next_timestamp = project.reports[i - 1].timestamp.finish;
206
+ next_longTimeStamp = Date.parse(next_timestamp.substring(4)).toString("MMM d");
207
+
208
+ if(report["longTimeStamp"] == next_longTimeStamp) {
209
+ report["longTimeStamp"] = "";
210
+ }
211
+ }
212
+
200
213
  // Not sure why providing a 3-letter day trips up Date.js sometimes
201
- report["shortTimeStamp"] = Date.parse(report.timestamp.finish.substring(4)).toString("HH:mm");
214
+ report["shortTimeStamp"] = Date.parse(timestamp.substring(4)).toString("HH:mm");
202
215
  report["projectDomId"] = domId;
203
216
 
204
217
  $("#" + domId + " .results").append(tmpl("resultTemplate", report));
205
- $("#" + domId + " .tests").prepend(tmpl("resultLinkTemplate", report));
218
+ $("#" + domId + " .tests").append(tmpl("resultLinkTemplate", report));
206
219
 
207
220
  // add failed/success indication to link - inlining in the template screws up
208
221
  if (report.test.exit_status && report.test.exit_status != '0') {
@@ -72,7 +72,7 @@ class TestRunner
72
72
 
73
73
  if options[:stream_test_results?]
74
74
  @results[:test][:output] = output
75
- @report_assembler.update_project(self)
75
+ @report_assembler.update_currently_building(self)
76
76
  end
77
77
  end
78
78
 
@@ -83,7 +83,7 @@ class TestRunner
83
83
 
84
84
  if options[:stream_test_results?]
85
85
  @results[:test][:error] = error
86
- @report_assembler.update_project(self)
86
+ @report_assembler.update_currently_building(self)
87
87
  end
88
88
  end
89
89
 
@@ -96,7 +96,7 @@ class TestRunner
96
96
 
97
97
  if options[:stream_test_results?]
98
98
  @results[:test][:error] = error
99
- @report_assembler.update_project(self)
99
+ @report_assembler.update_currently_building(self)
100
100
  end
101
101
  end
102
102
  end
@@ -1,3 +1,3 @@
1
1
  module CrazyIvan
2
- VERSION = '1.2.2'
2
+ VERSION = '1.2.3'
3
3
  end
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: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edward Ocampo-Gooding