rubycritic 3.5.2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -1
  3. data/README.md +19 -0
  4. data/lib/rubycritic/analysers/helpers/ast_node.rb +19 -12
  5. data/lib/rubycritic/analysers/helpers/modules_locator.rb +1 -1
  6. data/lib/rubycritic/analysers/helpers/reek.rb +1 -1
  7. data/lib/rubycritic/analysers/smells/flay.rb +10 -8
  8. data/lib/rubycritic/cli/application.rb +3 -2
  9. data/lib/rubycritic/cli/options.rb +9 -97
  10. data/lib/rubycritic/cli/options/argv.rb +117 -0
  11. data/lib/rubycritic/cli/options/file.rb +100 -0
  12. data/lib/rubycritic/command_factory.rb +6 -13
  13. data/lib/rubycritic/commands/compare.rb +2 -1
  14. data/lib/rubycritic/commands/default.rb +2 -2
  15. data/lib/rubycritic/commands/status_reporter.rb +1 -1
  16. data/lib/rubycritic/commands/utils/build_number_file.rb +2 -0
  17. data/lib/rubycritic/configuration.rb +7 -9
  18. data/lib/rubycritic/core/analysed_modules_collection.rb +11 -5
  19. data/lib/rubycritic/generators/html/base.rb +1 -1
  20. data/lib/rubycritic/generators/html/code_file.rb +2 -2
  21. data/lib/rubycritic/generators/html/code_index.rb +2 -2
  22. data/lib/rubycritic/generators/html/overview.rb +2 -2
  23. data/lib/rubycritic/generators/html/smells_index.rb +2 -2
  24. data/lib/rubycritic/generators/html/templates/overview.html.erb +1 -1
  25. data/lib/rubycritic/reporter.rb +9 -12
  26. data/lib/rubycritic/revision_comparator.rb +10 -11
  27. data/lib/rubycritic/source_control_systems/base.rb +3 -2
  28. data/lib/rubycritic/source_control_systems/git.rb +3 -2
  29. data/lib/rubycritic/source_control_systems/mercurial.rb +1 -1
  30. data/lib/rubycritic/source_control_systems/perforce.rb +1 -0
  31. data/lib/rubycritic/version.rb +1 -1
  32. metadata +74 -67
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0537a727706d7903c2a5de836b5536a686efa8ffcdd25c883e99405ca9610bd0
4
- data.tar.gz: 9d4a3d3c1d3fe703556a7e2b8a98353845c8fb85260244b8a5ea8152d4173857
3
+ metadata.gz: db2b8e076626a6a29d140f9f6552b6f5829e0f8d258b9cc47afa4fc1f21acbcc
4
+ data.tar.gz: 6ef348632806a7a388aebadb6d53eec20870f0efc93459433debeda020126f00
5
5
  SHA512:
6
- metadata.gz: 6580fd04f39137829c4f4b022a246c12625aca43c2d88ddd3de5dd2729bd7ddbbbfbccc4cbd0e6cf9e71045a318ce623af547f6d869bf92c67b3e1efa7b64e2c
7
- data.tar.gz: 3c8d5bd2a02452c2addc0460fb203f255ab2095230588c890af64610b75fc8badea7c791081c47c98ba53537d80554f448861fbfb4ddccb11d93fa4efabc9824
6
+ metadata.gz: b081e071ffad334bb27a1e469f5debe08bd2b3cc563cf1c5196c745539c237eb640297df2936461913a1b1fc4a714a8365786191bbe016725c94a96f80b7dd74
7
+ data.tar.gz: a937c6a4142b87a414b513492517d4defccdf06d182b1a846fea149142d6bf10d06c42dcf62fad5edd8746d7eb7236d427d12109f0e3b13573577dc6902848c7
@@ -1,4 +1,14 @@
1
- # master [(unreleased)](https://github.com/whitesmith/rubycritic/compare/v3.5.2...master)
1
+ # master [(unreleased)](https://github.com/whitesmith/rubycritic/compare/v4.0.0...master)
2
+
3
+ # 4.0.0 / 2019-02-27 [(commits)](https://github.com/whitesmith/rubycritic/compare/v3.5.1...v4.0.0)
4
+
5
+ * [FEATURE] Allow generating reports in multiple formats in one run (by [@katafrakt])
6
+ * [FEATURE] Allow to accept a config file (by [@mfbmina])
7
+ * [CHANGE] Update `reek` to 5.3 (by [@taitran19][] and [@onumis][])
8
+ * [CHANGE] Update `parser` to 2.6.0 (by [@onumis][])
9
+ * [CHANGE] Update `tty-which` to 0.4.0 (by [@onumis][])
10
+ * [CHANGE] Drop support for ruby 2.1 and 2.2 (by [@onumis][])
11
+ * [CHANGE] Fix rubocop offenses (by [@AllanSiqueira][] and [@harman28][])
2
12
 
3
13
  # 3.5.2 / 2018-09-27 [(commits)](https://github.com/whitesmith/rubycritic/compare/v3.5.1...v3.5.2)
4
14
 
@@ -253,3 +263,7 @@
253
263
  [@HemanthMudalaiah]: https://github.com/HemanthMudalaiah
254
264
  [@SuperSandro2000]: https://github.com/SuperSandro2000
255
265
  [@antoineLeclercq]: https://github.com/antoineLeclercq
266
+ [@mfbmina]: https://github.com/mfbmina
267
+ [@taitran19]: https://github.com/taitran19
268
+ [@AllanSiqueira]: https://github.com/AllanSiqueira
269
+ [@harman28]: https://github.com/harman28
data/README.md CHANGED
@@ -125,6 +125,25 @@ $ rubycritic --help
125
125
  | `--suppress-ratings` | Suppress letter ratings |
