cuke_linter 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae22f6f11409b8b44b14680f1b4134e2deda49a8deca6a92ac78798f33588cd1
4
- data.tar.gz: 443760f17fa6d22ba14c5264e0a26b3f71661afbb703505e9ca257cb3d677cfe
3
+ metadata.gz: cda526ecd0ab5cab7e5a1a588c5052cc9b15ca0779239289b043b5b0aa7160fa
4
+ data.tar.gz: 2a1b1eb4ad68db07f1b8deee8bee8614e1b5fb1048971ae6580e08d544c88424
5
5
  SHA512:
6
- metadata.gz: 72af3e32ba1ee0a0c4b7b6dd939293b708f4e726e1858d43651d14aa3da8ba0266a4d8d0e6b1b6edd213c24a291c5adc601c736134cf6d1537811276ac29a67d
7
- data.tar.gz: 583835b3d2f300f9d960711135aef2c5039062328bb5ba218cad1d37fae71c5dcdce5cc1394f6771281e09fbe740683822b98a5aecdd46c3ce843f12bc9d48dc
6
+ metadata.gz: be54da9ed9d7571302954de93506194b13b605790bcd140c421f00f70af02070b01e6c9af4cf1d51ceaa3b699b967ad60327fb06c85c6bf6cd2b993a26400381
7
+ data.tar.gz: b004e3c98632a9d510b828a238de24460c76201dc659ef780e98606225749b9feeb1568546ed1e9eda218a63e17873594bef8c2301cfa2886b03ddf733e6e855
@@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  Nothing yet...
10
10
 
11
+ ## [1.0.1] - 2020-05-06
12
+
13
+ ### Fixed
14
+ - Replaced some code that was not valid with earlier versions of Ruby 2.x, with which this gem is specified as being compatible.
15
+
11
16
 
12
17
  ## [1.0.0] - 2020-03-09
13
18
 
@@ -154,7 +159,8 @@ Nothing yet...
154
159
  - Custom linters, formatters, and command line usability
155
160
 
156
161
 
