crazy_ivan 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
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