126
126
  | `--no-browser` | Do not open html report with browser |
127
127
 
128
+ You also can use a config file. Just create a `.rubycritic.yml` on your project root path.
129
+
130
+ Here are one example:
131
+ ```
132
+ mode_ci:
133
+ enabled: true # default is false
134
+ branch: 'production' # default is master
135
+ branch: 'production' # default is master
136
+ path: '/tmp/mycustompath' # Set path where report will be saved (tmp/rubycritic by default)
137
+ threshhold_score: 10 # default is 0
138
+ deduplicate_symlinks: true # default is false
139
+ suppress_ratings: true # default is false
140
+ no_browser: true # default is false
141
+ format: console # Available values are: html, json, console, lint. Default value is html.
142
+ minimum_score: 95 # default is 0
143
+ paths: # Files to analyse.
144
+ - 'app/controllers/'
145
+ - 'app/models/'
146
+ ```
128
147
 
129
148
  ### Analyzer Configuration
130
149
 
@@ -16,24 +16,21 @@ module Parser
16
16
  def recursive_children
17
17
  children.each do |child|
18
18
  next unless child.is_a?(Parser::AST::Node)
19
+
19
20
  yield child
20
21
  child.recursive_children { |grand_child| yield grand_child }
21
22
  end
22
23
  end
23
24
 
24
- def get_module_names
25
- children_modules = children
26
- .select { |child| child.is_a?(Parser::AST::Node) }
27
- .flat_map(&:get_module_names)
25
+ def module_names
26
+ ast_node_children = children.select do |child|
27
+ child.is_a?(Parser::AST::Node)
28
+ end
29
+
30
+ children_modules = ast_node_children.flat_map(&:module_names)
28
31
 
29
32
  if MODULE_TYPES.include?(type)
30
- if children_modules.empty?
31
- [module_name]
32
- else
33
- children_modules.map do |children_module|
34
- "#{module_name}::#{children_module}"
35
- end
36
- end
33
+ module_names_with_children children_modules
37
34
  else
38
35
  children_modules
39
36
  end
@@ -41,6 +38,16 @@ module Parser
41
38
 
42
39
  private
43
40
 
41
+ def module_names_with_children(children_modules)
42
+ if children_modules.empty?
43
+ [module_name]
44
+ else
45
+ children_modules.map do |children_module|
46
+ "#{module_name}::#{children_module}"
47
+ end
48
+ end
49
+ end
50
+
44
51
  def module_name
45
52
  name_segments = []
46
53
  current_node = children[0]
@@ -61,7 +68,7 @@ module RubyCritic
61
68
  0
62
69
  end
63
70
 
64
- def get_module_names
71
+ def module_names
65
72
  []
66
73
  end
67
74
  end
@@ -13,7 +13,7 @@ module RubyCritic
13
13
  end
14
14
 
15
15
  def names
16
- names = node.get_module_names
16
+ names = node.module_names
17
17
  if names.empty?
18
18
  name_from_path
19
19
  else
@@ -5,7 +5,7 @@ require 'reek'
5
5
  module RubyCritic
6
6
  class Reek < ::Reek::Examiner
7
7
  def initialize(analysed_module)
8
- super(analysed_module, configuration: ::Reek::Configuration::AppConfiguration.from_path)
8
+ super(analysed_module, configuration: ::Reek::Configuration::AppConfiguration.from_default_path)
9
9
  end
10
10
  end
11
11
  end
@@ -15,14 +15,7 @@ module RubyCritic
15
15
 
16
16
  def run
17
17
  @flay.hashes.each do |structural_hash, nodes|
18
- smell = create_smell(structural_hash, nodes)
19
- nodes.map(&:file).uniq.each do |file|
20
- @analysed_modules[file].smells << smell
21
- end
22
-
23
- nodes.each do |node|
24
- @analysed_modules[node.file].duplication += node.mass
25
- end
18
+ analyze_modules(structural_hash, nodes)
26
19
  print green '.'
27
20
  end
28
21
  puts ''
@@ -72,6 +65,15 @@ module RubyCritic
72
65
  def cost(mass)
73
66
  mass / 25
74
67
  end
68
+
69
+ def analyze_modules(structural_hash, nodes)
70
+ nodes.map(&:file).uniq.each do |file|
71
+ @analysed_modules[file].smells << create_smell(structural_hash, nodes)
72
+ end
73
+ nodes.each do |node|
74
+ @analysed_modules[node.file].duplication += node.mass
75
+ end
76
+ end
75
77
  end
76
78
  end
77
79
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rubycritic'
4
+ require 'rubycritic/browser'
4
5
  require 'rubycritic/cli/options'
5
6
  require 'rubycritic/command_factory'
6
7
 
@@ -15,9 +16,9 @@ module RubyCritic
15
16
  end
16
17
 
17
18
  def execute
18
- parsed_options = @options.parse
19
+ parsed_options = @options.parse.to_h
19
20
 
20
- reporter = RubyCritic::CommandFactory.create(parsed_options.to_h).execute
21
+ reporter = RubyCritic::CommandFactory.create(parsed_options).execute
21
22
  print(reporter.status_message)
22
23
  reporter.status
23
24
  rescue OptionParser::InvalidOption => error
@@ -1,115 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'optparse'
4
- require 'rubycritic/browser'
3
+ require 'rubycritic/cli/options/argv'
4
+ require 'rubycritic/cli/options/file'
5
5
 
6
6
  module RubyCritic
7
7
  module Cli
8
8
  class Options
9
+ attr_reader :argv_options, :file_options
10
+
9
11
  def initialize(argv)