157
- [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v1.0.0...HEAD
162
+ [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v1.0.1...HEAD
163
+ [1.0.1]: https://github.com/enkessler/cuke_linter/compare/v1.0.0...v1.0.1
158
164
  [1.0.0]: https://github.com/enkessler/cuke_linter/compare/v0.13.0...v1.0.0
159
165
  [0.13.0]: https://github.com/enkessler/cuke_linter/compare/v0.12.1...v0.13.0
160
166
  [0.12.1]: https://github.com/enkessler/cuke_linter/compare/v0.12.0...v0.12.1
data/README.md CHANGED
@@ -104,7 +104,8 @@ class MyCustomLinter
104
104
  return nil unless model.is_a?(CukeModeler::Scenario)
105
105
 
106
106
  if model.name.empty?
107
- { problem: 'Scenario has no name', location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }
107
+ { problem: 'Scenario has no name',
108
+ location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }
108
109
  else
109
110
  nil
110
111
  end
@@ -134,13 +135,16 @@ output_path = "#{__dir__}/my_report.txt"
134
135
  model_tree_root = CukeModeler::Directory.new(Dir.pwd)
135
136
  additional_file_path = 'path/to/some.feature'
136
137
 
137
- # Providing the formatter twice so that it also is printed to the console
138
- CukeLinter.lint(linters: [linter], formatters: [[formatter], [formatter, output_path]], model_trees: [model_tree_root], file_paths: [additional_file_path])
138
+ # Providing the formatter twice so that output also is printed to the console
139
+ CukeLinter.lint(linters: [linter],
140
+ formatters: [[formatter], [formatter, output_path]],
141
+ model_trees: [model_tree_root],
142
+ file_paths: [additional_file_path])
139
143
  ```
140
144
 
141
145
  ### Configuration
142
146
 
143
- Rather than using the default linters or providing a custom set of of modified linters every time linting occurs, which linters to use and any linter specific modifications can be configured in a more static manner via a configuration file or setting the configuration directly in code. See [documentation](#documentation) for specifics.
147
+ Rather than using the default linters or providing a custom set of of modified linters every time linting occurs, which linters to use and any linter specific modifications (such as choosing a non-default dialect) can be configured in a more static manner via a configuration file or setting the configuration directly in code. See [documentation](#documentation) for specifics.
144
148
 
145
149
 
146
150
  ### <a id="documentation"></a>Everything Else
@@ -1,40 +1,44 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "cuke_linter/version"
3
+ require 'cuke_linter/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "cuke_linter"
6
+ spec.name = 'cuke_linter'
8
7
  spec.version = CukeLinter::VERSION
9
- spec.authors = ["Eric Kessler"]
10
- spec.email = ["morrow748@gmail.com"]
8
+ spec.authors = ['Eric Kessler']
9
+ spec.email = ['morrow748@gmail.com']
11
10
 
12
- spec.summary = %q{Lints feature files used by Cucumber and other similar frameworks.}
11
+ spec.summary = 'Lints feature files used by Cucumber and other similar frameworks.'
13
12
  spec.homepage = 'https://github.com/enkessler/cuke_linter'
14
- spec.license = "MIT"
13
+ spec.license = 'MIT'
15
14
 
16
15
 
17
16
  # Specify which files should be added to the gem when it is released.
18
17
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ spec.files = Dir.chdir(File.expand_path('', __dir__)) do
20
19
  source_controlled_files = `git ls-files -z`.split("\x0")
21
- source_controlled_files.keep_if { |file| file =~ %r{^(lib|exe|testing/cucumber/features)} } + ['README.md', 'LICENSE.txt', 'CHANGELOG.md', 'cuke_linter.gemspec']
20
+ source_controlled_files.keep_if { |file| file =~ %r{^(lib|exe|testing/cucumber/features)} }
21
+ source_controlled_files + ['README.md', 'LICENSE.txt', 'CHANGELOG.md', 'cuke_linter.gemspec']
22
22
  end
23
- spec.bindir = "exe"
23
+ spec.bindir = 'exe'
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
- spec.require_paths = ["lib"]
25
+ spec.require_paths = ['lib']
26
26
 
27
27
  spec.required_ruby_version = '~> 2.0'
28
28
 
29
29
  spec.add_runtime_dependency 'cuke_modeler', '>= 1.5', '< 3.0'
30
30
 
31
- spec.add_development_dependency "bundler", "< 3.0"
32
- spec.add_development_dependency "cucumber", "~> 3.0"
33
- spec.add_development_dependency "racatt", "~> 1.0"
34
- spec.add_development_dependency "rake", "~> 12.0"
35
- spec.add_development_dependency "require_all", "~> 2.0"
36
- spec.add_development_dependency "rspec", "~> 3.0"
37
- spec.add_development_dependency 'simplecov', '< 1.0.0'
31
+ spec.add_development_dependency 'bundler', '< 3.0'
32
+ spec.add_development_dependency 'childprocess', '~> 3.0'
38
33
  spec.add_development_dependency 'coveralls', '< 1.0.0'
34
+ spec.add_development_dependency 'cucumber', '~> 3.0'
35
+ spec.add_development_dependency 'cuke_slicer', '>= 2.0.2', '< 3.0'
36
+ spec.add_development_dependency 'ffi', '~> 1.0'
37
+ spec.add_development_dependency 'parallel', '~> 1.0'
39
38
  spec.add_development_dependency 'rainbow', '< 4.0.0'
39
+ spec.add_development_dependency 'rake', '~> 12.0'
40
+ spec.add_development_dependency 'require_all', '~> 2.0'
41
+ spec.add_development_dependency 'rspec', '~> 3.0'
42
+ spec.add_development_dependency 'rubocop', '< 1.0.0'
43
+ spec.add_development_dependency 'simplecov', '< 1.0.0'
40
44
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "cuke_linter"
3
+ require 'cuke_linter'
4
4
  require 'optparse'
5
5
 
6
6
  params = {}
@@ -9,6 +9,7 @@ params[:formatters] = []
9
9
  params[:outs] = []
10
10
  params[:requires] = []
11
11
 
12
+ # rubocop:disable Metrics/BlockLength
12
13
  parser = OptionParser.new do |options|
13
14
 
14
15
  options.set_summary_width(30)
@@ -68,6 +69,7 @@ parser = OptionParser.new do |options|
68
69
  end
69
70
 
70
71
  end
72
+ # rubocop:enable Metrics/BlockLength
71
73
 
72
74
  begin
73
75
  parser.parse!
@@ -1,7 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'cuke_modeler'
3
3
 
4
- require "cuke_linter/version"
4
+ require 'cuke_linter/version'
5
5
  require 'cuke_linter/formatters/pretty_formatter'
6
6
  require 'cuke_linter/linters/linter'
7
7
  require 'cuke_linter/linters/background_does_more_than_setup_linter'
@@ -29,233 +29,170 @@ require 'cuke_linter/linters/test_with_setup_step_after_action_step_linter'
29
29
  require 'cuke_linter/linters/test_with_setup_step_after_verification_step_linter'
30
30
  require 'cuke_linter/linters/test_with_setup_step_as_final_step_linter'
31
31
  require 'cuke_linter/linters/test_with_too_many_steps_linter'
32
+ require 'cuke_linter/configuration'
33
+ require 'cuke_linter/default_linters'
34
+ require 'cuke_linter/gherkin'
35
+ require 'cuke_linter/linter_registration'
32
36
 
33
37
 
34
38
  # The top level namespace used by this gem
35
-
36
39
  module CukeLinter
37
40
 
38
- # The default keyword that is considered a 'Given' keyword
39
- DEFAULT_GIVEN_KEYWORD = 'Given'.freeze
40
- # The default keyword that is considered a 'When' keyword
41
- DEFAULT_WHEN_KEYWORD = 'When'.freeze
42
- # The default keyword that is considered a 'Then' keyword
43
- DEFAULT_THEN_KEYWORD = 'Then'.freeze
44
-
45
- @original_linters = { 'BackgroundDoesMoreThanSetupLinter' => BackgroundDoesMoreThanSetupLinter.new,
46
- 'ElementWithCommonTagsLinter' => ElementWithCommonTagsLinter.new,
47
- 'ElementWithDuplicateTagsLinter' => ElementWithDuplicateTagsLinter.new,
48
- 'ElementWithTooManyTagsLinter' => ElementWithTooManyTagsLinter.new,
49
- 'ExampleWithoutNameLinter' => ExampleWithoutNameLinter.new,
50
- 'FeatureFileWithInvalidNameLinter' => FeatureFileWithInvalidNameLinter.new,
51
- 'FeatureFileWithMismatchedNameLinter' => FeatureFileWithMismatchedNameLinter.new,
52
- 'FeatureWithTooManyDifferentTagsLinter' => FeatureWithTooManyDifferentTagsLinter.new,
53
- 'FeatureWithoutDescriptionLinter' => FeatureWithoutDescriptionLinter.new,
54
- 'FeatureWithoutNameLinter' => FeatureWithoutNameLinter.new,
55
- 'FeatureWithoutScenariosLinter' => FeatureWithoutScenariosLinter.new,
56
- 'OutlineWithSingleExampleRowLinter' => OutlineWithSingleExampleRowLinter.new,
57
- 'SingleTestBackgroundLinter' => SingleTestBackgroundLinter.new,
58
- 'StepWithEndPeriodLinter' => StepWithEndPeriodLinter.new,
59
- 'StepWithTooManyCharactersLinter' => StepWithTooManyCharactersLinter.new,
60
- 'TestShouldUseBackgroundLinter' => TestShouldUseBackgroundLinter.new,
61
- 'TestWithActionStepAsFinalStepLinter' => TestWithActionStepAsFinalStepLinter.new,
62
- 'TestWithBadNameLinter' => TestWithBadNameLinter.new,
63
- 'TestWithNoActionStepLinter' => TestWithNoActionStepLinter.new,
64
- 'TestWithNoNameLinter' => TestWithNoNameLinter.new,
65
- 'TestWithNoVerificationStepLinter' => TestWithNoVerificationStepLinter.new,
66
- 'TestWithSetupStepAfterActionStepLinter' => TestWithSetupStepAfterActionStepLinter.new,
67
- 'TestWithSetupStepAfterVerificationStepLinter' => TestWithSetupStepAfterVerificationStepLinter.new,
68
- 'TestWithSetupStepAsFinalStepLinter' => TestWithSetupStepAsFinalStepLinter.new,
69
- 'TestWithTooManyStepsLinter' => TestWithTooManyStepsLinter.new }
70
-
71
-
72
- # Configures linters based on the given options
73
- def self.load_configuration(config_file_path: nil, config: nil)
74
- # TODO: define what happens if both a configuration file and a configuration are provided. Merge them or have direct config take precedence? Both?
75
-
76
- unless config || config_file_path
77
- config_file_path = "#{Dir.pwd}/.cuke_linter"
78
- raise 'No configuration or configuration file given and no .cuke_linter file found' unless File.exist?(config_file_path)
79
- end
80
-
81
- config = config || YAML.load_file(config_file_path)
41
+ extend CukeLinter::Configuration
42
+ extend CukeLinter::LinterRegistration
82
43
 
83
- common_config = config['AllLinters'] || {}
84
- to_delete = []
44
+ class << self
85
45
 
86
- registered_linters.each_pair do |name, linter|
87
- linter_config = config[name] || {}
88
- final_config = common_config.merge(linter_config)
46
+ # Lints the given model trees and file paths using the given linting objects and formatting
47
+ # the results with the given formatters and their respective output locations
48
+ def lint(file_paths: [], model_trees: [], linters: registered_linters.values, formatters: [[CukeLinter::PrettyFormatter.new]]) # rubocop:disable Metrics/LineLength
49
+ # TODO: Test this?
50
+ # Because directive memoization is based on a model's `#object_id` and Ruby reuses object IDs over the
51
+ # life of a program as objects are garbage collected, it is not safe to remember the IDs forever. However,
52
+ # models shouldn't get GC'd in the middle of the linting process and so the start of the linting process is
53
+ # a good time to reset things
54
+ @directives_for_feature_file = {}
89
55
 
90
- disabled = (final_config.key?('Enabled') && !final_config['Enabled'])
56
+ model_trees = [CukeModeler::Directory.new(Dir.pwd)] if model_trees.empty? && file_paths.empty?
57
+ file_path_models = collect_file_path_models(file_paths)
58
+ model_sets = model_trees + file_path_models
91
59
 
92
- # Just save it for afterwards because modifying a collection while iterating through it is not a good idea
93
- to_delete << name if disabled
60
+ linting_data = lint_models(model_sets, linters)
61
+ format_data(formatters, linting_data)
94
62
 
95
- linter.configure(final_config) if linter.respond_to?(:configure)
63
+ linting_data
96
64
  end
97
65
 
98
- to_delete.each { |linter_name| unregister_linter(linter_name) }
99
- end
100
-
101
- # Returns the registered linters to their default state
102
- def self.reset_linters
103
- @registered_linters = nil
104
- end
105
-
106
- # Registers for linting use the given linter object, tracked by the given name
107
- def self.register_linter(linter:, name:)
108
- self.registered_linters[name] = linter
109
- end
110
-
111
- # Unregisters the linter object tracked by the given name so that it is not used for linting
112
- def self.unregister_linter(name)
113
- self.registered_linters.delete(name)
114
- end
115
66
 
116
- # Lists the names of the currently registered linting objects
117
- def self.registered_linters
118
- @registered_linters ||= Marshal.load(Marshal.dump(@original_linters))
119
- end
67
+ private
120
68
 
121
- # Unregisters all currently registered linting objects
122
- def self.clear_registered_linters
123
- self.registered_linters.clear
124
- end
125
69
 
126
- # Lints the given model trees and file paths using the given linting objects and formatting the results with the given formatters and their respective output locations
127
- def self.lint(file_paths: [], model_trees: [], linters: self.registered_linters.values, formatters: [[CukeLinter::PrettyFormatter.new]])
128
-
129
- # TODO: Test this?
130
- # Because directive memoization is based on a model's `#object_id` and Ruby reuses object IDs over the
131
- # life of a program as objects are garbage collected, it is not safe to remember the IDs forever. However,
132
- # models shouldn't get GC'd in the middle of the linting process and so the start of the linting process is
133
- # a good time to reset things
134
- @directives_for_feature_file = {}
135
-
136
- model_trees = [CukeModeler::Directory.new(Dir.pwd)] if model_trees.empty? && file_paths.empty?
137
- file_path_models = file_paths.collect do |file_path|
138
- # TODO: raise exception unless path exists?
139
- case
140
- when File.directory?(file_path)
70
+ def collect_file_path_models(file_paths)
71
+ file_paths.collect do |file_path|
72
+ # TODO: raise exception unless path exists?
73
+ if File.directory?(file_path)
141
74
  CukeModeler::Directory.new(file_path)
142
- when File.file?(file_path) && File.extname(file_path) == '.feature'
75
+ elsif File.file?(file_path) && File.extname(file_path) == '.feature'
143
76
  CukeModeler::FeatureFile.new(file_path)
144
- else
145
- # Non-feature files are not modeled
146
- end
147
- end.compact # Compacting in order to get rid of any `nil` values left over from non-feature files
148
-
149
- linting_data = []
150
- model_sets = model_trees + file_path_models
151
-
152
- model_sets.each do |model_tree|
153
- model_tree.each_model do |model|
154
- applicable_linters = relevant_linters_for_model(linters, model)
155
- applicable_linters.each do |linter|
156
- # TODO: have linters lint only certain types of models?
157
- # linting_data.concat(linter.lint(model)) if relevant_model?(linter, model)
158
-
159
- result = linter.lint(model)
160
-
161
- if result
162
- result[:linter] = linter.name
163
- linting_data << result
164
- end
165
77
  end
166
- end
78
+ end.compact # Compacting in order to get rid of any `nil` values left over from non-feature files
167
79
  end
168
80
 
169
- formatters.each do |formatter_output_pair|
170
- formatter = formatter_output_pair[0]
171
- location = formatter_output_pair[1]
172
-
173
- formatted_data = formatter.format(linting_data)
174
-
175
- if location
176
- File.write(location, formatted_data)
177
- else
178
- puts formatted_data
81
+ def lint_models(model_sets, linters)
82
+ [].tap do |linting_data|
83
+ model_sets.each do |model_tree|
84
+ model_tree.each_model do |model|
85
+ applicable_linters = relevant_linters_for_model(linters, model)
86
+ applicable_linters.each do |linter|
87
+ # TODO: have linters lint only certain types of models?
88
+ # linting_data.concat(linter.lint(model)) if relevant_model?(linter, model)
89
+
90
+ result = linter.lint(model)
91
+
92
+ if result
93
+ result[:linter] = linter.name
94
+ linting_data << result
95
+ end
96
+ end
97
+ end
98
+ end
179
99
  end
180
100
  end
181
101
 
182
- linting_data
183
- end
102
+ def relevant_linters_for_model(base_linters, model)
103
+ feature_file_model = model.get_ancestor(:feature_file)
184
104
 
105
+ # Linter directives are not applicable for directory and feature file models. Every other
106
+ # model type should have a feature file ancestor from which to grab linter directive comments.
107
+ return base_linters if feature_file_model.nil?
185
108
 
186
- def self.relevant_linters_for_model(base_linters, model)
187
- feature_file_model = model.get_ancestor(:feature_file)
109
+ linter_modifications_for_model = {}
188
110
 
189
- # Linter directives are not applicable for directory and feature file models. Every other model type should have a feature file ancestor from which to grab linter directive comments.
190
- return base_linters if feature_file_model.nil?
111
+ linter_directives_for_feature_file(feature_file_model).each do |directive|
112
+ # Assuming that the directives are in the same order that they appear in the file
113
+ break if directive[:source_line] > model.source_line
191
114
 
192
- linter_modifications_for_model = {}
115
+ linter_modifications_for_model[directive[:linter_class]] = directive[:enabled_status]
116
+ end
193
117
 
194
- linter_directives_for_feature_file(feature_file_model).each do |directive|
195
- # Assuming that the directives are in the same order that they appear in the file
196
- break if directive[:source_line] > model.source_line
118
+ disabled_linter_classes = linter_modifications_for_model.reject { |_name, status| status }.keys
119
+ enabled_linter_classes = linter_modifications_for_model.select { |_name, status| status }.keys
197
120
 
198
- linter_modifications_for_model[directive[:linter_class]] = directive[:enabled_status]
121
+ determine_final_linters(base_linters, disabled_linter_classes, enabled_linter_classes)
199
122
  end
200
123
 
201
- disabled_linter_classes = linter_modifications_for_model.reject { |_name, status| status }.keys
202
- enabled_linter_classes = linter_modifications_for_model.select { |_name, status| status }.keys
124
+ def determine_final_linters(base_linters, disabled_linter_classes, enabled_linter_classes)
125
+ final_linters = base_linters.reject { |linter| disabled_linter_classes.include?(linter.class) }
203
126
 
204
- final_linters = base_linters.reject { |linter| disabled_linter_classes.include?(linter.class) }
205
- enabled_linter_classes.each do |clazz|
206
- final_linters << dynamic_linters[clazz] unless final_linters.map(&:class).include?(clazz)
207
- end
208
-
209
- final_linters
210
- end
127
+ enabled_linter_classes.each do |clazz|
128
+ final_linters << dynamic_linters[clazz] unless final_linters.map(&:class).include?(clazz)
129
+ end
211
130
 
212
- private_class_method(:relevant_linters_for_model)
131
+ final_linters
132
+ end
213
133
 
134
+ def linter_directives_for_feature_file(feature_file_model)
135
+ # IMPORTANT ASSUMPTION: Models never change during the life of a linting, so data only has to be gathered once
136
+ existing_directives = @directives_for_feature_file[feature_file_model.object_id]
214
137
 
215
- def self.linter_directives_for_feature_file(feature_file_model)
216
- # IMPORTANT ASSUMPTION: Models never change during the life of a linting, so data only has to be gathered once
217
- return @directives_for_feature_file[feature_file_model.object_id] if @directives_for_feature_file[feature_file_model.object_id]
138
+ return existing_directives if existing_directives
218
139
 
140
+ directives = gather_directives_in_feature(feature_file_model)
219
141
 
220
- @directives_for_feature_file[feature_file_model.object_id] = []
142
+ # Make sure that the directives are in the same order as they appear in the source file
143
+ directives = directives.sort_by { |a| a[:source_line] }
221
144
 
222
- feature_file_model.comments.each do |comment|
223
- pieces = comment.text.match(/#\s*cuke_linter:(disable|enable)\s+(.*)/)
224
- next unless pieces # Skipping non-directive file comments
145
+ @directives_for_feature_file[feature_file_model.object_id] = directives
146
+ end
225
147
 
226
- linter_classes = pieces[2].gsub(',', ' ').split(' ')
227
- linter_classes.each do |clazz|
228
- @directives_for_feature_file[feature_file_model.object_id] << { linter_class: Kernel.const_get(clazz),
229
- enabled_status: pieces[1] != 'disable',
230
- source_line: comment.source_line }
148
+ def gather_directives_in_feature(feature_file_model)
149
+ [].tap do |directives|
150
+ feature_file_model.comments.each do |comment|
151
+ pieces = comment.text.match(/#\s*cuke_linter:(disable|enable)\s+(.*)/)
152
+ next unless pieces # Skipping non-directive file comments
153
+
154
+ linter_classes = pieces[2].tr(',', ' ').split(' ')
155
+ linter_classes.each do |clazz|
156
+ directives << { linter_class: Kernel.const_get(clazz),
157
+ enabled_status: pieces[1] != 'disable',
158
+ source_line: comment.source_line }
159
+ end
160
+ end
231
161
  end
232
162
  end
233
163
 
234
- # Make sure that the directives are in the same order as they appear in the source file
235
- @directives_for_feature_file[feature_file_model.object_id] = @directives_for_feature_file[feature_file_model.object_id].sort { |a, b| a[:source_line] <=> b[:source_line] }
164
+ def dynamic_linters
165
+ # No need to keep making new ones over and over...
166
+ @dynamic_linters ||= Hash.new { |hash, key| hash[key] = key.new }
167
+ # return @dynamic_linters if @dynamic_linters
168
+ #
169
+ # @dynamic_linters = {}
170
+ end
236
171
 
172
+ def format_data(formatters, linting_data)
173
+ formatters.each do |formatter_output_pair|
174
+ formatter = formatter_output_pair[0]
175
+ location = formatter_output_pair[1]
237
176
 
238
- @directives_for_feature_file[feature_file_model.object_id]
239
- end
177
+ formatted_data = formatter.format(linting_data)
240
178
 
241
- private_class_method(:linter_directives_for_feature_file)
179
+ if location
180
+ File.write(location, formatted_data)
181
+ else
182
+ puts formatted_data
183
+ end
184
+ end
185
+ end
242
186
 
243
- def self.dynamic_linters
244
- # No need to keep making new ones over and over...
245
- @dynamic_linters ||= Hash.new { |hash, key| hash[key] = key.new }
246
- # return @dynamic_linters if @dynamic_linters
187
+ # Not linting unused code
188
+ # rubocop:disable Metrics/LineLength
189
+ # def self.relevant_model?(linter, model)
190
+ # model_classes = linter.class.target_model_types.map { |type| CukeModeler.const_get(type.to_s.capitalize.chop) }
191
+ # model_classes.any? { |clazz| model.is_a?(clazz) }
192
+ # end
247
193
  #
248
- # @dynamic_linters = {}
249
- end
250
-
251
- private_class_method(:dynamic_linters)
252
-
253
-
254
- # # def self.relevant_model?(linter, model)
255
- # # model_classes = linter.class.target_model_types.map { |type| CukeModeler.const_get(type.to_s.capitalize.chop) }
256
- # # model_classes.any? { |clazz| model.is_a?(clazz) }
257
- # # end
258
- # #
259
- # # private_class_method(:relevant_model?)
194
+ # private_class_method(:relevant_model?)
195
+ # rubocop:enable Metrics/LineLength
260
196
 
197
+ end
261
198
  end