rubycritic 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +593 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +7 -0
- data/CONTRIBUTING.md +17 -15
- data/README.md +15 -4
- data/Rakefile +9 -6
- data/bin/rubycritic +2 -2
- data/lib/rubycritic.rb +21 -1
- data/lib/rubycritic/analysers/churn.rb +4 -2
- data/lib/rubycritic/analysers/helpers/ast_node.rb +4 -8
- data/lib/rubycritic/analysers/helpers/methods_counter.rb +2 -5
- data/lib/rubycritic/analysers/helpers/modules_locator.rb +2 -5
- data/lib/rubycritic/analysers/helpers/parser.rb +12 -0
- data/lib/rubycritic/analysers/helpers/reek.rb +6 -2
- data/lib/rubycritic/analysers/smells/reek.rb +1 -1
- data/lib/rubycritic/analysers_runner.rb +13 -7
- data/lib/rubycritic/cli/application.rb +24 -0
- data/lib/rubycritic/cli/options.rb +57 -0
- data/lib/rubycritic/commands/ci.rb +28 -0
- data/lib/rubycritic/commands/default.rb +30 -0
- data/lib/rubycritic/commands/help.rb +13 -0
- data/lib/rubycritic/commands/version.rb +11 -0
- data/lib/rubycritic/configuration.rb +19 -14
- data/lib/rubycritic/core/analysed_module.rb +1 -1
- data/lib/rubycritic/core/smell.rb +1 -1
- data/lib/rubycritic/report_generators/base.rb +1 -1
- data/lib/rubycritic/report_generators/line.rb +1 -1
- data/lib/rubycritic/report_generators/smells_index.rb +1 -0
- data/lib/rubycritic/report_generators/templates/code_file.html.erb +1 -1
- data/lib/rubycritic/report_generators/templates/smells_index.html.erb +6 -2
- data/lib/rubycritic/report_generators/templates/smelly_line.html.erb +1 -1
- data/lib/rubycritic/report_generators/view_helpers.rb +4 -4
- data/lib/rubycritic/reporters/base.rb +1 -1
- data/lib/rubycritic/revision_comparator.rb +14 -14
- data/lib/rubycritic/source_control_systems/base.rb +9 -32
- data/lib/rubycritic/source_control_systems/double.rb +6 -7
- data/lib/rubycritic/source_control_systems/git.rb +10 -16
- data/lib/rubycritic/source_control_systems/mercurial.rb +29 -0
- data/lib/rubycritic/source_locator.rb +4 -5
- data/lib/rubycritic/version.rb +1 -1
- data/rubycritic.gemspec +4 -3
- data/test/lib/rubycritic/analysers/churn_test.rb +5 -5
- data/test/lib/rubycritic/analysers/smells/flay_test.rb +1 -1
- data/test/lib/rubycritic/configuration_test.rb +8 -7
- data/test/lib/rubycritic/core/analysed_module_test.rb +2 -2
- data/test/lib/rubycritic/core/smell_test.rb +2 -2
- data/test/lib/rubycritic/source_control_systems/{source_control_system_test.rb → base_test.rb} +1 -1
- data/test/lib/rubycritic/source_control_systems/double_test.rb +11 -0
- data/test/lib/rubycritic/source_control_systems/git_test.rb +13 -0
- data/test/lib/rubycritic/source_control_systems/interfaces/basic.rb +7 -0
- data/test/lib/rubycritic/source_control_systems/interfaces/time_travel.rb +7 -0
- data/test/lib/rubycritic/source_control_systems/mercurial_test.rb +11 -0
- data/test/lib/rubycritic/source_locator_test.rb +8 -2
- data/test/test_helper.rb +29 -0
- metadata +49 -13
- data/lib/rubycritic/cli.rb +0 -46
- data/lib/rubycritic/modules_initializer.rb +0 -14
- data/lib/rubycritic/orchestrator.rb +0 -23
@@ -0,0 +1,30 @@
|
|
1
|
+
require "rubycritic/source_control_systems/base"
|
2
|
+
require "rubycritic/analysers_runner"
|
3
|
+
require "rubycritic/revision_comparator"
|
4
|
+
require "rubycritic/reporters/main"
|
5
|
+
|
6
|
+
module Rubycritic
|
7
|
+
module Command
|
8
|
+
class Default
|
9
|
+
def initialize(options)
|
10
|
+
@paths = options[:paths]
|
11
|
+
Config.source_control_system = SourceControlSystem::Base.create
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
critique(@paths)
|
16
|
+
report
|
17
|
+
end
|
18
|
+
|
19
|
+
def critique(paths)
|
20
|
+
@analysed_modules = AnalysersRunner.new(paths).run
|
21
|
+
RevisionComparator.new(paths).set_statuses(@analysed_modules)
|
22
|
+
end
|
23
|
+
|
24
|
+
def report
|
25
|
+
report_location = Reporter::Main.new(@analysed_modules).generate_report
|
26
|
+
puts "New critique at #{report_location}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,24 +1,29 @@
|
|
1
|
-
require "pathname"
|
2
|
-
|
3
1
|
module Rubycritic
|
4
|
-
def self.configuration
|
5
|
-
@configuration ||= Configuration.new
|
6
|
-
end
|
7
|
-
|
8
2
|
class Configuration
|
9
3
|
attr_reader :root
|
4
|
+
attr_accessor :source_control_system, :mode
|
10
5
|
|
11
|
-
def
|
12
|
-
self.
|
6
|
+
def set(options)
|
7
|
+
self.mode = options[:mode] || :default
|
8
|
+
self.root = options[:root] || "tmp/rubycritic"
|
13
9
|
end
|
14
10
|
|
15
11
|
def root=(path)
|
16
|
-
@root =
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
12
|
+
@root = File.expand_path(path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Config
|
17
|
+
def self.configuration
|
18
|
+
@configuration ||= Configuration.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.set(options = {})
|
22
|
+
configuration.set(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.method_missing(method, *args, &block)
|
26
|
+
configuration.public_send(method, *args, &block)
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -3,7 +3,9 @@
|
|
3
3
|
<tr>
|
4
4
|
<th class="first-cell">Smell</th>
|
5
5
|
<th>Locations</th>
|
6
|
-
|
6
|
+
<% if @show_status %>
|
7
|
+
<th class="centered-cell last-cell" title="Code smells introduced recently are marked as new. There's still time before they are committed!">Status</th>
|
8
|
+
<% end %>
|
7
9
|
</tr>
|
8
10
|
</thead>
|
9
11
|
<tbody>
|
@@ -15,7 +17,9 @@
|
|
15
17
|
<a href="<%= smell_location_path(location) %>"><%= @analysed_module_names[location.pathname] %></a>
|
16
18
|
<% end %>
|
17
19
|
</td>
|
18
|
-
|
20
|
+
<% if @show_status %>
|
21
|
+
<td class="centered-cell last-cell"><span class="status-<%= smell.status %> circled-text circle"><%= smell.status %></span></td>
|
22
|
+
<% end %>
|
19
23
|
</tr>
|
20
24
|
<% end %>
|
21
25
|
</tbody>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<% @smells.each do |smell| %>
|
5
5
|
<li class="smell <%= smell.status %>">
|
6
6
|
<span class="description"><%= smell %>
|
7
|
-
<% if smell.
|
7
|
+
<% if smell.multiple_locations? %>
|
8
8
|
<% smell.locations.each_with_index do |location, index| %>
|
9
9
|
<a href="<%= smell_location_path(location) %>" class="js-smell-location"><%= index %></a>
|
10
10
|
<% end %>
|
@@ -14,11 +14,11 @@ module Rubycritic
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def asset_path(file)
|
17
|
-
relative_path(
|
17
|
+
relative_path("assets/#{file}")
|
18
18
|
end
|
19
19
|
|
20
20
|
def file_path(file)
|
21
|
-
relative_path(
|
21
|
+
relative_path(file)
|
22
22
|
end
|
23
23
|
|
24
24
|
def smell_location_path(location)
|
@@ -27,8 +27,8 @@ module Rubycritic
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def relative_path(
|
31
|
-
|
30
|
+
def relative_path(file)
|
31
|
+
(root_directory + file).relative_path_from(file_directory)
|
32
32
|
end
|
33
33
|
|
34
34
|
def file_directory
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require "rubycritic/serializer"
|
2
|
-
require "rubycritic/modules_initializer"
|
3
2
|
require "rubycritic/analysers_runner"
|
4
3
|
require "rubycritic/smells_status_setter"
|
5
4
|
require "rubycritic/version"
|
@@ -10,17 +9,18 @@ module Rubycritic
|
|
10
9
|
class RevisionComparator
|
11
10
|
SNAPSHOTS_DIR_NAME = "snapshots"
|
12
11
|
|
13
|
-
def initialize(
|
14
|
-
@analysed_modules_now = analysed_modules
|
15
|
-
@source_control_system = source_control_system
|
12
|
+
def initialize(paths)
|
16
13
|
@paths = paths
|
17
14
|
end
|
18
15
|
|
19
|
-
def set_statuses
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
def set_statuses(analysed_modules_now)
|
17
|
+
if Config.source_control_system.revision?
|
18
|
+
SmellsStatusSetter.set(
|
19
|
+
analysed_modules_before.flat_map(&:smells),
|
20
|
+
analysed_modules_now.flat_map(&:smells)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
analysed_modules_now
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
@@ -30,9 +30,9 @@ module Rubycritic
|
|
30
30
|
if File.file?(revision_file)
|
31
31
|
serializer.load
|
32
32
|
else
|
33
|
-
analysed_modules =
|
34
|
-
|
35
|
-
AnalysersRunner.new(
|
33
|
+
analysed_modules = nil
|
34
|
+
Config.source_control_system.travel_to_head do
|
35
|
+
analysed_modules = AnalysersRunner.new(@paths).run
|
36
36
|
end
|
37
37
|
serializer.dump(analysed_modules)
|
38
38
|
analysed_modules
|
@@ -41,11 +41,11 @@ module Rubycritic
|
|
41
41
|
|
42
42
|
def revision_file
|
43
43
|
@revision_file ||= File.join(
|
44
|
-
|
44
|
+
Config.root,
|
45
45
|
SNAPSHOTS_DIR_NAME,
|
46
46
|
VERSION,
|
47
47
|
Digest::MD5.hexdigest(Marshal.dump(@paths)),
|
48
|
-
|
48
|
+
Config.source_control_system.head_reference
|
49
49
|
)
|
50
50
|
end
|
51
51
|
end
|
@@ -10,46 +10,22 @@ module Rubycritic
|
|
10
10
|
@@systems << self
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.systems
|
14
|
+
@@systems
|
15
|
+
end
|
16
|
+
|
13
17
|
def self.create
|
14
|
-
supported_system = systems.
|
18
|
+
supported_system = systems.find(&:supported?)
|
15
19
|
if supported_system
|
16
20
|
supported_system.new
|
17
21
|
else
|
18
|
-
puts "
|
22
|
+
puts "RubyCritic can provide more feedback if you use a #{connected_system_names} repository."
|
19
23
|
Double.new
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
|
-
def self.
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.system_names
|
28
|
-
systems.join(", ")
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.supported?
|
32
|
-
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
33
|
-
end
|
34
|
-
|
35
|
-
def has_revision?
|
36
|
-
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
37
|
-
end
|
38
|
-
|
39
|
-
def head_reference
|
40
|
-
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
41
|
-
end
|
42
|
-
|
43
|
-
def travel_to_head
|
44
|
-
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
45
|
-
end
|
46
|
-
|
47
|
-
def revisions_count(path)
|
48
|
-
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
49
|
-
end
|
50
|
-
|
51
|
-
def date_of_last_commit(path)
|
52
|
-
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
27
|
+
def self.connected_system_names
|
28
|
+
"#{systems[0...-1].join(', ')} or #{systems[-1]}"
|
53
29
|
end
|
54
30
|
end
|
55
31
|
|
@@ -58,3 +34,4 @@ end
|
|
58
34
|
|
59
35
|
require "rubycritic/source_control_systems/double"
|
60
36
|
require "rubycritic/source_control_systems/git"
|
37
|
+
require "rubycritic/source_control_systems/mercurial"
|
@@ -1,18 +1,17 @@
|
|
1
1
|
module Rubycritic
|
2
2
|
module SourceControlSystem
|
3
|
-
|
4
3
|
class Double < Base
|
5
|
-
def
|
6
|
-
false
|
7
|
-
end
|
8
|
-
|
9
|
-
def revisions_count(path)
|
4
|
+
def revisions_count(_)
|
10
5
|
"N/A"
|
11
6
|
end
|
12
7
|
|
13
|
-
def date_of_last_commit(
|
8
|
+
def date_of_last_commit(_)
|
14
9
|
nil
|
15
10
|
end
|
11
|
+
|
12
|
+
def revision?
|
13
|
+
false
|
14
|
+
end
|
16
15
|
end
|
17
16
|
|
18
17
|
end
|
@@ -12,7 +12,15 @@ module Rubycritic
|
|
12
12
|
"Git"
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def revisions_count(path)
|
16
|
+
`git log --follow --format=%h #{path.shellescape}`.count("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
def date_of_last_commit(path)
|
20
|
+
`git log -1 --date=iso --format=%ad #{path.shellescape}`.chomp!
|
21
|
+
end
|
22
|
+
|
23
|
+
def revision?
|
16
24
|
head_reference && $?.success?
|
17
25
|
end
|
18
26
|
|
@@ -27,31 +35,17 @@ module Rubycritic
|
|
27
35
|
travel_to_original_state if stash_successful
|
28
36
|
end
|
29
37
|
|
30
|
-
def revisions_count(path)
|
31
|
-
`git log --follow --format=oneline #{path.shellescape}`.count("\n")
|
32
|
-
end
|
33
|
-
|
34
|
-
def date_of_last_commit(path)
|
35
|
-
`git log -1 --date=iso --format=%ad #{path.shellescape}`.chomp!
|
36
|
-
end
|
37
|
-
|
38
38
|
private
|
39
39
|
|
40
40
|
def stash_changes
|
41
|
-
return false if everything_commmited?
|
42
|
-
|
43
41
|
stashes_count_before = stashes_count
|
44
42
|
`git stash`
|
45
43
|
stashes_count_after = stashes_count
|
46
44
|
stashes_count_after > stashes_count_before
|
47
45
|
end
|
48
46
|
|
49
|
-
def everything_commmited?
|
50
|
-
`git status --porcelain`.empty?
|
51
|
-
end
|
52
|
-
|
53
47
|
def stashes_count
|
54
|
-
`git stash list`.count("\n")
|
48
|
+
`git stash list --format=%h`.count("\n")
|
55
49
|
end
|
56
50
|
|
57
51
|
def travel_to_original_state
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rubycritic
|
2
|
+
module SourceControlSystem
|
3
|
+
|
4
|
+
class Mercurial < Base
|
5
|
+
register_system
|
6
|
+
|
7
|
+
def self.supported?
|
8
|
+
`hg verify 2>&1` && $?.success?
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.to_s
|
12
|
+
"Mercurial"
|
13
|
+
end
|
14
|
+
|
15
|
+
def revisions_count(path)
|
16
|
+
`hg log #{path.shellescape} --template '1'`.size
|
17
|
+
end
|
18
|
+
|
19
|
+
def date_of_last_commit(path)
|
20
|
+
`hg log #{path.shellescape} --template '{date|isodate}' --limit 1`.chomp
|
21
|
+
end
|
22
|
+
|
23
|
+
def revision?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|