10
- @argv = argv
11
- self.parser = OptionParser.new
12
+ @argv_options = Argv.new(argv)
13
+ @file_options = File.new
12
14
  end
13
15
 
14
- # rubocop:disable Metrics/MethodLength
15
16
  def parse
16
- parser.new do |opts|
17
- opts.banner = 'Usage: rubycritic [options] [paths]'
18
-
19
- opts.on('-p', '--path [PATH]', 'Set path where report will be saved (tmp/rubycritic by default)') do |path|
20
- @root = path
21
- end
22
-
23
- opts.on('-b', '--branch BRANCH', 'Set branch to compare') do |branch|
24
- self.base_branch = String(branch)
25
- set_current_branch
26
- self.mode = :compare_branches
27
- end
28
-
29
- opts.on('-t', '--maximum-decrease [MAX_DECREASE]',
30
- 'Set a threshold for score difference between two branches (works only with -b)') do |threshold_score|
31
- self.threshold_score = Integer(threshold_score)
32
- end
33
-
34
- opts.on(
35
- '-f', '--format [FORMAT]',
36
- %i[html json console lint],
37
- 'Report smells in the given format:',
38
- ' html (default; will open in a browser)',
39
- ' json',
40
- ' console',
41
- ' lint'
42
- ) do |format|
43
- self.format = format
44
- end
45
-
46
- opts.on('-s', '--minimum-score [MIN_SCORE]', 'Set a minimum score') do |min_score|
47
- self.minimum_score = Float(min_score)
48
- end
49
-
50
- opts.on('-m', '--mode-ci [BASE_BRANCH]',
51
- 'Use CI mode (faster, analyses diffs w.r.t base_branch (default: master))') do |branch|
52
- self.base_branch = branch || 'master'
53
- set_current_branch
54
- self.mode = :ci
55
- end
56
-
57
- opts.on('--deduplicate-symlinks', 'De-duplicate symlinks based on their final target') do
58
- self.deduplicate_symlinks = true
59
- end
17
+ argv_options.parse
18
+ file_options.parse
60
19
 
61
- opts.on('--suppress-ratings', 'Suppress letter ratings') do
62
- self.suppress_ratings = true
63
- end
64
-
65
- opts.on('--no-browser', 'Do not open html report with browser') do
66
- self.no_browser = true
67
- end
68
-
69
- opts.on_tail('-v', '--version', "Show gem's version") do
70
- self.mode = :version
71
- end
72
-
73
- opts.on_tail('-h', '--help', 'Show this message') do
74
- self.mode = :help
75
- end
76
- end.parse!(@argv)
77
20
  self
78
21
  end
79
22
 
80
23
  def to_h
81
- {
82
- mode: mode,
83
- root: root,
84
- format: format,
85
- deduplicate_symlinks: deduplicate_symlinks,
86
- paths: paths,
87
- suppress_ratings: suppress_ratings,
88
- help_text: parser.help,
89
- minimum_score: minimum_score || 0,
90
- no_browser: no_browser,
91
- base_branch: base_branch,
92
- feature_branch: feature_branch,
93
- threshold_score: threshold_score || 0
94
- }
95
- end
96
- # rubocop:enable Metrics/MethodLength
97
-
98
- private
99
-
100
- attr_accessor :mode, :root, :format, :deduplicate_symlinks,
101
- :suppress_ratings, :minimum_score, :no_browser,
102
- :parser, :base_branch, :feature_branch, :threshold_score
103
- def paths
104
- if @argv.empty?
105
- ['.']
106
- else
107
- @argv
108
- end
109
- end
110
-
111
- def set_current_branch
112
- self.feature_branch = SourceControlSystem::Git.current_branch
24
+ file_options.to_h.merge(argv_options.to_h)
113
25
  end
114
26
  end
