rubycritic 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68c58782f25f2ad071d05ae5060034e4f2b77832
|
4
|
+
data.tar.gz: 61ae75fea93cde03f7e9ab378e363f345eb8f184
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15a35a6440ba6536d6989451ec60d0d8037303e93c47049aaa73c05846ea65f22bad0517084510811ed9cfa794acf86f0f5dc512cee37320841cff402fb381ba
|
7
|
+
data.tar.gz: 493ebc3d9f648e39ca5869d397dfcd4af1bc5facb5c1a669eda9a358bce67f85c21b93c7781ae8dbce3a9c4a34bdf98b8df788c08964e5214affb957a081edd6
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@ RubyCritic
|
|
3
3
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/rubycritic.svg)](http://badge.fury.io/rb/rubycritic)
|
5
5
|
[![Build Status](https://travis-ci.org/whitesmith/rubycritic.svg?branch=master)](https://travis-ci.org/whitesmith/rubycritic)
|
6
|
-
[![Code Climate](
|
6
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/whitesmith/rubycritic.svg)](https://codeclimate.com/github/whitesmith/rubycritic)
|
7
7
|
|
8
8
|
RubyCritic is a gem that wraps around static analysis gems such as [Reek][1]
|
9
9
|
and [Flay][2] to provide a quality report of your Ruby code.
|
@@ -16,11 +16,11 @@ This gem provides features such as:
|
|
16
16
|
|
17
17
|
2. An index of the project files with their respective number of smells:
|
18
18
|
|
19
|
-
![RubyCritic code index screenshot](http://i.imgur.com/
|
19
|
+
![RubyCritic code index screenshot](http://i.imgur.com/0ETNrX7.png)
|
20
20
|
|
21
21
|
3. An index of the smells detected:
|
22
22
|
|
23
|
-
![RubyCritic smells index screenshot](http://i.imgur.com/
|
23
|
+
![RubyCritic smells index screenshot](http://i.imgur.com/5CpPt9v.png)
|
24
24
|
|
25
25
|
4. Finally, when analysing code like the following:
|
26
26
|
|
@@ -40,7 +40,7 @@ This gem provides features such as:
|
|
40
40
|
|
41
41
|
Into something like this:
|
42
42
|
|
43
|
-
![RubyCritic file code screenshot](http://i.imgur.com/
|
43
|
+
![RubyCritic file code screenshot](http://i.imgur.com/KLVrhMm.png)
|
44
44
|
|
45
45
|
Installation
|
46
46
|
------------
|
@@ -80,6 +80,18 @@ Alternatively you can pass `rubycritic` a list of files and directories to check
|
|
80
80
|
$ rubycritic app lib/foo.rb
|
81
81
|
```
|
82
82
|
|
83
|
+
By default, RubyCritic generates its report in `tmp/rubycritic`. You can customize the output directory using the `path` option. You can use relative paths:
|
84
|
+
|
85
|
+
```bash
|
86
|
+
rubycritic --path tmp/custom_dir # outputs to tmp/custom_dir
|
87
|
+
```
|
88
|
+
|
89
|
+
Or full paths:
|
90
|
+
|
91
|
+
```bash
|
92
|
+
rubycritic --path $HOME/tmp/custom_dir # outputs to $HOME/tmp/custom_dir
|
93
|
+
```
|
94
|
+
|
83
95
|
For a full list of the command-line options run:
|
84
96
|
|
85
97
|
```bash
|
data/bin/rubycritic
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
+
require "rubycritic/analysers/flog"
|
2
|
+
|
1
3
|
module Rubycritic
|
2
4
|
module ComplexityAdapter
|
3
5
|
|
4
6
|
class Flog
|
5
|
-
def initialize(
|
6
|
-
@flog =
|
7
|
-
@
|
7
|
+
def initialize(analysed_files)
|
8
|
+
@flog = Analyser::Flog.new
|
9
|
+
@analysed_files = analysed_files
|
8
10
|
end
|
9
11
|
|
10
12
|
def complexity
|
11
|
-
@
|
13
|
+
@analysed_files.each do |analysed_file|
|
12
14
|
@flog.reset
|
13
|
-
@flog.flog(path)
|
14
|
-
@flog.total_score.round
|
15
|
+
@flog.flog(analysed_file.path)
|
16
|
+
analysed_file.complexity = @flog.total_score.round
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -5,25 +5,43 @@ module Rubycritic
|
|
5
5
|
module SmellAdapter
|
6
6
|
|
7
7
|
class Flay
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(analysed_files)
|
9
|
+
@analysed_files = paths_to_analysed_files(analysed_files)
|
10
|
+
@flay = Analyser::Flay.new(@analysed_files.keys)
|
10
11
|
end
|
11
12
|
|
12
13
|
def smells
|
13
|
-
@flay.hashes.
|
14
|
-
create_smell(structural_hash, nodes)
|
14
|
+
@flay.hashes.each do |structural_hash, nodes|
|
15
|
+
smell = create_smell(structural_hash, nodes)
|
16
|
+
nodes.map(&:file).uniq.each do |file|
|
17
|
+
@analysed_files[file].smells << smell
|
18
|
+
end
|
19
|
+
|
20
|
+
nodes.each do |node|
|
21
|
+
@analysed_files[node.file].duplication += node.mass
|
22
|
+
end
|
15
23
|
end
|
16
24
|
end
|
17
25
|
|
18
26
|
private
|
19
27
|
|
28
|
+
def paths_to_analysed_files(analysed_files)
|
29
|
+
paths = {}
|
30
|
+
analysed_files.each do |analysed_file|
|
31
|
+
paths[analysed_file.path] = analysed_file
|
32
|
+
end
|
33
|
+
paths
|
34
|
+
end
|
35
|
+
|
20
36
|
def create_smell(structural_hash, nodes)
|
37
|
+
mass = @flay.masses[structural_hash]
|
21
38
|
Smell.new(
|
22
39
|
:locations => smell_locations(nodes),
|
23
|
-
:context =>
|
40
|
+
:context => similarity(structural_hash),
|
24
41
|
:message => "found in #{nodes.size} nodes",
|
25
|
-
:score =>
|
26
|
-
:type => "DuplicateCode"
|
42
|
+
:score => mass,
|
43
|
+
:type => "DuplicateCode",
|
44
|
+
:cost => cost(mass)
|
27
45
|
)
|
28
46
|
end
|
29
47
|
|
@@ -35,11 +53,15 @@ module Rubycritic
|
|
35
53
|
|
36
54
|
def similarity(structural_hash)
|
37
55
|
if @flay.identical[structural_hash]
|
38
|
-
"Identical"
|
56
|
+
"Identical code"
|
39
57
|
else
|
40
|
-
"Similar"
|
58
|
+
"Similar code"
|
41
59
|
end
|
42
60
|
end
|
61
|
+
|
62
|
+
def cost(mass)
|
63
|
+
mass / 25
|
64
|
+
end
|
43
65
|
end
|
44
66
|
|
45
67
|
end
|
@@ -8,29 +8,38 @@ module Rubycritic
|
|
8
8
|
HIGH_COMPLEXITY_SCORE_THRESHOLD = 25
|
9
9
|
VERY_HIGH_COMPLEXITY_SCORE_THRESHOLD = 60
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
@flog =
|
13
|
-
@
|
11
|
+
def initialize(analysed_files)
|
12
|
+
@flog = Analyser::Flog.new
|
13
|
+
@analysed_files = analysed_files
|
14
14
|
end
|
15
15
|
|
16
16
|
def smells
|
17
|
-
|
18
|
-
|
19
|
-
score = original_score.round
|
20
|
-
smells << create_smell(class_method, score) if score >= HIGH_COMPLEXITY_SCORE_THRESHOLD
|
17
|
+
@analysed_files.each do |analysed_file|
|
18
|
+
add_smells_to(analysed_file)
|
21
19
|
end
|
22
|
-
smells
|
23
20
|
end
|
24
21
|
|
25
22
|
private
|
26
23
|
|
24
|
+
def add_smells_to(analysed_file)
|
25
|
+
@flog.reset
|
26
|
+
@flog.flog(analysed_file.path)
|
27
|
+
@flog.each_by_score do |class_method, original_score|
|
28
|
+
score = original_score.round
|
29
|
+
if score >= HIGH_COMPLEXITY_SCORE_THRESHOLD
|
30
|
+
analysed_file.smells << create_smell(class_method, score)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
27
35
|
def create_smell(context, score)
|
28
36
|
Smell.new(
|
29
37
|
:locations => smell_locations(context),
|
30
38
|
:context => context,
|
31
39
|
:message => "has a flog score of #{score}",
|
32
40
|
:score => score,
|
33
|
-
:type => type(score)
|
41
|
+
:type => type(score),
|
42
|
+
:cost => 0
|
34
43
|
)
|
35
44
|
end
|
36
45
|
|
@@ -5,24 +5,31 @@ module Rubycritic
|
|
5
5
|
module SmellAdapter
|
6
6
|
|
7
7
|
class Reek
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(analysed_files)
|
9
|
+
@analysed_files = analysed_files
|
10
10
|
end
|
11
11
|
|
12
12
|
def smells
|
13
|
-
@
|
14
|
-
|
13
|
+
@analysed_files.each do |analysed_file|
|
14
|
+
add_smells_to(analysed_file)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
+
def add_smells_to(analysed_file)
|
21
|
+
Analyser::Reek.new(analysed_file.path).smells.each do |smell|
|
22
|
+
analysed_file.smells << create_smell(smell)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
20
26
|
def create_smell(smell)
|
21
27
|
Smell.new(
|
22
28
|
:locations => smell_locations(smell.source, smell.lines),
|
23
29
|
:context => smell.context,
|
24
30
|
:message => smell.message,
|
25
|
-
:type => smell.subclass
|
31
|
+
:type => smell.subclass,
|
32
|
+
:cost => 0
|
26
33
|
)
|
27
34
|
end
|
28
35
|
|
@@ -2,13 +2,16 @@ module Rubycritic
|
|
2
2
|
module Analyser
|
3
3
|
|
4
4
|
class Churn
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(analysed_files, source_control_system)
|
6
|
+
@analysed_files = analysed_files
|
7
7
|
@source_control_system = source_control_system
|
8
8
|
end
|
9
9
|
|
10
10
|
def churn
|
11
|
-
@
|
11
|
+
@analysed_files.each do |analysed_file|
|
12
|
+
analysed_file.churn = @source_control_system.revisions_count(analysed_file.path)
|
13
|
+
analysed_file.committed_at = @source_control_system.date_of_last_commit(analysed_file.path)
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "code_analyzer"
|
2
|
+
|
3
|
+
module Rubycritic
|
4
|
+
module Analyser
|
5
|
+
|
6
|
+
class Stats
|
7
|
+
def initialize(analysed_files)
|
8
|
+
@analysed_files = analysed_files
|
9
|
+
end
|
10
|
+
|
11
|
+
def stats
|
12
|
+
@analysed_files.each do |analysed_file|
|
13
|
+
analysed_file.methods_count = methods_count(analysed_file.path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def methods_count(path)
|
20
|
+
content = File.read(path)
|
21
|
+
node = parse_content(content)
|
22
|
+
node.grep_nodes_count(sexp_type: [:def, :defs])
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_content(content)
|
26
|
+
Sexp.from_array(Ripper::SexpBuilder.new(content).parse)[1]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -1,33 +1,27 @@
|
|
1
|
-
require "rubycritic/active_support/methods"
|
2
1
|
require "rubycritic/adapters/smell/flay"
|
3
2
|
require "rubycritic/adapters/smell/flog"
|
4
3
|
require "rubycritic/adapters/smell/reek"
|
4
|
+
require "rubycritic/adapters/complexity/flog"
|
5
|
+
require "rubycritic/analysers/churn"
|
6
|
+
require "rubycritic/analysers/stats"
|
5
7
|
|
6
8
|
module Rubycritic
|
7
9
|
|
8
10
|
class AnalysersRunner
|
9
|
-
|
11
|
+
SMELL_ANALYSERS = [SmellAdapter::Flay, SmellAdapter::Flog, SmellAdapter::Reek]
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@paths = paths
|
15
|
-
end
|
16
|
-
|
17
|
-
def smells
|
18
|
-
aggregate_smells(smell_adapters)
|
13
|
+
def initialize(analysed_files, source_control_system)
|
14
|
+
@analysed_files = analysed_files
|
15
|
+
@source_control_system = source_control_system
|
19
16
|
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
ANALYSERS.map do |analyser_name|
|
25
|
-
constantize("Rubycritic::SmellAdapter::#{analyser_name}").new(@paths)
|
18
|
+
def run
|
19
|
+
SMELL_ANALYSERS.map do |analyser|
|
20
|
+
analyser.new(@analysed_files).smells
|
26
21
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
smell_adapters.flat_map(&:smells)
|
22
|
+
ComplexityAdapter::Flog.new(@analysed_files).complexity
|
23
|
+
Analyser::Churn.new(@analysed_files, @source_control_system).churn
|
24
|
+
Analyser::Stats.new(@analysed_files).stats
|
31
25
|
end
|
32
26
|
end
|
33
27
|
|
data/lib/rubycritic/cli.rb
CHANGED
@@ -1,30 +1,46 @@
|
|
1
1
|
require "optparse"
|
2
2
|
require "rubycritic"
|
3
|
-
require "rubycritic/
|
3
|
+
require "rubycritic/reporters/main"
|
4
4
|
|
5
5
|
module Rubycritic
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
class Cli
|
8
|
+
STATUS_SUCCESS = 0
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
def initialize(argv)
|
11
|
+
@argv = argv
|
12
|
+
@argv << "." if @argv.empty?
|
13
|
+
@main_command = true
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
exit 0
|
18
|
-
end
|
16
|
+
def execute
|
17
|
+
OptionParser.new do |opts|
|
18
|
+
opts.banner = "Usage: rubycritic [options] [paths]"
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
opts.on("-p", "--path [PATH]", "Set path where report will be saved (tmp/rubycritic by default)") do |path|
|
21
|
+
::Rubycritic.configuration.root = path
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on_tail("-v", "--version", "Show gem's version") do
|
25
|
+
require "rubycritic/version"
|
26
|
+
puts "RubyCritic #{VERSION}"
|
27
|
+
@main_command = false
|
28
|
+
end
|
25
29
|
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
31
|
+
puts opts
|
32
|
+
@main_command = false
|
33
|
+
end
|
34
|
+
end.parse!(@argv)
|
35
|
+
|
36
|
+
if @main_command
|
37
|
+
analysed_files = Orchestrator.new.critique(@argv)
|
38
|
+
report_location = Reporter::Main.new(analysed_files).generate_report
|
39
|
+
puts "New critique at #{report_location}"
|
40
|
+
end
|
41
|
+
|
42
|
+
STATUS_SUCCESS
|
43
|
+
end
|
44
|
+
end
|
29
45
|
|
30
46
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
1
3
|
module Rubycritic
|
2
4
|
def self.configuration
|
3
5
|
@configuration ||= Configuration.new
|
@@ -11,7 +13,11 @@ module Rubycritic
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def root=(path)
|
14
|
-
@root =
|
16
|
+
@root = if Pathname(path).relative?
|
17
|
+
File.expand_path(path)
|
18
|
+
else
|
19
|
+
path
|
20
|
+
end
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "virtus"
|
2
|
+
require "rubycritic/core/rating"
|
2
3
|
|
3
4
|
module Rubycritic
|
4
5
|
|
@@ -8,15 +9,40 @@ module Rubycritic
|
|
8
9
|
attribute :pathname
|
9
10
|
attribute :smells
|
10
11
|
attribute :churn
|
12
|
+
attribute :committed_at
|
11
13
|
attribute :complexity
|
14
|
+
attribute :duplication
|
15
|
+
attribute :methods_count
|
12
16
|
|
13
17
|
def name
|
14
|
-
pathname.basename.sub_ext("").to_s
|
18
|
+
@name ||= pathname.basename.sub_ext("").to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def path
|
22
|
+
@path ||= pathname.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def cost
|
26
|
+
@cost ||= smells.map(&:cost).inject(0, :+) + (complexity / 25)
|
27
|
+
end
|
28
|
+
|
29
|
+
def rating
|
30
|
+
@rating ||= Rating.from_cost(cost)
|
31
|
+
end
|
32
|
+
|
33
|
+
def complexity_per_method
|
34
|
+
complexity.fdiv(methods_count).round(1)
|
35
|
+
rescue ZeroDivisionError
|
36
|
+
"N/A"
|
15
37
|
end
|
16
38
|
|
17
39
|
def has_smells?
|
18
40
|
!smells.empty?
|
19
41
|
end
|
42
|
+
|
43
|
+
def smells_at_location(location)
|
44
|
+
smells.select { |smell| smell.at_location?(location) }
|
45
|
+
end
|
20
46
|
end
|
21
47
|
|
22
48
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Rubycritic
|
2
|
+
|
3
|
+
class Rating
|
4
|
+
def self.from_cost(cost)
|
5
|
+
if cost <= 2 then new("A")
|
6
|
+
elsif cost <= 4 then new("B")
|
7
|
+
elsif cost <= 8 then new("C")
|
8
|
+
elsif cost <= 16 then new("D")
|
9
|
+
else new("F")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(letter)
|
14
|
+
@letter = letter
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@letter
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -7,15 +7,12 @@ module Rubycritic
|
|
7
7
|
include Virtus.model
|
8
8
|
|
9
9
|
attribute :context
|
10
|
+
attribute :cost
|
10
11
|
attribute :locations
|
11
12
|
attribute :message
|
12
13
|
attribute :score
|
13
|
-
attribute :type
|
14
14
|
attribute :status
|
15
|
-
|
16
|
-
def at_pathname?(other_pathname)
|
17
|
-
pathnames.any? { |pathname| pathname == other_pathname }
|
18
|
-
end
|
15
|
+
attribute :type
|
19
16
|
|
20
17
|
def at_location?(other_location)
|
21
18
|
locations.any? { |location| location == other_location }
|
@@ -26,7 +23,7 @@ module Rubycritic
|
|
26
23
|
end
|
27
24
|
|
28
25
|
def ==(other)
|
29
|
-
|
26
|
+
state == other.state
|
30
27
|
end
|
31
28
|
alias_method :eql?, :==
|
32
29
|
|
@@ -43,12 +40,6 @@ module Rubycritic
|
|
43
40
|
def state
|
44
41
|
[@context, @message, @score, @type]
|
45
42
|
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def pathnames
|
50
|
-
@pathnames ||= locations.map(&:pathname).uniq
|
51
|
-
end
|
52
43
|
end
|
53
44
|
|
54
45
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rubycritic/source_locator"
|
2
|
+
require "rubycritic/core/analysed_file"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
module FilesInitializer
|
7
|
+
def self.init(paths)
|
8
|
+
source = SourceLocator.new(paths)
|
9
|
+
source.pathnames.map do |pathname|
|
10
|
+
AnalysedFile.new(:pathname => pathname, :smells => [], :duplication => 0)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "rubycritic/source_control_systems/base"
|
2
|
+
require "rubycritic/files_initializer"
|
3
|
+
require "rubycritic/analysers_runner"
|
4
|
+
require "rubycritic/revision_comparator"
|
5
|
+
|
6
|
+
module Rubycritic
|
7
|
+
|
8
|
+
class Orchestrator
|
9
|
+
def initialize
|
10
|
+
@source_control_system = SourceControlSystem::Base.create
|
11
|
+
end
|
12
|
+
|
13
|
+
def critique(paths)
|
14
|
+
analysed_files = FilesInitializer.init(paths)
|
15
|
+
AnalysersRunner.new(analysed_files, @source_control_system).run
|
16
|
+
if @source_control_system.has_revision?
|
17
|
+
RevisionComparator.new(analysed_files, @source_control_system).set_statuses
|
18
|
+
end
|
19
|
+
analysed_files
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -8,8 +8,8 @@ function emphasizeLineFromFragment() {
|
|
8
8
|
|
9
9
|
$(".js-file-code").on("click", ".js-smell-location", emphasizeLineFromHref);
|
10
10
|
|
11
|
-
function emphasizeLineFromHref() {
|
12
|
-
if (hrefTargetIsOnCurrentPage(this)) {
|
11
|
+
function emphasizeLineFromHref(event) {
|
12
|
+
if (hrefTargetIsOnCurrentPage(this) && !event.ctrlKey) {
|
13
13
|
$(".js-file-code li").removeClass("highlight");
|
14
14
|
var lineId = "#" + this.href.split("#")[1];
|
15
15
|
emphasizeLine(lineId);
|
@@ -52,6 +52,8 @@ $("#js-index-table")
|
|
52
52
|
})
|
53
53
|
.floatThead(); // Make table headers stick to the top when scrolling
|
54
54
|
|
55
|
+
$(".js-timeago").timeago();
|
56
|
+
|
55
57
|
$("#js-chart-container").highcharts({
|
56
58
|
chart: {
|
57
59
|
type: "scatter",
|
@@ -97,6 +99,6 @@ $("#js-chart-container").highcharts({
|
|
97
99
|
series: [{
|
98
100
|
showInLegend: false,
|
99
101
|
color: "steelblue",
|
100
|
-
data:
|
102
|
+
data: turbulenceData
|
101
103
|
}]
|
102
104
|
});
|