rubycritic-simplecov 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +290 -0
- data/CONTRIBUTING.md +93 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +259 -0
- data/ROADMAP.md +56 -0
- data/Rakefile +28 -0
- data/bin/rubycritic +10 -0
- data/lib/rubycritic/analysers/attributes.rb +29 -0
- data/lib/rubycritic/analysers/churn.rb +30 -0
- data/lib/rubycritic/analysers/complexity.rb +30 -0
- data/lib/rubycritic/analysers/coverage.rb +118 -0
- data/lib/rubycritic/analysers/helpers/ast_node.rb +76 -0
- data/lib/rubycritic/analysers/helpers/flay.rb +13 -0
- data/lib/rubycritic/analysers/helpers/flog.rb +17 -0
- data/lib/rubycritic/analysers/helpers/methods_counter.rb +25 -0
- data/lib/rubycritic/analysers/helpers/modules_locator.rb +42 -0
- data/lib/rubycritic/analysers/helpers/parser.rb +14 -0
- data/lib/rubycritic/analysers/helpers/reek.rb +11 -0
- data/lib/rubycritic/analysers/smells/flay.rb +79 -0
- data/lib/rubycritic/analysers/smells/flog.rb +69 -0
- data/lib/rubycritic/analysers/smells/reek.rb +53 -0
- data/lib/rubycritic/analysers_runner.rb +41 -0
- data/lib/rubycritic/analysis_summary.rb +40 -0
- data/lib/rubycritic/browser.rb +19 -0
- data/lib/rubycritic/cli/application.rb +34 -0
- data/lib/rubycritic/cli/options/argv.rb +137 -0
- data/lib/rubycritic/cli/options/file.rb +100 -0
- data/lib/rubycritic/cli/options.rb +33 -0
- data/lib/rubycritic/colorize.rb +17 -0
- data/lib/rubycritic/command_factory.rb +25 -0
- data/lib/rubycritic/commands/base.rb +18 -0
- data/lib/rubycritic/commands/ci.rb +14 -0
- data/lib/rubycritic/commands/compare.rb +106 -0
- data/lib/rubycritic/commands/default.rb +38 -0
- data/lib/rubycritic/commands/help.rb +18 -0
- data/lib/rubycritic/commands/status_reporter.rb +45 -0
- data/lib/rubycritic/commands/utils/build_number_file.rb +37 -0
- data/lib/rubycritic/commands/version.rb +16 -0
- data/lib/rubycritic/configuration.rb +69 -0
- data/lib/rubycritic/core/analysed_module.rb +93 -0
- data/lib/rubycritic/core/analysed_modules_collection.rb +95 -0
- data/lib/rubycritic/core/location.rb +47 -0
- data/lib/rubycritic/core/rating.rb +30 -0
- data/lib/rubycritic/core/smell.rb +84 -0
- data/lib/rubycritic/generators/console_report.rb +20 -0
- data/lib/rubycritic/generators/html/assets/fonts/FontAwesome.otf +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/Roboto-Medium.ttf +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/Roboto-Regular.ttf +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.eot +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.svg +2671 -0
- data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.woff +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.woff2 +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.svg +288 -0
- data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/lib/rubycritic/generators/html/assets/images/logo.png +0 -0
- data/lib/rubycritic/generators/html/assets/javascripts/application.js +281 -0
- data/lib/rubycritic/generators/html/assets/javascripts/bootstrap.min.js +7 -0
- data/lib/rubycritic/generators/html/assets/javascripts/highcharts.src-4.0.1.js +17672 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.filtertable.min.js +13 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.min.js +4 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.scrollTo.min.js +7 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.tablesorter.js +1031 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.tablesorter.min.js +4 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.timeago.js +231 -0
- data/lib/rubycritic/generators/html/assets/javascripts/prettify.js +46 -0
- data/lib/rubycritic/generators/html/assets/stylesheets/application.css +570 -0
- data/lib/rubycritic/generators/html/assets/stylesheets/bootstrap.min.css +6 -0
- data/lib/rubycritic/generators/html/assets/stylesheets/font-awesome.min.css +4 -0
- data/lib/rubycritic/generators/html/assets/stylesheets/prettify.css +1 -0
- data/lib/rubycritic/generators/html/assets/stylesheets/prettify.custom_theme.css +69 -0
- data/lib/rubycritic/generators/html/base.rb +54 -0
- data/lib/rubycritic/generators/html/code_file.rb +51 -0
- data/lib/rubycritic/generators/html/code_index.rb +33 -0
- data/lib/rubycritic/generators/html/line.rb +37 -0
- data/lib/rubycritic/generators/html/overview.rb +38 -0
- data/lib/rubycritic/generators/html/simple_cov_index.rb +44 -0
- data/lib/rubycritic/generators/html/smells_index.rb +45 -0
- data/lib/rubycritic/generators/html/templates/code_file.html.erb +61 -0
- data/lib/rubycritic/generators/html/templates/code_index.html.erb +55 -0
- data/lib/rubycritic/generators/html/templates/layouts/application.html.erb +66 -0
- data/lib/rubycritic/generators/html/templates/line.html.erb +1 -0
- data/lib/rubycritic/generators/html/templates/overview.html.erb +68 -0
- data/lib/rubycritic/generators/html/templates/simple_cov_index.html.erb +44 -0
- data/lib/rubycritic/generators/html/templates/smells_index.html.erb +47 -0
- data/lib/rubycritic/generators/html/templates/smelly_line.html.erb +23 -0
- data/lib/rubycritic/generators/html/turbulence.rb +17 -0
- data/lib/rubycritic/generators/html/view_helpers.rb +58 -0
- data/lib/rubycritic/generators/html_report.rb +77 -0
- data/lib/rubycritic/generators/json/simple.rb +43 -0
- data/lib/rubycritic/generators/json_report.rb +26 -0
- data/lib/rubycritic/generators/lint_report.rb +30 -0
- data/lib/rubycritic/generators/text/lint.rb +41 -0
- data/lib/rubycritic/generators/text/list.rb +45 -0
- data/lib/rubycritic/generators/text/templates/lint.erb +3 -0
- data/lib/rubycritic/generators/text/templates/list.erb +12 -0
- data/lib/rubycritic/rake_task.rb +71 -0
- data/lib/rubycritic/reporter.rb +39 -0
- data/lib/rubycritic/revision_comparator.rb +45 -0
- data/lib/rubycritic/serializer.rb +32 -0
- data/lib/rubycritic/smells_status_setter.rb +18 -0
- data/lib/rubycritic/source_control_systems/base.rb +41 -0
- data/lib/rubycritic/source_control_systems/double.rb +19 -0
- data/lib/rubycritic/source_control_systems/git.rb +95 -0
- data/lib/rubycritic/source_control_systems/mercurial.rb +29 -0
- data/lib/rubycritic/source_control_systems/perforce.rb +116 -0
- data/lib/rubycritic/source_locator.rb +52 -0
- data/lib/rubycritic/version.rb +5 -0
- data/lib/rubycritic.rb +6 -0
- metadata +528 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module RubyCritic
|
6
|
+
module SourceControlSystem
|
7
|
+
PERFORCE_FSTAT_OPTS = '-F "clientFile=*.rb" -T clientFile,headRev,headTime,headChange,action'.freeze
|
8
|
+
PerforceStats = Struct.new(:filename, :revision, :last_commit, :opened?, :head)
|
9
|
+
|
10
|
+
class Perforce < Base
|
11
|
+
register_system
|
12
|
+
|
13
|
+
def self.supported?
|
14
|
+
p4_client = ENV['P4CLIENT'] || ''
|
15
|
+
p4_installed? && !p4_client.empty? && in_client_directory?
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.p4_installed?
|
19
|
+
p4_exe = Gem.win_platform? ? 'p4.exe' : 'p4'
|
20
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory|
|
21
|
+
File.executable?(File.join(directory, p4_exe))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.in_client_directory?
|
26
|
+
p4_info = `p4 info`.each_line.select do |line|
|
27
|
+
line.start_with?('Client root', 'Current directory')
|
28
|
+
end
|
29
|
+
|
30
|
+
client_directory, current_directory = p4_info.map! { |info| info.split(': ').last.chomp }
|
31
|
+
child?(client_directory, current_directory)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.child?(root, target)
|
35
|
+
root_size = root.size
|
36
|
+
target_size = target.size
|
37
|
+
return false if target_size < root_size
|
38
|
+
|
39
|
+
target[0...root_size] == root &&
|
40
|
+
(target_size == root_size || [File::ALT_SEPARATOR, File::SEPARATOR].include?(target[root_size]))
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.to_s
|
44
|
+
'Perforce'
|
45
|
+
end
|
46
|
+
|
47
|
+
def revisions_count(path)
|
48
|
+
perforce_files[Perforce.key_file(path)].revision.to_i
|
49
|
+
end
|
50
|
+
|
51
|
+
def date_of_last_commit(path)
|
52
|
+
Time.strptime(perforce_files[Perforce.key_file(path)].last_commit, '%s').strftime('%Y-%m-%d %H:%M:%S %z')
|
53
|
+
end
|
54
|
+
|
55
|
+
def revision?
|
56
|
+
!perforce_files.values.count(&:opened?).zero?
|
57
|
+
end
|
58
|
+
|
59
|
+
def head_reference
|
60
|
+
perforce_files.values.map(&:head).max_by(&:to_i)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.build_file_cache
|
64
|
+
# Chun is very slow if files stats are requested one by one
|
65
|
+
# this fill a hash with the result of all ruby file in the current directory (and sub-directories)
|
66
|
+
{}.tap do |file_cache|
|
67
|
+
line_aggregator = []
|
68
|
+
`p4 fstat #{PERFORCE_FSTAT_OPTS} #{Dir.getwd}...`.each_line do |line|
|
69
|
+
Perforce.compute_line(file_cache, line_aggregator, line)
|
70
|
+
end
|
71
|
+
# handle remaining lines
|
72
|
+
Perforce.insert_file_cache(file_cache, line_aggregator) if line_aggregator.any?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.compute_line(file_cache, line_aggregator, line)
|
77
|
+
if line.chomp.empty?
|
78
|
+
Perforce.insert_file_cache(file_cache, line_aggregator)
|
79
|
+
else
|
80
|
+
line_aggregator << line
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.insert_file_cache(file_cache, lines)
|
85
|
+
perforce_stat = Perforce.compute_cache_lines(lines)
|
86
|
+
file_cache[perforce_stat.filename] = perforce_stat
|
87
|
+
lines.clear
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.compute_cache_lines(lines)
|
91
|
+
perforce_lines = Hash[*lines.map { |line| line.split[1..-1] }.flatten]
|
92
|
+
PerforceStats.new(
|
93
|
+
Perforce.normalized_file_path(perforce_lines['clientFile']),
|
94
|
+
perforce_lines['headRev'],
|
95
|
+
perforce_lines['headTime'],
|
96
|
+
perforce_lines.key?('action'),
|
97
|
+
perforce_lines['headChange']
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.key_file(source_file_path)
|
102
|
+
Perforce.normalized_file_path(File.join(Dir.getwd, source_file_path))
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.normalized_file_path(file_path)
|
106
|
+
file_path.downcase.tr('\\', '/')
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def perforce_files
|
112
|
+
@perforce_files ||= Perforce.build_file_cache
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'rubycritic/configuration'
|
5
|
+
|
6
|
+
module RubyCritic
|
7
|
+
class SourceLocator
|
8
|
+
RUBY_EXTENSION = '.rb'.freeze
|
9
|
+
RUBY_FILES = File.join('**', "*#{RUBY_EXTENSION}")
|
10
|
+
|
11
|
+
def initialize(paths)
|
12
|
+
@initial_paths = Array(paths)
|
13
|
+
end
|
14
|
+
|
15
|
+
def paths
|
16
|
+
@paths ||= pathnames.map(&:to_s)
|
17
|
+
end
|
18
|
+
|
19
|
+
def pathnames
|
20
|
+
@pathnames ||= expand_paths
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def deduplicate_symlinks(path_list)
|
26
|
+
# sort the symlinks to the end so files are preferred
|
27
|
+
path_list.sort_by! { |path| File.symlink?(path.cleanpath) ? 'z' : 'a' }
|
28
|
+
if defined?(JRUBY_VERSION)
|
29
|
+
require 'java'
|
30
|
+
path_list.uniq! do |path|
|
31
|
+
java.io.File.new(path.realpath.to_s).canonical_path
|
32
|
+
end
|
33
|
+
else
|
34
|
+
path_list.uniq!(&:realpath)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def expand_paths
|
39
|
+
path_list = @initial_paths.flat_map do |path|
|
40
|
+
if File.directory?(path)
|
41
|
+
Pathname.glob(File.join(path, RUBY_FILES))
|
42
|
+
elsif File.exist?(path) && File.extname(path) == RUBY_EXTENSION
|
43
|
+
Pathname.new(path)
|
44
|
+
end
|
45
|
+
end.compact
|
46
|
+
|
47
|
+
deduplicate_symlinks(path_list) if Config.deduplicate_symlinks
|
48
|
+
|
49
|
+
path_list.map(&:cleanpath)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|