115
27
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ module RubyCritic
6
+ module Cli
7
+ class Options
8
+ class Argv
9
+ def initialize(argv)
10
+ @argv = argv
11
+ self.parser = OptionParser.new
12
+ end
13
+
14
+ # rubocop:disable Metrics/MethodLength
15
+ def parse
16
+ parser.new do |opts|
17
+ opts.banner = 'Usage: rubycritic [options] [paths]'
18
+
19
+ opts.on('-p', '--path [PATH]', 'Set path where report will be saved (tmp/rubycritic by default)') do |path|
20
+ @root = path
21
+ end
22
+
23
+ opts.on('-b', '--branch BRANCH', 'Set branch to compare') do |branch|
24
+ self.base_branch = String(branch)
25
+ set_current_branch
26
+ self.mode = :compare_branches
27
+ end
28
+
29
+ opts.on(
30
+ '-t',
31
+ '--maximum-decrease [MAX_DECREASE]',
32
+ 'Set a threshold for score difference between two branches (works only with -b)'
33
+ ) do |threshold_score|
34
+ self.threshold_score = Integer(threshold_score)
35
+ end
36
+
37
+ formats = []
38
+ self.formats = formats
39
+ opts.on(
40
+ '-f', '--format [FORMAT]',
41
+ %i[html json console lint],
42
+ 'Report smells in the given format:',
43
+ ' html (default; will open in a browser)',
44
+ ' json',
45
+ ' console',
46
+ ' lint'
47
+ ) do |format|
48
+ formats << format
49
+ end
50
+
51
+ opts.on('-s', '--minimum-score [MIN_SCORE]', 'Set a minimum score') do |min_score|
52
+ self.minimum_score = Float(min_score)
53
+ end
54
+
55
+ opts.on('-m', '--mode-ci [BASE_BRANCH]',
56
+ 'Use CI mode (faster, analyses diffs w.r.t base_branch (default: master))') do |branch|
57
+ self.base_branch = branch || 'master'
58
+ set_current_branch
59
+ self.mode = :ci
60
+ end
61
+
62
+ opts.on('--deduplicate-symlinks', 'De-duplicate symlinks based on their final target') do
63
+ self.deduplicate_symlinks = true
64
+ end
65
+
66
+ opts.on('--suppress-ratings', 'Suppress letter ratings') do
67
+ self.suppress_ratings = true
68
+ end
69
+
70
+ opts.on('--no-browser', 'Do not open html report with browser') do
71
+ self.no_browser = true
72
+ end
73
+
74
+ opts.on_tail('-v', '--version', "Show gem's version") do
75
+ self.mode = :version
76
+ end
77
+
78
+ opts.on_tail('-h', '--help', 'Show this message') do
79
+ self.mode = :help
80
+ end
81
+ end.parse!(@argv)
82
+ end
83
+
84
+ def to_h
85
+ {
86
+ mode: mode,
87
+ root: root,
88
+ formats: formats,
89
+ deduplicate_symlinks: deduplicate_symlinks,
90
+ paths: paths,
91
+ suppress_ratings: suppress_ratings,
92
+ help_text: parser.help,
93
+ minimum_score: minimum_score,
94
+ no_browser: no_browser,
95
+ base_branch: base_branch,
96
+ feature_branch: feature_branch,
97
+ threshold_score: threshold_score
98
+ }
99
+ end
100
+ # rubocop:enable Metrics/MethodLength
101
+
102
+ private
103
+
104
+ attr_accessor :mode, :root, :formats, :deduplicate_symlinks,
105
+ :suppress_ratings, :minimum_score, :no_browser,
106
+ :parser, :base_branch, :feature_branch, :threshold_score
107
+ def paths
108
+ @argv unless @argv.empty?
109
+ end
110
+
111
+ def set_current_branch
112
+ self.feature_branch = SourceControlSystem::Git.current_branch
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module RubyCritic
6
+ module Cli
7
+ class Options
8
+ class File
9
+ attr_reader :filename, :options
10
+
11
+ def initialize(filename = './.rubycritic.yml')
12
+ @filename = filename
13
+ @options = {}
14
+ end
15
+
16
+ def parse
17
+ @options = YAML.load_file(filename) if ::File.file?(filename)
18
+ end
19
+
20
+ # rubocop:disable Metrics/MethodLength
21
+ def to_h
22
+ {
23
+ mode: mode,
24
+ root: root,
25
+ formats: formats,
26
+ deduplicate_symlinks: deduplicate_symlinks,
27
+ paths: paths,
28
+ suppress_ratings: suppress_ratings,
29
+ minimum_score: minimum_score,
30
+ no_browser: no_browser,
31
+ base_branch: base_branch,
32
+ feature_branch: feature_branch,
33
+ threshold_score: threshold_score
34
+ }
35
+ end
36
+ # rubocop:enable Metrics/MethodLength
37
+
38
+ private
39
+
40
+ def base_branch
41
+ return options.dig('mode_ci', 'branch') || 'master' if options.dig('mode_ci', 'enabled').to_s == 'true'
42
+
43
+ options['branch']
44
+ end
45
+
46
+ def mode
47
+ if options.dig('mode_ci', 'enabled').to_s == 'true'
48
+ :ci
49
+ elsif base_branch
50
+ :compare_branches
51
+ end
52
+ end
53
+
54
+ def feature_branch
55
+ SourceControlSystem::Git.current_branch if base_branch
56
+ end
57
+
58
+ def root
59
+ options['path']
60
+ end
61
+
62
+ def threshold_score
63
+ options['threshold_score']
64
+ end
65
+
66
+ def deduplicate_symlinks
67
+ value_for(options['deduplicate_symlinks'])
68
+ end
69
+
70
+ def suppress_ratings
71
+ value_for(options['suppress_ratings'])
72
+ end
73
+
74
+ def no_browser
75
+ value_for(options['no_browser'])
76
+ end
77
+
78
+ def formats
79
+ formats = options['formats'] || []
80
+ formats.select do |format|
81
+ %w[html json console lint].include?(format)
82
+ end
83
+ end
84
+
85
+ def minimum_score
86
+ options['minimum_score']
87
+ end
88
+
89
+ def paths
90
+ options['paths']
91
+ end
92
+
93
+ def value_for(value)
94
+ value = value.to_s
95
+ value == 'true' unless value.empty?
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -4,25 +4,18 @@ require 'rubycritic/configuration'
4
4
 
5
5
  module RubyCritic
6
6
  class CommandFactory
7
+ COMMAND_CLASS_MODES = %i[version help ci compare default].freeze
8
+
7
9
  def self.create(options = {})
8
10
  Config.set(options)
9
11
  command_class(Config.mode).new(options)
10
12
  end
11
13
 
12
14
  def self.command_class(mode)
13
- case mode
14
- when :version
15
- require 'rubycritic/commands/version'
16
- Command::Version
17
- when :help
18
- require 'rubycritic/commands/help'
19
- Command::Help
20
- when :ci
21
- require 'rubycritic/commands/ci'
22
- Command::Ci
23
- when :compare_branches
24
- require 'rubycritic/commands/compare'
25
- Command::Compare
15
+ mode = mode.to_s.split('_').first.to_sym
16
+ if COMMAND_CLASS_MODES.include? mode
17
+ require "rubycritic/commands/#{mode}"
18
+ Command.const_get(mode.capitalize)
26
19
  else
27
20
  require 'rubycritic/commands/default'
28
21
  Command::Default
@@ -70,6 +70,7 @@ module RubyCritic
70
70
  # two branches is greater than threshold value
