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
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
|
[](http://badge.fury.io/rb/rubycritic)
|
5
5
|
[](https://travis-ci.org/whitesmith/rubycritic)
|
6
|
-
[](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
|
-

|
20
20
|
|
21
21
|
3. An index of the smells detected:
|
22
22
|
|
23
|
-

|
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
|
-

|
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
|
});
|