rubycritic 0.0.14 → 0.0.15
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.
- checksums.yaml +4 -4
- data/README.md +16 -4
- data/bin/rubycritic +2 -0
- data/lib/rubycritic/adapters/complexity/flog.rb +8 -6
- data/lib/rubycritic/adapters/smell/flay.rb +31 -9
- data/lib/rubycritic/adapters/smell/flog.rb +18 -9
- data/lib/rubycritic/adapters/smell/reek.rb +12 -5
- data/lib/rubycritic/analysers/churn.rb +6 -3
- data/lib/rubycritic/analysers/stats.rb +31 -0
- data/lib/rubycritic/analysers_runner.rb +13 -19
- data/lib/rubycritic/cli.rb +34 -18
- data/lib/rubycritic/configuration.rb +7 -1
- data/lib/rubycritic/core/analysed_file.rb +27 -1
- data/lib/rubycritic/core/location.rb +1 -1
- data/lib/rubycritic/core/rating.rb +22 -0
- data/lib/rubycritic/core/smell.rb +3 -12
- data/lib/rubycritic/files_initializer.rb +15 -0
- data/lib/rubycritic/orchestrator.rb +23 -0
- data/lib/rubycritic/report_generators/assets/javascripts/application.js +5 -3
- data/lib/rubycritic/report_generators/assets/javascripts/jquery.timeago-v1.4.1.js +214 -0
- data/lib/rubycritic/report_generators/assets/stylesheets/application.css +87 -2
- data/lib/rubycritic/report_generators/code_file.rb +1 -3
- data/lib/rubycritic/report_generators/code_index.rb +0 -1
- data/lib/rubycritic/report_generators/current_code_file.rb +17 -0
- data/lib/rubycritic/report_generators/line.rb +0 -1
- data/lib/rubycritic/report_generators/overview.rb +1 -2
- data/lib/rubycritic/report_generators/smells_index.rb +0 -1
- data/lib/rubycritic/report_generators/templates/code_file.html.erb +28 -1
- data/lib/rubycritic/report_generators/templates/code_index.html.erb +6 -2
- data/lib/rubycritic/report_generators/templates/layouts/application.html.erb +8 -7
- data/lib/rubycritic/report_generators/templates/overview.html.erb +1 -1
- data/lib/rubycritic/report_generators/view_helpers.rb +6 -2
- data/lib/rubycritic/reporters/main.rb +7 -3
- data/lib/rubycritic/reporters/mini.rb +13 -4
- data/lib/rubycritic/revision_comparator.rb +15 -16
- data/lib/rubycritic/serializer.rb +32 -0
- data/lib/rubycritic/smells_status_setter.rb +5 -11
- data/lib/rubycritic/source_control_systems/base.rb +60 -0
- data/lib/rubycritic/source_control_systems/double.rb +19 -0
- data/lib/rubycritic/source_control_systems/git.rb +46 -40
- data/lib/rubycritic/turbulence.rb +3 -7
- data/lib/rubycritic/version.rb +1 -1
- data/lib/rubycritic.rb +1 -7
- data/rubycritic.gemspec +1 -0
- data/test/lib/rubycritic/adapters/complexity/flog_test.rb +5 -5
- data/test/lib/rubycritic/adapters/smell/flay_test.rb +19 -8
- data/test/lib/rubycritic/adapters/smell/flog_test.rb +11 -8
- data/test/lib/rubycritic/adapters/smell/reek_test.rb +14 -10
- data/test/lib/rubycritic/analysers/churn_test.rb +23 -8
- data/test/lib/rubycritic/core/analysed_file_test.rb +31 -11
- data/test/lib/rubycritic/core/smell_test.rb +13 -20
- data/test/lib/rubycritic/smells_status_setter_test.rb +2 -2
- data/test/lib/rubycritic/source_control_systems/source_control_system_test.rb +5 -12
- data/test/lib/rubycritic/turbulence_test.rb +1 -2
- data/test/lib/rubycritic/version_test.rb +1 -0
- data/test/samples/flog/{smelly2.rb → complex.rb} +0 -0
- data/test/test_helper.rb +1 -0
- metadata +27 -17
- data/lib/rubycritic/active_support/methods.rb +0 -36
- data/lib/rubycritic/analysed_files_builder.rb +0 -36
- data/lib/rubycritic/orchestrators/base.rb +0 -27
- data/lib/rubycritic/orchestrators/main.rb +0 -14
- data/lib/rubycritic/orchestrators/mini.rb +0 -14
- data/lib/rubycritic/smells_serializer.rb +0 -32
- data/lib/rubycritic/source_control_systems/source_control_system.rb +0 -50
- data/test/lib/rubycritic/analysed_files_builder_test.rb +0 -36
- data/test/lib/rubycritic/analysers_runner_test.rb +0 -11
- data/test/samples/analysers_runner/empty.rb +0 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
/**
|
2
|
+
* Timeago is a jQuery plugin that makes it easy to support automatically
|
3
|
+
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
|
4
|
+
*
|
5
|
+
* @name timeago
|
6
|
+
* @version 1.4.1
|
7
|
+
* @requires jQuery v1.2.3+
|
8
|
+
* @author Ryan McGeary
|
9
|
+
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
|
10
|
+
*
|
11
|
+
* For usage and examples, visit:
|
12
|
+
* http://timeago.yarp.com/
|
13
|
+
*
|
14
|
+
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
|
15
|
+
*/
|
16
|
+
|
17
|
+
(function (factory) {
|
18
|
+
if (typeof define === 'function' && define.amd) {
|
19
|
+
// AMD. Register as an anonymous module.
|
20
|
+
define(['jquery'], factory);
|
21
|
+
} else {
|
22
|
+
// Browser globals
|
23
|
+
factory(jQuery);
|
24
|
+
}
|
25
|
+
}(function ($) {
|
26
|
+
$.timeago = function(timestamp) {
|
27
|
+
if (timestamp instanceof Date) {
|
28
|
+
return inWords(timestamp);
|
29
|
+
} else if (typeof timestamp === "string") {
|
30
|
+
return inWords($.timeago.parse(timestamp));
|
31
|
+
} else if (typeof timestamp === "number") {
|
32
|
+
return inWords(new Date(timestamp));
|
33
|
+
} else {
|
34
|
+
return inWords($.timeago.datetime(timestamp));
|
35
|
+
}
|
36
|
+
};
|
37
|
+
var $t = $.timeago;
|
38
|
+
|
39
|
+
$.extend($.timeago, {
|
40
|
+
settings: {
|
41
|
+
refreshMillis: 60000,
|
42
|
+
allowPast: true,
|
43
|
+
allowFuture: false,
|
44
|
+
localeTitle: false,
|
45
|
+
cutoff: 0,
|
46
|
+
strings: {
|
47
|
+
prefixAgo: null,
|
48
|
+
prefixFromNow: null,
|
49
|
+
suffixAgo: "ago",
|
50
|
+
suffixFromNow: "from now",
|
51
|
+
inPast: 'any moment now',
|
52
|
+
seconds: "less than a minute",
|
53
|
+
minute: "about a minute",
|
54
|
+
minutes: "%d minutes",
|
55
|
+
hour: "about an hour",
|
56
|
+
hours: "about %d hours",
|
57
|
+
day: "a day",
|
58
|
+
days: "%d days",
|
59
|
+
month: "about a month",
|
60
|
+
months: "%d months",
|
61
|
+
year: "about a year",
|
62
|
+
years: "%d years",
|
63
|
+
wordSeparator: " ",
|
64
|
+
numbers: []
|
65
|
+
}
|
66
|
+
},
|
67
|
+
|
68
|
+
inWords: function(distanceMillis) {
|
69
|
+
if(!this.settings.allowPast && ! this.settings.allowFuture) {
|
70
|
+
throw 'timeago allowPast and allowFuture settings can not both be set to false.';
|
71
|
+
}
|
72
|
+
|
73
|
+
var $l = this.settings.strings;
|
74
|
+
var prefix = $l.prefixAgo;
|
75
|
+
var suffix = $l.suffixAgo;
|
76
|
+
if (this.settings.allowFuture) {
|
77
|
+
if (distanceMillis < 0) {
|
78
|
+
prefix = $l.prefixFromNow;
|
79
|
+
suffix = $l.suffixFromNow;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
if(!this.settings.allowPast && distanceMillis >= 0) {
|
84
|
+
return this.settings.strings.inPast;
|
85
|
+
}
|
86
|
+
|
87
|
+
var seconds = Math.abs(distanceMillis) / 1000;
|
88
|
+
var minutes = seconds / 60;
|
89
|
+
var hours = minutes / 60;
|
90
|
+
var days = hours / 24;
|
91
|
+
var years = days / 365;
|
92
|
+
|
93
|
+
function substitute(stringOrFunction, number) {
|
94
|
+
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
|
95
|
+
var value = ($l.numbers && $l.numbers[number]) || number;
|
96
|
+
return string.replace(/%d/i, value);
|
97
|
+
}
|
98
|
+
|
99
|
+
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
|
100
|
+
seconds < 90 && substitute($l.minute, 1) ||
|
101
|
+
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
|
102
|
+
minutes < 90 && substitute($l.hour, 1) ||
|
103
|
+
hours < 24 && substitute($l.hours, Math.round(hours)) ||
|
104
|
+
hours < 42 && substitute($l.day, 1) ||
|
105
|
+
days < 30 && substitute($l.days, Math.round(days)) ||
|
106
|
+
days < 45 && substitute($l.month, 1) ||
|
107
|
+
days < 365 && substitute($l.months, Math.round(days / 30)) ||
|
108
|
+
years < 1.5 && substitute($l.year, 1) ||
|
109
|
+
substitute($l.years, Math.round(years));
|
110
|
+
|
111
|
+
var separator = $l.wordSeparator || "";
|
112
|
+
if ($l.wordSeparator === undefined) { separator = " "; }
|
113
|
+
return $.trim([prefix, words, suffix].join(separator));
|
114
|
+
},
|
115
|
+
|
116
|
+
parse: function(iso8601) {
|
117
|
+
var s = $.trim(iso8601);
|
118
|
+
s = s.replace(/\.\d+/,""); // remove milliseconds
|
119
|
+
s = s.replace(/-/,"/").replace(/-/,"/");
|
120
|
+
s = s.replace(/T/," ").replace(/Z/," UTC");
|
121
|
+
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
|
122
|
+
s = s.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900
|
123
|
+
return new Date(s);
|
124
|
+
},
|
125
|
+
datetime: function(elem) {
|
126
|
+
var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
|
127
|
+
return $t.parse(iso8601);
|
128
|
+
},
|
129
|
+
isTime: function(elem) {
|
130
|
+
// jQuery's `is()` doesn't play well with HTML5 in IE
|
131
|
+
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
|
132
|
+
}
|
133
|
+
});
|
134
|
+
|
135
|
+
// functions that can be called via $(el).timeago('action')
|
136
|
+
// init is default when no action is given
|
137
|
+
// functions are called with context of a single element
|
138
|
+
var functions = {
|
139
|
+
init: function(){
|
140
|
+
var refresh_el = $.proxy(refresh, this);
|
141
|
+
refresh_el();
|
142
|
+
var $s = $t.settings;
|
143
|
+
if ($s.refreshMillis > 0) {
|
144
|
+
this._timeagoInterval = setInterval(refresh_el, $s.refreshMillis);
|
145
|
+
}
|
146
|
+
},
|
147
|
+
update: function(time){
|
148
|
+
var parsedTime = $t.parse(time);
|
149
|
+
$(this).data('timeago', { datetime: parsedTime });
|
150
|
+
if($t.settings.localeTitle) $(this).attr("title", parsedTime.toLocaleString());
|
151
|
+
refresh.apply(this);
|
152
|
+
},
|
153
|
+
updateFromDOM: function(){
|
154
|
+
$(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) });
|
155
|
+
refresh.apply(this);
|
156
|
+
},
|
157
|
+
dispose: function () {
|
158
|
+
if (this._timeagoInterval) {
|
159
|
+
window.clearInterval(this._timeagoInterval);
|
160
|
+
this._timeagoInterval = null;
|
161
|
+
}
|
162
|
+
}
|
163
|
+
};
|
164
|
+
|
165
|
+
$.fn.timeago = function(action, options) {
|
166
|
+
var fn = action ? functions[action] : functions.init;
|
167
|
+
if(!fn){
|
168
|
+
throw new Error("Unknown function name '"+ action +"' for timeago");
|
169
|
+
}
|
170
|
+
// each over objects here and call the requested function
|
171
|
+
this.each(function(){
|
172
|
+
fn.call(this, options);
|
173
|
+
});
|
174
|
+
return this;
|
175
|
+
};
|
176
|
+
|
177
|
+
function refresh() {
|
178
|
+
var data = prepareData(this);
|
179
|
+
var $s = $t.settings;
|
180
|
+
|
181
|
+
if (!isNaN(data.datetime)) {
|
182
|
+
if ( $s.cutoff == 0 || Math.abs(distance(data.datetime)) < $s.cutoff) {
|
183
|
+
$(this).text(inWords(data.datetime));
|
184
|
+
}
|
185
|
+
}
|
186
|
+
return this;
|
187
|
+
}
|
188
|
+
|
189
|
+
function prepareData(element) {
|
190
|
+
element = $(element);
|
191
|
+
if (!element.data("timeago")) {
|
192
|
+
element.data("timeago", { datetime: $t.datetime(element) });
|
193
|
+
var text = $.trim(element.text());
|
194
|
+
if ($t.settings.localeTitle) {
|
195
|
+
element.attr("title", element.data('timeago').datetime.toLocaleString());
|
196
|
+
} else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
|
197
|
+
element.attr("title", text);
|
198
|
+
}
|
199
|
+
}
|
200
|
+
return element.data("timeago");
|
201
|
+
}
|
202
|
+
|
203
|
+
function inWords(date) {
|
204
|
+
return $t.inWords(distance(date));
|
205
|
+
}
|
206
|
+
|
207
|
+
function distance(date) {
|
208
|
+
return (new Date().getTime() - date.getTime());
|
209
|
+
}
|
210
|
+
|
211
|
+
// fix for IE6 suckage
|
212
|
+
document.createElement("abbr");
|
213
|
+
document.createElement("time");
|
214
|
+
}));
|
@@ -54,6 +54,16 @@ html {
|
|
54
54
|
background-color: white;
|
55
55
|
}
|
56
56
|
|
57
|
+
.index-table .circle {
|
58
|
+
width: 28px;
|
59
|
+
height: 28px;
|
60
|
+
}
|
61
|
+
|
62
|
+
.index-table .circled-rating {
|
63
|
+
display: inline-block;
|
64
|
+
line-height: 28px;
|
65
|
+
}
|
66
|
+
|
57
67
|
.sortable-table .headerSortUp,
|
58
68
|
.sortable-table .headerSortDown {
|
59
69
|
border: 1px solid silver;
|
@@ -81,6 +91,10 @@ html {
|
|
81
91
|
text-align: right;
|
82
92
|
}
|
83
93
|
|
94
|
+
.index-table .centered-cell {
|
95
|
+
text-align: center;
|
96
|
+
}
|
97
|
+
|
84
98
|
.button {
|
85
99
|
margin: 0;
|
86
100
|
padding: 0.5em 1em;
|
@@ -93,21 +107,92 @@ html {
|
|
93
107
|
transition-duration: 0.5s;
|
94
108
|
}
|
95
109
|
|
110
|
+
.circle {
|
111
|
+
display: block;
|
112
|
+
border-radius: 50%;
|
113
|
+
}
|
114
|
+
|
115
|
+
.circled-rating {
|
116
|
+
text-align: center;
|
117
|
+
color: white;
|
118
|
+
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
|
119
|
+
font-weight: bold;
|
120
|
+
-webkit-user-select: none;
|
121
|
+
-moz-user-select: none;
|
122
|
+
-ms-user-select: none;
|
123
|
+
user-select: none;
|
124
|
+
cursor: default;
|
125
|
+
}
|
126
|
+
|
96
127
|
.file-header {
|
97
128
|
position: relative;
|
98
129
|
padding: 0 0 10px 60px;
|
99
130
|
border-bottom: 1px solid silver;
|
100
131
|
}
|
101
132
|
|
133
|
+
.file-header .circle {
|
134
|
+
width: 50px;
|
135
|
+
height: 50px;
|
136
|
+
}
|
137
|
+
|
138
|
+
.file-header .circled-rating {
|
139
|
+
float: left;
|
140
|
+
line-height: 50px;
|
141
|
+
font-size: 32px;
|
142
|
+
}
|
143
|
+
|
144
|
+
.rating-a {
|
145
|
+
background-color: #2ECC40;
|
146
|
+
}
|
147
|
+
|
148
|
+
.rating-b {
|
149
|
+
background-color: #2ECC40;
|
150
|
+
}
|
151
|
+
|
152
|
+
.rating-c {
|
153
|
+
background-color: #FFDC00;
|
154
|
+
}
|
155
|
+
|
156
|
+
.rating-d {
|
157
|
+
background-color: #FF851B;
|
158
|
+
}
|
159
|
+
|
160
|
+
.rating-f {
|
161
|
+
background-color: #FF4136;
|
162
|
+
}
|
163
|
+
|
102
164
|
.file-name {
|
103
|
-
|
165
|
+
float: left;
|
166
|
+
margin: 0 0 0 20px;
|
167
|
+
line-height: 50px;
|
104
168
|
font-weight: normal;
|
105
169
|
}
|
106
170
|
|
171
|
+
.file-committed-at {
|
172
|
+
float: left;
|
173
|
+
margin: 20px 0 0 28px;
|
174
|
+
font-size: 13px;
|
175
|
+
color: #666666;
|
176
|
+
}
|
177
|
+
|
178
|
+
.file-stats {
|
179
|
+
clear: both;
|
180
|
+
margin-left: 68px;
|
181
|
+
width: 300px;
|
182
|
+
}
|
183
|
+
|
184
|
+
.file-stat {
|
185
|
+
float: left;
|
186
|
+
margin: 3px;
|
187
|
+
width: 130px;
|
188
|
+
font-size: 12px;
|
189
|
+
white-space: nowrap;
|
190
|
+
}
|
191
|
+
|
107
192
|
.smells-toggle-button {
|
108
193
|
position: absolute;
|
109
194
|
right: 64px;
|
110
|
-
|
195
|
+
bottom: -17px;
|
111
196
|
border-color: silver;
|
112
197
|
background-color: #EEEBE9;
|
113
198
|
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require "erb"
|
2
1
|
require "rubycritic/report_generators/base"
|
3
2
|
require "rubycritic/report_generators/line"
|
4
3
|
|
@@ -12,7 +11,6 @@ module Rubycritic
|
|
12
11
|
def initialize(analysed_file)
|
13
12
|
@analysed_file = analysed_file
|
14
13
|
@pathname = @analysed_file.pathname
|
15
|
-
@smells = @analysed_file.smells
|
16
14
|
end
|
17
15
|
|
18
16
|
def file_directory
|
@@ -27,7 +25,7 @@ module Rubycritic
|
|
27
25
|
file_code = ""
|
28
26
|
File.readlines(@pathname).each.with_index(LINE_NUMBER_OFFSET) do |line_text, line_number|
|
29
27
|
location = Location.new(@pathname, line_number)
|
30
|
-
line_smells = @
|
28
|
+
line_smells = @analysed_file.smells_at_location(location)
|
31
29
|
file_code << Line.new(line_text, line_smells).render
|
32
30
|
end
|
33
31
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require "erb"
|
2
1
|
require "rubycritic/report_generators/base"
|
3
2
|
require "rubycritic/turbulence"
|
4
3
|
|
@@ -9,7 +8,7 @@ module Rubycritic
|
|
9
8
|
TEMPLATE = erb_template("overview.html.erb")
|
10
9
|
|
11
10
|
def initialize(analysed_files)
|
12
|
-
@turbulence_data = Turbulence.
|
11
|
+
@turbulence_data = Turbulence.data(analysed_files)
|
13
12
|
end
|
14
13
|
|
15
14
|
def file_name
|
@@ -1,6 +1,33 @@
|
|
1
|
-
<div class="file-header">
|
1
|
+
<div class="file-header group">
|
2
|
+
<span class="rating-<%= @analysed_file.rating.to_s.downcase %> circled-rating circle "><%= @analysed_file.rating %></span>
|
2
3
|
<h2 class="file-name"><%= @analysed_file.name %></h2>
|
3
4
|
|
5
|
+
<span class="file-committed-at">
|
6
|
+
<% if @analysed_file.committed_at %>
|
7
|
+
Updated <%= timeago_tag(@analysed_file.committed_at) %></span>
|
8
|
+
<% else %>
|
9
|
+
Never committed
|
10
|
+
<% end %>
|
11
|
+
</span>
|
12
|
+
|
13
|
+
<div class="file-stats group">
|
14
|
+
<div class="file-stat">
|
15
|
+
<%= @analysed_file.complexity %> complexity
|
16
|
+
</div>
|
17
|
+
<div class="file-stat">
|
18
|
+
<%= @analysed_file.complexity_per_method %> complexity per method
|
19
|
+
</div>
|
20
|
+
<div class="file-stat">
|
21
|
+
<%= @analysed_file.churn %> churn
|
22
|
+
</div>
|
23
|
+
<div class="file-stat">
|
24
|
+
<%= @analysed_file.methods_count %> methods
|
25
|
+
</div>
|
26
|
+
<div class="file-stat">
|
27
|
+
<%= @analysed_file.duplication %> duplication
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
|
4
31
|
<% if @analysed_file.has_smells? %>
|
5
32
|
<button id="js-toggle-smells" class="smells-toggle-button button">Toggle Smells</button>
|
6
33
|
<% end %>
|
@@ -4,7 +4,9 @@
|
|
4
4
|
<th class="first-cell">Name</th>
|
5
5
|
<th class="numeric-cell" title="Number of times a file has changed">Churn</th>
|
6
6
|
<th class="numeric-cell" title="Overall amount of code in a file">Complexity</th>
|
7
|
-
<th class="numeric-cell
|
7
|
+
<th class="numeric-cell" title="Amount of code that is similar to other code">Duplication</th>
|
8
|
+
<th class="numeric-cell">Smells</th>
|
9
|
+
<th class="centered-cell last-cell">Rating</th>
|
8
10
|
</tr>
|
9
11
|
</thead>
|
10
12
|
<tbody>
|
@@ -15,7 +17,9 @@
|
|
15
17
|
</td>
|
16
18
|
<td class="numeric-cell"><%= analysed_file.churn %></td>
|
17
19
|
<td class="numeric-cell"><%= analysed_file.complexity %></td>
|
18
|
-
<td class="numeric-cell
|
20
|
+
<td class="numeric-cell"><%= analysed_file.duplication %></td>
|
21
|
+
<td class="numeric-cell"><%= analysed_file.smells.length %></td>
|
22
|
+
<td class="centered-cell last-cell"><span class="rating-<%= analysed_file.rating.to_s.downcase %> circled-rating circle"><%= analysed_file.rating %></td>
|
19
23
|
</tr>
|
20
24
|
<% end %>
|
21
25
|
</tbody>
|
@@ -18,12 +18,13 @@
|
|
18
18
|
</nav>
|
19
19
|
</header>
|
20
20
|
<%= yield %>
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
<%= javascript_tag(:'jquery-2.1.0') %>
|
22
|
+
<%= javascript_tag(:'jquery.tablesorter-2.0') %>
|
23
|
+
<%= javascript_tag(:'jquery.floatThead-v1.2.7') %>
|
24
|
+
<%= javascript_tag(:'jquery.timeago-v1.4.1') %>
|
25
|
+
<%= javascript_tag(:'highcharts.src-4.0.1') %>
|
26
|
+
<%= javascript_tag(:'jquery.scrollTo-1.4.11') %>
|
27
|
+
<%= javascript_tag(:'prettify-4-Mar-2013') %>
|
28
|
+
<%= javascript_tag(:application) %>
|
28
29
|
</body>
|
29
30
|
</html>
|
@@ -3,8 +3,12 @@ require "pathname"
|
|
3
3
|
module Rubycritic
|
4
4
|
|
5
5
|
module ViewHelpers
|
6
|
-
def
|
7
|
-
|
6
|
+
def timeago_tag(time)
|
7
|
+
"<time class='js-timeago' datetime='#{time}'>#{time}</time>"
|
8
|
+
end
|
9
|
+
|
10
|
+
def javascript_tag(file)
|
11
|
+
"<script src='" + asset_path(File.join("javascripts", "#{file}.js")) + "'></script>"
|
8
12
|
end
|
9
13
|
|
10
14
|
def stylesheet_path(file)
|
@@ -8,15 +8,15 @@ module Rubycritic
|
|
8
8
|
module Reporter
|
9
9
|
|
10
10
|
class Main < Base
|
11
|
-
def initialize(analysed_files
|
11
|
+
def initialize(analysed_files)
|
12
12
|
@analysed_files = analysed_files
|
13
|
-
@smells = smells
|
13
|
+
@smells = analysed_files.flat_map(&:smells).uniq
|
14
14
|
end
|
15
15
|
|
16
16
|
def generate_report
|
17
17
|
create_directories_and_files(generators)
|
18
18
|
copy_assets_to_report_directory
|
19
|
-
|
19
|
+
report_location
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
@@ -42,6 +42,10 @@ module Rubycritic
|
|
42
42
|
Generator::CodeFile.new(analysed_file)
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
def report_location
|
47
|
+
overview_generator.file_href
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
end
|
@@ -1,18 +1,27 @@
|
|
1
1
|
require "rubycritic/reporters/base"
|
2
|
-
require "rubycritic/report_generators/
|
2
|
+
require "rubycritic/report_generators/current_code_file"
|
3
3
|
|
4
4
|
module Rubycritic
|
5
5
|
module Reporter
|
6
6
|
|
7
7
|
class Mini < Base
|
8
|
-
def initialize(
|
9
|
-
@analysed_file =
|
8
|
+
def initialize(analysed_files)
|
9
|
+
@analysed_file = analysed_files.first
|
10
10
|
end
|
11
11
|
|
12
12
|
def generate_report
|
13
|
-
file_generator = Generator::CodeFile.new(@analysed_file)
|
14
13
|
create_directories_and_files(file_generator)
|
15
14
|
copy_assets_to_report_directory
|
15
|
+
report_location
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def file_generator
|
21
|
+
@file_generator ||= Generator::CurrentCodeFile.new(@analysed_file)
|
22
|
+
end
|
23
|
+
|
24
|
+
def report_location
|
16
25
|
file_generator.file_href
|
17
26
|
end
|
18
27
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require "rubycritic/
|
2
|
-
require "rubycritic/
|
1
|
+
require "rubycritic/serializer"
|
2
|
+
require "rubycritic/files_initializer"
|
3
3
|
require "rubycritic/analysers_runner"
|
4
4
|
require "rubycritic/smells_status_setter"
|
5
5
|
|
@@ -8,28 +8,31 @@ module Rubycritic
|
|
8
8
|
class RevisionComparator
|
9
9
|
SNAPSHOTS_DIR_NAME = "snapshots"
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
@
|
11
|
+
def initialize(analysed_files, source_control_system)
|
12
|
+
@analysed_files_now = analysed_files
|
13
13
|
@source_control_system = source_control_system
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
SmellsStatusSetter.
|
16
|
+
def set_statuses
|
17
|
+
SmellsStatusSetter.set(
|
18
|
+
analysed_files_before.flat_map(&:smells),
|
19
|
+
@analysed_files_now.flat_map(&:smells)
|
20
|
+
)
|
18
21
|
end
|
19
22
|
|
20
23
|
private
|
21
24
|
|
22
|
-
def
|
23
|
-
serializer =
|
25
|
+
def analysed_files_before
|
26
|
+
serializer = Serializer.new(revision_file)
|
24
27
|
if File.file?(revision_file)
|
25
28
|
serializer.load
|
26
29
|
else
|
27
|
-
|
30
|
+
analysed_files = FilesInitializer.init(["."])
|
28
31
|
@source_control_system.travel_to_head do
|
29
|
-
|
32
|
+
AnalysersRunner.new(analysed_files, @source_control_system).run
|
30
33
|
end
|
31
|
-
serializer.dump(
|
32
|
-
|
34
|
+
serializer.dump(analysed_files)
|
35
|
+
analysed_files
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
@@ -40,10 +43,6 @@ module Rubycritic
|
|
40
43
|
@source_control_system.head_reference
|
41
44
|
)
|
42
45
|
end
|
43
|
-
|
44
|
-
def paths_of_tracked_files
|
45
|
-
SourceLocator.new(["."]).paths
|
46
|
-
end
|
47
46
|
end
|
48
47
|
|
49
48
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
module Rubycritic
|
4
|
+
|
5
|
+
class Serializer
|
6
|
+
def initialize(file)
|
7
|
+
@file = file
|
8
|
+
end
|
9
|
+
|
10
|
+
def load
|
11
|
+
Marshal.load(File.binread(@file))
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump(content)
|
15
|
+
create_file_directory
|
16
|
+
File.open(@file, "w+") do |file|
|
17
|
+
Marshal.dump(content, file)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def create_file_directory
|
24
|
+
FileUtils.mkdir_p(file_directory)
|
25
|
+
end
|
26
|
+
|
27
|
+
def file_directory
|
28
|
+
File.dirname(@file)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|