71
71
  def compare_threshold
72
72
  return unless mark_build_fail?
73
+
73
74
  print("Threshold: #{Config.threshold_score}\n")
74
75
  print("Difference: #{(Config.base_branch_score - Config.feature_branch_score).abs}\n")
75
76
  abort('The score difference between the two branches is over the threshold.')
@@ -98,7 +99,7 @@ module RubyCritic
98
99
  def critique(branch)
99
100
  module_collection = AnalysersRunner.new(paths).run
100
101
  Config.send(:"#{branch}_collection=", module_collection)
101
- RevisionComparator.new(paths).set_statuses(module_collection)
102
+ RevisionComparator.new(paths).statuses = module_collection
102
103
  end
103
104
  end
104
105
  end
@@ -11,7 +11,7 @@ module RubyCritic
11
11
  class Default < Base
12
12
  def initialize(options)
13
13
  super
14
- @paths = options[:paths]
14
+ @paths = options[:paths] || ['.']
15
15
  Config.source_control_system = SourceControlSystem::Base.create
16
16
  end
17
17
 
@@ -22,7 +22,7 @@ module RubyCritic
22
22
 
23
23
  def critique
24
24
  analysed_modules = AnalysersRunner.new(paths).run
25
- RevisionComparator.new(paths).set_statuses(analysed_modules)
25
+ RevisionComparator.new(paths).statuses = analysed_modules
26
26
  end
27
27
 
28
28
  def report(analysed_modules)
@@ -29,7 +29,7 @@ module RubyCritic
29
29
  end
30
30
 
31
31
  def satisfy_minimum_score_rule
32
- score >= @options[:minimum_score]
32
+ score >= @options[:minimum_score].to_f
33
33
  end
34
34
 
35
35
  def update_status_message
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RubyCritic
2
4
  module Command
3
5
  module Utils
@@ -5,7 +5,7 @@ require 'rubycritic/source_control_systems/base'
5
5
  module RubyCritic
6
6
  class Configuration
7
7
  attr_reader :root
8
- attr_accessor :source_control_system, :mode, :format, :deduplicate_symlinks,
8
+ attr_accessor :source_control_system, :mode, :formats, :deduplicate_symlinks,
9
9
  :suppress_ratings, :open_with, :no_browser, :base_branch,
10
10
  :feature_branch, :base_branch_score, :feature_branch_score,
11
11
  :base_root_directory, :feature_root_directory,
@@ -15,14 +15,14 @@ module RubyCritic
15
15
  def set(options)
16
16
  self.mode = options[:mode] || :default
17
17
  self.root = options[:root] || 'tmp/rubycritic'
18
- self.format = options[:format] || :html
19
- self.deduplicate_symlinks = options[:deduplicate_symlinks] || false
20
- self.suppress_ratings = options[:suppress_ratings] || false
18
+ self.formats = options[:formats] || [:html]
19
+ self.deduplicate_symlinks = options[:deduplicate_symlinks]
20
+ self.suppress_ratings = options[:suppress_ratings]
21
21
  self.open_with = options[:open_with]
22
22
  self.no_browser = options[:no_browser]
23
23
  self.base_branch = options[:base_branch]
24
24
  self.feature_branch = options[:feature_branch]
25
- self.threshold_score = options[:threshold_score]
25
+ self.threshold_score = options[:threshold_score].to_i
26
26
  end
27
27
 
28
28
  def root=(path)
@@ -45,13 +45,11 @@ module RubyCritic
45
45
  end
46
46
 
47
47
  def self.compare_branches_mode?
48
- mode = Config.mode
49
- mode == :compare_branches || mode == :ci
48
+ %i[compare_branches ci].include?(Config.mode)
50
49
  end
51
50
 
52
51
  def self.build_mode?
53
- mode = Config.mode
54
- (mode == :compare_branches || mode == :ci) && !Config.no_browser
52
+ !Config.no_browser && %i[compare_branches ci].include?(Config.mode)
55
53
  end
56
54
 
57
55
  def self.method_missing(method, *args, &block)
@@ -68,7 +68,7 @@ module RubyCritic
68
68
 
69
69
  def average_cost
70
70
  num_modules = @modules.size
71
- if num_modules > 0
71
+ if num_modules.positive?
72
72
  map { |mod| limited_cost_for(mod) }.reduce(:+) / num_modules.to_f
73
73
  else
74
74
  0.0
@@ -80,10 +80,16 @@ module RubyCritic
80
80
  end
81
81
 
82
82
  def build_analysed_module(analysed_module)
83
- AnalysedModule.new(pathname: analysed_module.pathname, name: analysed_module.name,
84
- smells: analysed_module.smells, churn: analysed_module.churn,
85
- committed_at: analysed_module.committed_at, complexity: analysed_module.complexity,
86
- duplication: analysed_module.duplication, methods_count: analysed_module.methods_count)
83
+ AnalysedModule.new(
84
+ pathname: analysed_module.pathname,
85
+ name: analysed_module.name,
86
+ smells: analysed_module.smells,
87
+ churn: analysed_module.churn,
88
+ committed_at: analysed_module.committed_at,
89
+ complexity: analysed_module.complexity,
90
+ duplication: analysed_module.duplication,
91
+ methods_count: analysed_module.methods_count
92
+ )
87
93
  end
88
94
  end
89
95
  end
@@ -45,7 +45,7 @@ module RubyCritic
45
45
  @root_directory ||= Pathname.new(Config.root)
46
46
  end
47
47
 
48
- def get_binding
48
+ def base_binding
49
49
  binding
50
50
  end
51
51
  end
@@ -42,8 +42,8 @@ module RubyCritic
42
42
  file_code << Line.new(file_directory, line_text, line_smells).render
