haml_lint 0.52.0 → 0.54.0
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/lib/haml_lint/adapter.rb +0 -2
- data/lib/haml_lint/constants.rb +1 -1
- data/lib/haml_lint/directive.rb +2 -2
- data/lib/haml_lint/document.rb +10 -1
- data/lib/haml_lint/linter/alignment_tabs.rb +1 -1
- data/lib/haml_lint/linter/class_attribute_with_static_value.rb +1 -1
- data/lib/haml_lint/linter/indentation.rb +1 -1
- data/lib/haml_lint/linter/multiline_pipe.rb +1 -1
- data/lib/haml_lint/linter/no_placeholders.rb +2 -2
- data/lib/haml_lint/options.rb +8 -2
- data/lib/haml_lint/ruby_extraction/chunk_extractor.rb +28 -0
- data/lib/haml_lint/runner.rb +39 -29
- data/lib/haml_lint/source.rb +24 -0
- data/lib/haml_lint/version.rb +1 -1
- metadata +7 -7
- data/lib/haml_lint/adapter/haml_4.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b017823b15563d033480ee99317c4d0c007624b10ad2ed3b53c254c5686289c8
|
4
|
+
data.tar.gz: cf83ac415fb7749551466fcc0b23a5a2019bbecb99a67b2c54051a78523f1a33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17ea23cce399f12712d0f73560553b82068e2ac3be9124c590bbea78948a330811402c15fd2b5f8cbc0b5e8e044bc044e69df78f2e05462580665db814298595
|
7
|
+
data.tar.gz: d619d3018e139b00ce539da9b9f7e1bfef644c71c8e102d146778c3c322770458a16feb89bb44a1a3699eadacc6038c7186407fc8361e6b354f0c4bdbb2dcd57
|
data/lib/haml_lint/adapter.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'haml_lint/adapter/haml_4'
|
4
3
|
require 'haml_lint/adapter/haml_5'
|
5
4
|
require 'haml_lint/adapter/haml_6'
|
6
5
|
require 'haml_lint/exceptions'
|
@@ -19,7 +18,6 @@ module HamlLint
|
|
19
18
|
def self.detect_class
|
20
19
|
version = haml_version
|
21
20
|
case version
|
22
|
-
when '~> 4.0' then HamlLint::Adapter::Haml4
|
23
21
|
when '~> 5.0', '~> 5.1', '~> 5.2' then HamlLint::Adapter::Haml5
|
24
22
|
when '~> 6.0', '~> 6.0.a', '~> 6.1', '~> 6.2', '~> 6.3' then HamlLint::Adapter::Haml6
|
25
23
|
else fail HamlLint::Exceptions::UnknownHamlVersion, "Cannot handle Haml version: #{version}"
|
data/lib/haml_lint/constants.rb
CHANGED
data/lib/haml_lint/directive.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module HamlLint
|
4
4
|
# Handles linter configuration transformation via Haml comments.
|
5
5
|
class Directive
|
6
|
-
LINTER_REGEXP = /(?:[A-Z]\w+)
|
6
|
+
LINTER_REGEXP = /(?:[A-Z]\w+)/
|
7
7
|
|
8
8
|
DIRECTIVE_REGEXP = /
|
9
9
|
# "haml-lint:" with optional spacing
|
@@ -14,7 +14,7 @@ module HamlLint
|
|
14
14
|
|
15
15
|
# "all" or a comma-separated list (with optional spaces) of linters
|
16
16
|
(?<linters>all | (?:#{LINTER_REGEXP}\s*,\s*)* #{LINTER_REGEXP})
|
17
|
-
/x
|
17
|
+
/x
|
18
18
|
|
19
19
|
# Constructs a directive from source code as a given line.
|
20
20
|
#
|
data/lib/haml_lint/document.rb
CHANGED
@@ -14,6 +14,9 @@ module HamlLint
|
|
14
14
|
# @return [String] Haml template file path
|
15
15
|
attr_reader :file
|
16
16
|
|
17
|
+
# @return [Boolean] true if source changes (from autocorrect) should be written to stdout instead of disk
|
18
|
+
attr_reader :write_to_stdout
|
19
|
+
|
17
20
|
# @return [HamlLint::Tree::Node] Root of the parse tree
|
18
21
|
attr_reader :tree
|
19
22
|
|
@@ -36,10 +39,12 @@ module HamlLint
|
|
36
39
|
# @param source [String] Haml code to parse
|
37
40
|
# @param options [Hash]
|
38
41
|
# @option options :file [String] file name of document that was parsed
|
42
|
+
# @option options :write_to_stdout [Boolean] true if source changes should be written to stdout
|
39
43
|
# @raise [Haml::Parser::Error] if there was a problem parsing the document
|
40
44
|
def initialize(source, options)
|
41
45
|
@config = options[:config]
|
42
46
|
@file = options.fetch(:file, STRING_SOURCE)
|
47
|
+
@write_to_stdout = options[:write_to_stdout]
|
43
48
|
@source_was_changed = false
|
44
49
|
process_source(source)
|
45
50
|
end
|
@@ -82,7 +87,11 @@ module HamlLint
|
|
82
87
|
if file == STRING_SOURCE
|
83
88
|
raise HamlLint::Exceptions::InvalidFilePath, 'Cannot write without :file option'
|
84
89
|
end
|
85
|
-
|
90
|
+
if @write_to_stdout
|
91
|
+
$stdout << unstrip_frontmatter(source)
|
92
|
+
else
|
93
|
+
File.write(file, unstrip_frontmatter(source))
|
94
|
+
end
|
86
95
|
@source_was_changed = false
|
87
96
|
end
|
88
97
|
|
@@ -20,7 +20,7 @@ module HamlLint
|
|
20
20
|
|
21
21
|
STATIC_TYPES = %i[str sym].freeze
|
22
22
|
|
23
|
-
VALID_CLASS_REGEX = /^-?[_a-zA-Z]+[_a-zA-Z0-9-]
|
23
|
+
VALID_CLASS_REGEX = /^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$/
|
24
24
|
|
25
25
|
def visit_tag(node)
|
26
26
|
return unless contains_class_attribute?(node.dynamic_attributes_sources)
|
@@ -6,8 +6,8 @@ module HamlLint
|
|
6
6
|
include LinterRegistry
|
7
7
|
|
8
8
|
MSG = 'Placeholders attributes should not be used.'
|
9
|
-
HASH_REGEXP = /:?['"]?placeholder['"]?(?::| *=>)
|
10
|
-
HTML_REGEXP = /placeholder
|
9
|
+
HASH_REGEXP = /:?['"]?placeholder['"]?(?::| *=>)/
|
10
|
+
HTML_REGEXP = /placeholder=/
|
11
11
|
|
12
12
|
def visit_tag(node)
|
13
13
|
return unless node.hash_attributes_source =~ HASH_REGEXP || node.html_attributes_source =~ HTML_REGEXP
|
data/lib/haml_lint/options.rb
CHANGED
@@ -32,7 +32,7 @@ module HamlLint
|
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
def add_linter_options(parser) # rubocop:disable Metrics/MethodLength
|
35
|
+
def add_linter_options(parser) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
36
36
|
parser.on('--auto-gen-config', 'Generate a configuration file acting as a TODO list') do
|
37
37
|
@options[:auto_gen_config] = true
|
38
38
|
end
|
@@ -70,7 +70,13 @@ module HamlLint
|
|
70
70
|
@options[:autocorrect] ||= :safe
|
71
71
|
end
|
72
72
|
|
73
|
-
parser.on('--
|
73
|
+
parser.on('-s', '--stdin FILE', 'Pipe source from STDIN, using FILE in ' \
|
74
|
+
'offense when combined with --auto-correct and --stdin.') do |file_path|
|
75
|
+
@options[:stdin] = file_path
|
76
|
+
end
|
77
|
+
|
78
|
+
parser.on('--stderr', 'Write all output to stderr except for the autocorrected source. ' \
|
79
|
+
'This is especially useful when combined with --auto-correct and --stdin') do
|
74
80
|
@options[:stderr] = true
|
75
81
|
end
|
76
82
|
end
|
@@ -84,7 +84,35 @@ module HamlLint::RubyExtraction
|
|
84
84
|
def visit_comment(node)
|
85
85
|
line = @original_haml_lines[node.line - 1]
|
86
86
|
indent = line.index(/\S/)
|
87
|
+
|
87
88
|
@ruby_chunks << PlaceholderMarkerChunk.new(node, 'comment', indent: indent)
|
89
|
+
|
90
|
+
# Comment can have subnodes, such as plain. This happens for conditional comments, such as:
|
91
|
+
# %head
|
92
|
+
# /[if mso]
|
93
|
+
# %div
|
94
|
+
if node.children
|
95
|
+
# We don't want to use a block because assignments in a block are local to that block,
|
96
|
+
# so the semantics of the extracted ruby would be different from the one generated by
|
97
|
+
# Haml. Those differences can make some cops, such as UselessAssignment, have false
|
98
|
+
# positives
|
99
|
+
begin_chunk = AdHocChunk.new(node, [' ' * indent + 'begin'])
|
100
|
+
@ruby_chunks << begin_chunk
|
101
|
+
indent += 2
|
102
|
+
|
103
|
+
yield
|
104
|
+
|
105
|
+
indent -= 2
|
106
|
+
|
107
|
+
if @ruby_chunks.last.equal?(begin_chunk)
|
108
|
+
# So there is nothing nesting, remove the wrapping "begin"
|
109
|
+
@ruby_chunks.pop
|
110
|
+
else
|
111
|
+
@ruby_chunks << AdHocChunk.new(node,
|
112
|
+
[' ' * indent + 'ensure', ' ' * indent + ' HL.noop', ' ' * indent + 'end'],
|
113
|
+
haml_line_index: @ruby_chunks.last.haml_end_line_index)
|
114
|
+
end
|
115
|
+
end
|
88
116
|
end
|
89
117
|
|
90
118
|
# Visit a script which outputs. Lines looking like ` = foo`
|
data/lib/haml_lint/runner.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'parallel'
|
4
|
+
require_relative 'source'
|
4
5
|
|
5
6
|
module HamlLint
|
6
7
|
# Responsible for running the applicable linters against the desired files.
|
@@ -20,12 +21,13 @@ module HamlLint
|
|
20
21
|
# @return [HamlLint::Report] a summary of all lints found
|
21
22
|
def run(options = {})
|
22
23
|
@config = load_applicable_config(options)
|
23
|
-
@
|
24
|
+
@sources = extract_applicable_sources(config, options)
|
24
25
|
@linter_selector = HamlLint::LinterSelector.new(config, options)
|
25
26
|
@fail_fast = options.fetch(:fail_fast, false)
|
26
27
|
@cache = {}
|
27
28
|
@autocorrect = options[:autocorrect]
|
28
29
|
@autocorrect_only = options[:autocorrect_only]
|
30
|
+
@autocorrect_stdout = options[:stdin] && options[:stderr]
|
29
31
|
|
30
32
|
report(options)
|
31
33
|
end
|
@@ -48,10 +50,10 @@ module HamlLint
|
|
48
50
|
# @return [true, false]
|
49
51
|
alias fail_fast? fail_fast
|
50
52
|
|
51
|
-
# The list of
|
53
|
+
# The list of sources to lint during this run.
|
52
54
|
#
|
53
|
-
# @return [Array<
|
54
|
-
attr_reader :
|
55
|
+
# @return [Array<HamlLint::Source>]
|
56
|
+
attr_reader :sources
|
55
57
|
|
56
58
|
# The selector for which linters to run during this run.
|
57
59
|
#
|
@@ -79,18 +81,20 @@ module HamlLint
|
|
79
81
|
# Runs all provided linters using the specified config against the given
|
80
82
|
# file.
|
81
83
|
#
|
82
|
-
# @param
|
84
|
+
# @param source [HamlLint::Source] source to lint
|
83
85
|
# @param linter_selector [HamlLint::LinterSelector]
|
84
86
|
# @param config [HamlLint::Configuration]
|
85
|
-
def collect_lints(
|
87
|
+
def collect_lints(source, linter_selector, config)
|
86
88
|
begin
|
87
|
-
document = HamlLint::Document.new
|
89
|
+
document = HamlLint::Document.new source.contents, file: source.path,
|
90
|
+
config: config,
|
91
|
+
write_to_stdout: @autocorrect_stdout
|
88
92
|
rescue HamlLint::Exceptions::ParseError => e
|
89
|
-
return [HamlLint::Lint.new(HamlLint::Linter::Syntax.new(config),
|
93
|
+
return [HamlLint::Lint.new(HamlLint::Linter::Syntax.new(config), source.path,
|
90
94
|
e.line, e.to_s, :error)]
|
91
95
|
end
|
92
96
|
|
93
|
-
linters = linter_selector.linters_for_file(
|
97
|
+
linters = linter_selector.linters_for_file(source.path)
|
94
98
|
lint_arrays = []
|
95
99
|
|
96
100
|
if @autocorrect
|
@@ -125,40 +129,46 @@ module HamlLint
|
|
125
129
|
lint_arrays
|
126
130
|
end
|
127
131
|
|
128
|
-
# Returns the list of
|
132
|
+
# Returns the list of sources that should be linted given the specified
|
129
133
|
# configuration and options.
|
130
134
|
#
|
131
135
|
# @param config [HamlLint::Configuration]
|
132
136
|
# @param options [Hash]
|
133
|
-
# @return [Array<
|
134
|
-
def
|
135
|
-
|
136
|
-
|
137
|
-
|
137
|
+
# @return [Array<HamlLint::Source>]
|
138
|
+
def extract_applicable_sources(config, options)
|
139
|
+
if options[:stdin]
|
140
|
+
[HamlLint::Source.new($stdin, options[:stdin])]
|
141
|
+
else
|
142
|
+
included_patterns = options[:files]
|
143
|
+
excluded_patterns = config['exclude']
|
144
|
+
excluded_patterns += options.fetch(:excluded_files, [])
|
138
145
|
|
139
|
-
|
146
|
+
HamlLint::FileFinder.new(config).find(included_patterns, excluded_patterns).map do |file_path|
|
147
|
+
HamlLint::Source.new File.new(file_path), file_path
|
148
|
+
end
|
149
|
+
end
|
140
150
|
end
|
141
151
|
|
142
|
-
# Process the
|
152
|
+
# Process the sources and add them to the given report.
|
143
153
|
#
|
144
154
|
# @param report [HamlLint::Report]
|
145
155
|
# @return [void]
|
146
|
-
def
|
147
|
-
|
148
|
-
|
156
|
+
def process_sources(report)
|
157
|
+
sources.each do |source|
|
158
|
+
process_source(source, report)
|
149
159
|
break if report.failed? && fail_fast?
|
150
160
|
end
|
151
161
|
end
|
152
162
|
|
153
163
|
# Process a file and add it to the given report.
|
154
164
|
#
|
155
|
-
# @param
|
165
|
+
# @param source [HamlLint::Source] the source to process
|
156
166
|
# @param report [HamlLint::Report]
|
157
167
|
# @return [void]
|
158
|
-
def
|
159
|
-
lints = @cache[
|
168
|
+
def process_source(source, report)
|
169
|
+
lints = @cache[source.path] || collect_lints(source, linter_selector, config)
|
160
170
|
lints.each { |lint| report.add_lint(lint) }
|
161
|
-
report.finish_file(
|
171
|
+
report.finish_file(source.path, lints)
|
162
172
|
end
|
163
173
|
|
164
174
|
# Generates a report based on the given options.
|
@@ -168,9 +178,9 @@ module HamlLint
|
|
168
178
|
# @return [HamlLint::Report]
|
169
179
|
def report(options)
|
170
180
|
report = HamlLint::Report.new(reporter: options[:reporter], fail_level: options[:fail_level])
|
171
|
-
report.start(
|
181
|
+
report.start(sources.map(&:path))
|
172
182
|
warm_cache if options[:parallel]
|
173
|
-
|
183
|
+
process_sources(report)
|
174
184
|
report
|
175
185
|
end
|
176
186
|
|
@@ -178,9 +188,9 @@ module HamlLint
|
|
178
188
|
#
|
179
189
|
# @return [void]
|
180
190
|
def warm_cache
|
181
|
-
results = Parallel.map(
|
182
|
-
lints = collect_lints(
|
183
|
-
[
|
191
|
+
results = Parallel.map(sources) do |source|
|
192
|
+
lints = collect_lints(source, linter_selector, config)
|
193
|
+
[source.path, lints]
|
184
194
|
end
|
185
195
|
@cache = results.to_h
|
186
196
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HamlLint
|
4
|
+
# Wrapper class representing a single target for HamlLint::Runner to run against, comprised of an IO object
|
5
|
+
# containing haml code, as well as a file path.
|
6
|
+
class Source
|
7
|
+
# @return [String] File path associated with the given IO object.
|
8
|
+
attr_reader :path
|
9
|
+
|
10
|
+
# Wraps an IO object and file path to a source object.
|
11
|
+
#
|
12
|
+
# @param [IO] io
|
13
|
+
# @param [String] path
|
14
|
+
def initialize(io, path)
|
15
|
+
@io = io
|
16
|
+
@path = path
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [String] Contents of the given IO object.
|
20
|
+
def contents
|
21
|
+
@contents ||= @io.read
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/haml_lint/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml_lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.54.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shane da Silva
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: haml
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: parallel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,7 +93,6 @@ files:
|
|
93
93
|
- config/forced_rubocop_config.yml
|
94
94
|
- lib/haml_lint.rb
|
95
95
|
- lib/haml_lint/adapter.rb
|
96
|
-
- lib/haml_lint/adapter/haml_4.rb
|
97
96
|
- lib/haml_lint/adapter/haml_5.rb
|
98
97
|
- lib/haml_lint/adapter/haml_6.rb
|
99
98
|
- lib/haml_lint/cli.rb
|
@@ -177,6 +176,7 @@ files:
|
|
177
176
|
- lib/haml_lint/ruby_parser.rb
|
178
177
|
- lib/haml_lint/runner.rb
|
179
178
|
- lib/haml_lint/severity.rb
|
179
|
+
- lib/haml_lint/source.rb
|
180
180
|
- lib/haml_lint/spec.rb
|
181
181
|
- lib/haml_lint/spec/matchers/report_lint.rb
|
182
182
|
- lib/haml_lint/spec/normalize_indent.rb
|
@@ -208,14 +208,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
208
208
|
requirements:
|
209
209
|
- - ">="
|
210
210
|
- !ruby/object:Gem::Version
|
211
|
-
version:
|
211
|
+
version: '3.0'
|
212
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
213
213
|
requirements:
|
214
214
|
- - ">="
|
215
215
|
- !ruby/object:Gem::Version
|
216
216
|
version: '0'
|
217
217
|
requirements: []
|
218
|
-
rubygems_version: 3.
|
218
|
+
rubygems_version: 3.4.10
|
219
219
|
signing_key:
|
220
220
|
specification_version: 4
|
221
221
|
summary: HAML lint tool
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
|
5
|
-
module HamlLint
|
6
|
-
class Adapter
|
7
|
-
# Adapts the Haml::Parser from Haml 4 for use in HamlLint
|
8
|
-
# :reek:UncommunicativeModuleName
|
9
|
-
class Haml4 < Adapter
|
10
|
-
extend Forwardable
|
11
|
-
|
12
|
-
# Parses the specified Haml code into an abstract syntax tree
|
13
|
-
#
|
14
|
-
# @example
|
15
|
-
# HamlLint::Adapter::Haml4.new('%div')
|
16
|
-
#
|
17
|
-
# @api public
|
18
|
-
# @param source [String] Haml code to parse
|
19
|
-
# @param options [Haml::Options]
|
20
|
-
def initialize(source, options = Haml::Options.new)
|
21
|
-
@source = source
|
22
|
-
@parser = Haml::Parser.new(source, options)
|
23
|
-
end
|
24
|
-
|
25
|
-
def precompile
|
26
|
-
# Haml uses the filters as part of precompilation... we don't care about those,
|
27
|
-
# but without this tweak, it would fail on filters that are not loaded.
|
28
|
-
real_defined = Haml::Filters.defined
|
29
|
-
Haml::Filters.instance_variable_set(:@defined, Hash.new { real_defined['plain'] })
|
30
|
-
|
31
|
-
::Haml::Engine.new(source).precompiled
|
32
|
-
ensure
|
33
|
-
Haml::Filters.instance_variable_set(:@defined, real_defined)
|
34
|
-
end
|
35
|
-
|
36
|
-
# @!method
|
37
|
-
# Parses the source code into an abstract syntax tree
|
38
|
-
#
|
39
|
-
# @example
|
40
|
-
# HamlLint::Adapter::Haml4.new('%div')
|
41
|
-
#
|
42
|
-
# @api public
|
43
|
-
# @return [Haml::Parser::ParseNode]
|
44
|
-
# @raise [Haml::Error]
|
45
|
-
def_delegator :parser, :parse
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
# The Haml parser to adapt for HamlLint
|
50
|
-
#
|
51
|
-
# @api private
|
52
|
-
# @return [Haml::Parser] the Haml 4 parser
|
53
|
-
attr_reader :parser
|
54
|
-
|
55
|
-
# The Haml code to parse
|
56
|
-
#
|
57
|
-
# @api private
|
58
|
-
# @return [String] Haml code to parse
|
59
|
-
attr_reader :source
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|