43
43
  end
44
44
 
45
- file_body = TEMPLATE.result(get_binding { file_code.join })
46
- LAYOUT_TEMPLATE.result(get_binding { file_body })
45
+ file_body = TEMPLATE.result(base_binding { file_code.join })
46
+ LAYOUT_TEMPLATE.result(base_binding { file_body })
47
47
  end
48
48
  end
49
49
  end
@@ -24,8 +24,8 @@ module RubyCritic
24
24
  end
25
25
 
26
26
  def render
27
- index_body = TEMPLATE.result(get_binding)
28
- LAYOUT_TEMPLATE.result(get_binding { index_body })
27
+ index_body = TEMPLATE.result(base_binding)
28
+ LAYOUT_TEMPLATE.result(base_binding { index_body })
29
29
  end
30
30
  end
31
31
  end
@@ -29,8 +29,8 @@ module RubyCritic
29
29
  end
30
30
 
31
31
  def render
32
- index_body = TEMPLATE.result(get_binding)
33
- LAYOUT_TEMPLATE.result(get_binding { index_body })
32
+ index_body = TEMPLATE.result(base_binding)
33
+ LAYOUT_TEMPLATE.result(base_binding { index_body })
34
34
  end
35
35
  end
36
36
  end
@@ -26,8 +26,8 @@ module RubyCritic
26
26
  end
27
27
 
28
28
  def render
29
- index_body = TEMPLATE.result(get_binding)
30
- LAYOUT_TEMPLATE.result(get_binding { index_body })
29
+ index_body = TEMPLATE.result(base_binding)
30
+ LAYOUT_TEMPLATE.result(base_binding { index_body })
31
31
  end
32
32
 
33
33
  private
@@ -4,7 +4,7 @@
4
4
  <div class="row">
5
5
  <!--Page Title -->
6
6
  <div class="Page_Title">
7
- <h3>Overview</h3>
7
+ <h3>Overview</h3>
8
8
  </div>
9
9
  <!--End Page Title -->
10
10
  <div class="Content_Wrapper">
@@ -2,21 +2,18 @@
2
2
 
3
3
  module RubyCritic
4
4
  module Reporter
5
+ REPORT_GENERATOR_CLASS_FORMATS = %i[json console lint].freeze
6
+
5
7
  def self.generate_report(analysed_modules)
6
- report_generator_class.new(analysed_modules).generate_report
8
+ Config.formats.uniq.each do |format|
9
+ report_generator_class(format).new(analysed_modules).generate_report
10
+ end
7
11
  end
8
12
 
9
- def self.report_generator_class
10
- case Config.format
11
- when :json
12
- require 'rubycritic/generators/json_report'
13
- Generator::JsonReport
14
- when :console
15
- require 'rubycritic/generators/console_report'
16
- Generator::ConsoleReport
17
- when :lint
18
- require 'rubycritic/generators/lint_report'
19
- Generator::LintReport
13
+ def self.report_generator_class(config_format)
14
+ if REPORT_GENERATOR_CLASS_FORMATS.include? config_format
15
+ require "rubycritic/generators/#{config_format}_report"
16
+ Generator.const_get("#{config_format.capitalize}Report")
20
17
  else
21
18
  require 'rubycritic/generators/html_report'
22
19
  Generator::HtmlReport
@@ -14,17 +14,16 @@ module RubyCritic
14
14
  @paths = paths
15
15
  end
16
16
 
17
- def set_statuses(analysed_modules_now)
18
- if Config.source_control_system.revision?
19
- analysed_modules_before = load_cached_analysed_modules
20
- if analysed_modules_before
21
- SmellsStatusSetter.set(
22
- analysed_modules_before.flat_map(&:smells),
23
- analysed_modules_now.flat_map(&:smells)
24
- )
25
- end
26
- end
27
- analysed_modules_now
17
+ def statuses=(analysed_modules_now)
18
+ return unless Config.source_control_system.revision?
19
+
20
+ analysed_modules_before = load_cached_analysed_modules
21
+ return unless analysed_modules_before
22
+
23
+ SmellsStatusSetter.set(
24
+ analysed_modules_before.flat_map(&:smells),
25
+ analysed_modules_now.flat_map(&:smells)
26
+ )
28
27
  end
29
28
 
30
29
  private
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'English'
3
4
  require 'shellwords'
4
5
 
5
6
  module RubyCritic
@@ -21,8 +22,8 @@ module RubyCritic
21
22
  supported_system.new
22
23
  else
23
24
  puts 'RubyCritic can provide more feedback if you use '\
24
- "a #{connected_system_names} repository. "\
25
- 'Churn will not be calculated.'
25
+ "a #{connected_system_names} repository. "\
26
+ 'Churn will not be calculated.'
26
27
  Double.new
27
28
  end
28
29
  end
@@ -21,7 +21,7 @@ module RubyCritic
21
21
  end
22
22
 
23
23
  def self.supported?
24
- git('branch 2>&1') && $?.success?
24
+ git('branch 2>&1') && $CHILD_STATUS.success?
25
25
  end
26
26
 
27
27
  def self.to_s
@@ -37,7 +37,7 @@ module RubyCritic
37
37
  end
38
38
 
39
39
  def revision?
40
- head_reference && $?.success?
40
+ head_reference && $CHILD_STATUS.success?
41
41
  end
42
42
 
43
43
  def head_reference
@@ -63,6 +63,7 @@ module RubyCritic
63
63
  modified_files = `git diff --name-status #{Config.base_branch} #{Config.feature_branch}`
64
64
  modified_files.split("\n").map do |line|
65
65
  next if line.start_with?('D')
66
+
66
67
  file_name = line.split("\t")[1]
67
68
  file_name
68
69
  end.compact
@@ -6,7 +6,7 @@ module RubyCritic
6
6
  register_system
7
7
 
8
8
  def self.supported?
9
- `hg verify 2>&1` && $?.success?
9
+ `hg verify 2>&1` && $CHILD_STATUS.success?
10
10
  end
11
11
 
12
12
  def self.to_s
@@ -35,6 +35,7 @@ module RubyCritic
35
35
  root_size = root.size
36
36
  target_size = target.size
37
37
  return false if target_size < root_size
38
+
38
39
  target[0...root_size] == root &&
39
40
  (target_size == root_size || [File::ALT_SEPARATOR, File::SEPARATOR].include?(target[root_size]))
40
41
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyCritic
4
- VERSION = '3.5.2'.freeze
4
+ VERSION = '4.0.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubycritic
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.2
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guilherme Simoes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-27 00:00:00.000000000 Z
11
+ date: 2019-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: flay
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 2.5.0
61
+ version: 2.6.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 2.5.0
68
+ version: 2.6.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rainbow
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '4.4'
89
+ version: 5.3.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '4.4'
96
+ version: 5.3.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: ruby_parser
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.3.0
117
+ version: 0.4.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.3.0
124
+ version: 0.4.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: virtus
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -140,82 +140,82 @@ dependencies:
140
140
  name: aruba
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.12'
146
143
  - - ">="
147
144
  - !ruby/object:Gem::Version
148
145
  version: 0.12.0
146
+ - - "~>"
147
+ - !ruby/object:Gem::Version
148
+ version: '0.12'
149
149
  type: :development
150
150
  prerelease: false
151
151
  version_requirements: !ruby/object:Gem::Requirement
152
152
  requirements:
153
- - - "~>"
154
- - !ruby/object:Gem::Version
155
- version: '0.12'
156
153
  - - ">="
157
154
  - !ruby/object:Gem::Version
158
155
  version: 0.12.0
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '0.12'
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: bundler
161
161
  requirement: !ruby/object:Gem::Requirement
162
162
  requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: '1.3'
166
163
  - - ">="
167
164
  - !ruby/object:Gem::Version
168
- version: 1.3.0
165
+ version: 2.0.0
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: '2.0'
169
169
  type: :development
170
170
  prerelease: false
171
171
  version_requirements: !ruby/object:Gem::Requirement
172
172
  requirements:
173
- - - "~>"
174
- - !ruby/object:Gem::Version
175
- version: '1.3'
176
173
  - - ">="
177
174
  - !ruby/object:Gem::Version
178
- version: 1.3.0
175
+ version: 2.0.0
176
+ - - "~>"
177
+ - !ruby/object:Gem::Version
178
+ version: '2.0'
179
179
  - !ruby/object:Gem::Dependency
180
180
  name: byebug
181
181
  requirement: !ruby/object:Gem::Requirement
182
182
  requirements:
183
- - - "~>"
184
- - !ruby/object:Gem::Version
185
- version: '9.0'
186
183
  - - ">="
187
184
  - !ruby/object:Gem::Version
188
- version: '8.0'
185
+ version: '10.0'
186
+ - - "~>"
187
+ - !ruby/object:Gem::Version
188
+ version: '11.0'
189
189
  type: :development
190
190
  prerelease: false
191
191
  version_requirements: !ruby/object:Gem::Requirement
192
192
  requirements:
193
- - - "~>"
194
- - !ruby/object:Gem::Version
195
- version: '9.0'
196
193
  - - ">="
197
194
  - !ruby/object:Gem::Version
198
- version: '8.0'
195
+ version: '10.0'
196
+ - - "~>"
197
+ - !ruby/object:Gem::Version
198
+ version: '11.0'
199
199
  - !ruby/object:Gem::Dependency
200
200
  name: cucumber
201
201
  requirement: !ruby/object:Gem::Requirement
202
202
  requirements:
203
- - - "~>"
204
- - !ruby/object:Gem::Version
205
- version: '3.0'
206
203
  - - ">="
207
204
  - !ruby/object:Gem::Version
208
205
  version: 2.2.0
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '3.0'
209
209
  type: :development
210
210
  prerelease: false
211
211
  version_requirements: !ruby/object:Gem::Requirement
212
212
  requirements:
213
- - - "~>"
214
- - !ruby/object:Gem::Version
215
- version: '3.0'
216
213
  - - ">="
217
214
  - !ruby/object:Gem::Version
218
215
  version: 2.2.0
216
+ - - "~>"
217
+ - !ruby/object:Gem::Version
218
+ version: '3.0'
219
219
  - !ruby/object:Gem::Dependency
220
220
  name: diff-lcs
221
221
  requirement: !ruby/object:Gem::Requirement
@@ -234,110 +234,116 @@ dependencies:
234
234
  name: fakefs
235
235
  requirement: !ruby/object:Gem::Requirement
236
236
  requirements:
237
- - - "~>"
238
- - !ruby/object:Gem::Version
239
- version: '0.10'
240
237
  - - ">="
241
238
  - !ruby/object:Gem::Version
242
239
  version: 0.10.0
240
+ - - "~>"
241
+ - !ruby/object:Gem::Version
242
+ version: '0.10'
243
243
  type: :development
244
244
  prerelease: false
245
245
  version_requirements: !ruby/object:Gem::Requirement
246
246
  requirements:
247
- - - "~>"
248
- - !ruby/object:Gem::Version
249
- version: '0.10'
250
247
  - - ">="
251
248
  - !ruby/object:Gem::Version
252
249
  version: 0.10.0
250
+ - - "~>"
251
+ - !ruby/object:Gem::Version
252
+ version: '0.10'
253
253
  - !ruby/object:Gem::Dependency
254
254
  name: minitest
255
255
  requirement: !ruby/object:Gem::Requirement
256
256
  requirements:
257
- - - "~>"
258
- - !ruby/object:Gem::Version
259
- version: '5.3'
260
257
  - - ">="
261
258
  - !ruby/object:Gem::Version
262
259
  version: 5.3.0
260
+ - - "~>"
261
+ - !ruby/object:Gem::Version
262
+ version: '5.3'
263
263
  type: :development
264
264
  prerelease: false
265
265
  version_requirements: !ruby/object:Gem::Requirement
266
266
  requirements:
267
- - - "~>"
268
- - !ruby/object:Gem::Version
269
- version: '5.3'
270
267
  - - ">="
271
268
  - !ruby/object:Gem::Version
272
269
  version: 5.3.0
270
+ - - "~>"
271
+ - !ruby/object:Gem::Version
272
+ version: '5.3'
273
273
  - !ruby/object:Gem::Dependency
274
274
  name: minitest-around
275
275
  requirement: !ruby/object:Gem::Requirement
276
276
  requirements:
277
- - - "~>"
277
+ - - ">="
278
278
  - !ruby/object:Gem::Version
279
279
  version: 0.4.0
280
+ - - "~>"
281
+ - !ruby/object:Gem::Version
282
+ version: 0.5.0
280
283
  type: :development
281
284
  prerelease: false
282
285
  version_requirements: !ruby/object:Gem::Requirement
283
286
  requirements:
284
- - - "~>"
287
+ - - ">="
285
288
  - !ruby/object:Gem::Version
286
289
  version: 0.4.0
290
+ - - "~>"
291
+ - !ruby/object:Gem::Version
292
+ version: 0.5.0
287
293
  - !ruby/object:Gem::Dependency
288
294
  name: mocha
289
295
  requirement: !ruby/object:Gem::Requirement
290
296
  requirements:
291
- - - "~>"
292
- - !ruby/object:Gem::Version
293
- version: '1.1'
294
297
  - - ">="
295
298
  - !ruby/object:Gem::Version
296
299
  version: 1.1.0
300
+ - - "~>"
301
+ - !ruby/object:Gem::Version
302
+ version: '1.1'
297
303
  type: :development
298
304
  prerelease: false
299
305
  version_requirements: !ruby/object:Gem::Requirement
300
306
  requirements:
301
- - - "~>"
302
- - !ruby/object:Gem::Version
303
- version: '1.1'
304
307
  - - ">="
305
308
  - !ruby/object:Gem::Version
306
309
  version: 1.1.0
310
+ - - "~>"
311
+ - !ruby/object:Gem::Version
312
+ version: '1.1'
307
313
  - !ruby/object:Gem::Dependency
308
314
  name: rake
309
315
  requirement: !ruby/object:Gem::Requirement
310
316
  requirements:
311
- - - "~>"
312
- - !ruby/object:Gem::Version
313
- version: '12.0'
314
317
  - - ">="
315
318
  - !ruby/object:Gem::Version
316
319
  version: 11.0.0
320
+ - - "~>"
321
+ - !ruby/object:Gem::Version
322
+ version: '12.0'
317
323
  type: :development
318
324
  prerelease: false
319
325
  version_requirements: !ruby/object:Gem::Requirement
320
326
  requirements:
321
- - - "~>"
322
- - !ruby/object:Gem::Version
323
- version: '12.0'
324
327
  - - ">="
325
328
  - !ruby/object:Gem::Version
326
329
  version: 11.0.0
330
+ - - "~>"
331
+ - !ruby/object:Gem::Version
332
+ version: '12.0'
327
333
  - !ruby/object:Gem::Dependency
328
334
  name: rubocop
329
335
  requirement: !ruby/object:Gem::Requirement
330
336
  requirements:
331
337
  - - "~>"
332
338
  - !ruby/object:Gem::Version
333
- version: 0.53.0
339
+ version: 0.65.0
334
340
  type: :development
335
341
  prerelease: false
336
342
  version_requirements: !ruby/object:Gem::Requirement
337
343
  requirements:
338
344
  - - "~>"
339
345
  - !ruby/object:Gem::Version
340
- version: 0.53.0
346
+ version: 0.65.0
341
347
  description: RubyCritic is a tool that wraps around various static analysis gems to
342
348
  provide a quality report of your Ruby code.
343
349
  email:
@@ -374,6 +380,8 @@ files:
374
380
  - lib/rubycritic/browser.rb
375
381
  - lib/rubycritic/cli/application.rb
376
382
  - lib/rubycritic/cli/options.rb
383
+ - lib/rubycritic/cli/options/argv.rb
384
+ - lib/rubycritic/cli/options/file.rb
377
385
  - lib/rubycritic/colorize.rb
378
386
  - lib/rubycritic/command_factory.rb
379
387
  - lib/rubycritic/commands/base.rb
@@ -467,15 +475,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
467
475
  requirements:
468
476
  - - ">="
469
477
  - !ruby/object:Gem::Version
470
- version: 2.1.0
478
+ version: 2.3.0
471
479
  required_rubygems_version: !ruby/object:Gem::Requirement
472
480
  requirements:
473
481
  - - ">="
474
482
  - !ruby/object:Gem::Version
475
483
  version: '0'
476
484
  requirements: []
477
- rubyforge_project:
478
- rubygems_version: 2.7.6
485
+ rubygems_version: 3.0.2
479
486
  signing_key:
480
487
  specification_version: 4
481
488
  summary: RubyCritic is a Ruby code quality reporter