haml_lint 0.23.2 → 0.24.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/config/default.yml +5 -4
- data/lib/haml_lint/cli.rb +16 -2
- data/lib/haml_lint/configuration_loader.rb +38 -2
- data/lib/haml_lint/linter/indentation.rb +38 -2
- data/lib/haml_lint/linter.rb +10 -0
- data/lib/haml_lint/options.rb +5 -1
- data/lib/haml_lint/reporter/disabled_config_reporter.rb +105 -0
- data/lib/haml_lint/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe12a287eaf253fd83053061ac62a26b908918e6
|
4
|
+
data.tar.gz: cf8bae7a2e75dde6befbe09a9764fb223ea72583
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55334bc83c7c8f377c78b290db34ba08a2939bd9179e06541d27f3919118d3942500c85a5028ad2dde31a868ac82c4bd49b7ebf6492ec14400ae0f8b213e72d5
|
7
|
+
data.tar.gz: 84e178971e6068b40dd896f49efac863a244a8ed952b4d4d45d93872d6a2030a68134721c2cffbba94cffc5d3b11b88283b487c35a1d3907132eab86df44eb26
|
data/config/default.yml
CHANGED
@@ -47,6 +47,11 @@ linters:
|
|
47
47
|
ImplicitDiv:
|
48
48
|
enabled: true
|
49
49
|
|
50
|
+
Indentation:
|
51
|
+
enabled: true
|
52
|
+
character: space # or tab
|
53
|
+
width: 2 # ignored if character == tab
|
54
|
+
|
50
55
|
InstanceVariables:
|
51
56
|
enabled: true
|
52
57
|
file_types: partials
|
@@ -108,10 +113,6 @@ linters:
|
|
108
113
|
enabled: true
|
109
114
|
style: space
|
110
115
|
|
111
|
-
Indentation:
|
112
|
-
enabled: true
|
113
|
-
character: space # or tab
|
114
|
-
|
115
116
|
TagName:
|
116
117
|
enabled: true
|
117
118
|
|
data/lib/haml_lint/cli.rb
CHANGED
@@ -83,12 +83,26 @@ module HamlLint
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
# Instantiates a new reporter based on the options.
|
87
|
+
#
|
88
|
+
# @param options [HamlLint::Configuration]
|
89
|
+
# @option options [true, nil] :auto_gen_config whether to use the config
|
90
|
+
# generating reporter
|
91
|
+
# @option options [Class] :reporter the class of reporter to use
|
92
|
+
# @return [HamlLint::Reporter]
|
93
|
+
def reporter_from_options(options)
|
94
|
+
if options[:auto_gen_config]
|
95
|
+
HamlLint::Reporter::DisabledConfigReporter.new(log)
|
96
|
+
else
|
97
|
+
options.fetch(:reporter, HamlLint::Reporter::DefaultReporter).new(log)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
86
101
|
# Scans the files specified by the given options for lints.
|
87
102
|
#
|
88
103
|
# @return [Integer] exit status code
|
89
104
|
def scan_for_lints(options)
|
90
|
-
reporter = options
|
91
|
-
HamlLint::Reporter::DefaultReporter).new(log)
|
105
|
+
reporter = reporter_from_options(options)
|
92
106
|
report = Runner.new.run(options.merge(reporter: reporter))
|
93
107
|
report.display
|
94
108
|
report.failed? ? Sysexits::EX_DATAERR : Sysexits::EX_OK
|
@@ -6,6 +6,7 @@ require 'yaml'
|
|
6
6
|
module HamlLint
|
7
7
|
# Manages configuration file loading.
|
8
8
|
class ConfigurationLoader
|
9
|
+
AUTO_GENERATED_FILE = '.haml-lint_todo.yml'.freeze
|
9
10
|
DEFAULT_CONFIG_PATH = File.join(HamlLint::HOME, 'config', 'default.yml').freeze
|
10
11
|
CONFIG_FILE_NAME = '.haml-lint.yml'.freeze
|
11
12
|
|
@@ -31,11 +32,14 @@ module HamlLint
|
|
31
32
|
# Loads a configuration, ensuring it extends the default configuration.
|
32
33
|
#
|
33
34
|
# @param file [String]
|
35
|
+
# @param loaded_files [Array<String>] any previously loaded files in an
|
36
|
+
# inheritance chain
|
34
37
|
# @return [HamlLint::Configuration]
|
35
|
-
def load_file(file)
|
38
|
+
def load_file(file, loaded_files = [])
|
36
39
|
config = load_from_file(file)
|
37
40
|
|
38
|
-
default_configuration
|
41
|
+
[default_configuration, resolve_inheritance(config, loaded_files), config]
|
42
|
+
.reduce { |acc, elem| acc.merge(elem) }
|
39
43
|
rescue Psych::SyntaxError, Errno::ENOENT => error
|
40
44
|
raise HamlLint::Exceptions::ConfigurationError,
|
41
45
|
"Unable to load configuration from '#{file}': #{error}",
|
@@ -67,6 +71,11 @@ module HamlLint
|
|
67
71
|
{}
|
68
72
|
end
|
69
73
|
|
74
|
+
if hash.key?('inherit_from')
|
75
|
+
hash['inherits_from'] ||= []
|
76
|
+
hash['inherits_from'].concat(Array(hash.delete('inherit_from')))
|
77
|
+
end
|
78
|
+
|
70
79
|
HamlLint::Configuration.new(hash)
|
71
80
|
end
|
72
81
|
|
@@ -81,6 +90,33 @@ module HamlLint
|
|
81
90
|
.map { |path| path + CONFIG_FILE_NAME }
|
82
91
|
files << Pathname.new(CONFIG_FILE_NAME)
|
83
92
|
end
|
93
|
+
|
94
|
+
# Resolves an inherited file and loads it.
|
95
|
+
#
|
96
|
+
# @param file [String] the path to the file
|
97
|
+
# @param loaded_files [Array<String>] previously loaded files in the
|
98
|
+
# inheritance chain
|
99
|
+
# @return [HamlLint::Configuration, nil]
|
100
|
+
def resolve(file, loaded_files)
|
101
|
+
return unless File.exist?(file)
|
102
|
+
return if loaded_files.include?(file)
|
103
|
+
|
104
|
+
loaded_files << file
|
105
|
+
load_file(file, loaded_files)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Resolves the chain of `inherits_from` directives in a configuration.
|
109
|
+
#
|
110
|
+
# @param config [HamlLint::Configuration] the pre-existing configuration
|
111
|
+
# @param loaded_files [Array<String>] any previously loaded files in an
|
112
|
+
# inheritance chain
|
113
|
+
# @return [HamlLint::Configuration]
|
114
|
+
def resolve_inheritance(config, loaded_files)
|
115
|
+
Array(config['inherits_from'])
|
116
|
+
.map { |config_file| resolve(config_file, loaded_files) }
|
117
|
+
.compact
|
118
|
+
.reduce { |acc, elem| acc.merge(elem) } || config
|
119
|
+
end
|
84
120
|
end
|
85
121
|
end
|
86
122
|
end
|
@@ -9,15 +9,51 @@ module HamlLint
|
|
9
9
|
tab: /^\t*(?![ ])/,
|
10
10
|
}.freeze
|
11
11
|
|
12
|
+
LEADING_SPACES_REGEX = /^( +)(?! )/
|
13
|
+
|
12
14
|
def visit_root(root)
|
13
|
-
|
15
|
+
character = config['character'].to_sym
|
16
|
+
check_character(character, root)
|
17
|
+
|
18
|
+
width = config['width'].to_i
|
19
|
+
check_width(width, root) if character == :space && width > 0
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# validate that indentation matches config characters (either spaces or tabs)
|
25
|
+
def check_character(character, root)
|
26
|
+
wrong_characters = character == :space ? 'tabs' : 'spaces'
|
27
|
+
regex = INDENT_REGEX[character]
|
14
28
|
dummy_node = Struct.new(:line)
|
15
29
|
|
16
30
|
document.source_lines.each_with_index do |line, index|
|
17
31
|
next if line =~ regex
|
18
32
|
|
19
33
|
unless root.node_for_line(index).disabled?(self)
|
20
|
-
record_lint dummy_node.new(index + 1),
|
34
|
+
record_lint dummy_node.new(index + 1), "Line contains #{wrong_characters} in indentation"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# validate that indentation matches config width (only for spaces)
|
40
|
+
def check_width(width, root)
|
41
|
+
dummy_node = Struct.new(:line)
|
42
|
+
|
43
|
+
root.children.each do |top_node|
|
44
|
+
# once we've found one line with leading space, there's no need to check any more lines
|
45
|
+
# `haml` will check indenting_at_start, deeper_indenting, inconsistent_indentation
|
46
|
+
break if top_node.children.find do |node|
|
47
|
+
line = node.source_code
|
48
|
+
leading_space = LEADING_SPACES_REGEX.match(line)
|
49
|
+
|
50
|
+
break unless leading_space && !node.disabled?(self)
|
51
|
+
|
52
|
+
if leading_space[1] != ' ' * width
|
53
|
+
record_lint dummy_node.new(node.line), "File does not use #{width}-space indentation"
|
54
|
+
end
|
55
|
+
|
56
|
+
break true
|
21
57
|
end
|
22
58
|
end
|
23
59
|
end
|
data/lib/haml_lint/linter.rb
CHANGED
@@ -27,6 +27,16 @@ module HamlLint
|
|
27
27
|
@lints = []
|
28
28
|
visit(document.tree)
|
29
29
|
@lints
|
30
|
+
rescue Parser::SyntaxError => ex
|
31
|
+
location = ex.diagnostic.location
|
32
|
+
@lints <<
|
33
|
+
HamlLint::Lint.new(
|
34
|
+
HamlLint::Linter::Syntax.new(config),
|
35
|
+
document.file,
|
36
|
+
location.line,
|
37
|
+
ex.to_s,
|
38
|
+
:error
|
39
|
+
)
|
30
40
|
end
|
31
41
|
|
32
42
|
# Returns the simple name for this linter.
|
data/lib/haml_lint/options.rb
CHANGED
@@ -21,7 +21,7 @@ module HamlLint
|
|
21
21
|
end.parse!(args)
|
22
22
|
|
23
23
|
# Any remaining arguments are assumed to be files
|
24
|
-
@options[:files] = args
|
24
|
+
@options[:files] = args.empty? ? ["."] : args
|
25
25
|
|
26
26
|
@options
|
27
27
|
rescue OptionParser::InvalidOption => ex
|
@@ -33,6 +33,10 @@ module HamlLint
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def add_linter_options(parser)
|
36
|
+
parser.on('--auto-gen-config', 'Generate a configuration file acting as a TODO list') do
|
37
|
+
@options[:auto_gen_config] = true
|
38
|
+
end
|
39
|
+
|
36
40
|
parser.on('-i', '--include-linter linter,...', Array,
|
37
41
|
'Specify which linters you want to run') do |linters|
|
38
42
|
@options[:included_linters] = linters
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'haml_lint/reporter/progress_reporter'
|
2
|
+
|
3
|
+
module HamlLint
|
4
|
+
# Outputs a YAML configuration file based on existing violations.
|
5
|
+
class Reporter::DisabledConfigReporter < Reporter::ProgressReporter
|
6
|
+
HEADING =
|
7
|
+
['# This configuration was generated by',
|
8
|
+
'# `haml-lint --auto-gen-config`',
|
9
|
+
"# on #{Time.now} using Haml-Lint version #{HamlLint::VERSION}.",
|
10
|
+
'# The point is for the user to remove these configuration records',
|
11
|
+
'# one by one as the lints are removed from the code base.',
|
12
|
+
'# Note that changes in the inspected code, or installation of new',
|
13
|
+
'# versions of Haml-Lint, may require this file to be generated again.']
|
14
|
+
.join("\n")
|
15
|
+
|
16
|
+
# Disables this reporter on the CLI since it doesn't output anything.
|
17
|
+
#
|
18
|
+
# @return [false]
|
19
|
+
def self.available?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create the reporter that will display the report and write the config.
|
24
|
+
#
|
25
|
+
# @param _log [HamlLint::Logger]
|
26
|
+
def initialize(_log)
|
27
|
+
super
|
28
|
+
@linters_with_lints = Hash.new { |hash, key| hash[key] = [] }
|
29
|
+
@linters_lint_count = Hash.new(0)
|
30
|
+
end
|
31
|
+
|
32
|
+
# A hash of linters with the files that have that type of lint.
|
33
|
+
#
|
34
|
+
# @return [Hash<String, Integer] a Hash with linter name keys and lint
|
35
|
+
# count values
|
36
|
+
attr_reader :linters_lint_count
|
37
|
+
|
38
|
+
# A hash of linters with the files that have that type of lint.
|
39
|
+
#
|
40
|
+
# @return [Hash<String, Array<String>>] a Hash with linter name keys and file
|
41
|
+
# name list values
|
42
|
+
attr_reader :linters_with_lints
|
43
|
+
|
44
|
+
# Prints the standard progress reporter output and writes the new config file.
|
45
|
+
#
|
46
|
+
# @param report [HamlLint::Report]
|
47
|
+
# @return [void]
|
48
|
+
def display_report(report)
|
49
|
+
super
|
50
|
+
|
51
|
+
File.write(ConfigurationLoader::AUTO_GENERATED_FILE, config_file_contents)
|
52
|
+
log.log "Created #{ConfigurationLoader::AUTO_GENERATED_FILE}."
|
53
|
+
log.log "Run `haml-lint --config #{ConfigurationLoader::AUTO_GENERATED_FILE}`" \
|
54
|
+
", or add `inherits_from: #{ConfigurationLoader::AUTO_GENERATED_FILE}` in a " \
|
55
|
+
'.haml-lint.yml file.'
|
56
|
+
end
|
57
|
+
|
58
|
+
# Prints the standard progress report marks and tracks files with lint.
|
59
|
+
#
|
60
|
+
# @param file [String]
|
61
|
+
# @param lints [Array<HamlLint::Lint>]
|
62
|
+
# @return [void]
|
63
|
+
def finished_file(file, lints)
|
64
|
+
super
|
65
|
+
|
66
|
+
if lints.any?
|
67
|
+
lints.each do |lint|
|
68
|
+
linters_with_lints[lint.linter.name] |= [lint.filename]
|
69
|
+
linters_lint_count[lint.linter.name] += 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# The contents of the generated configuration file based on captured lint.
|
77
|
+
#
|
78
|
+
# @return [String] a Yaml-formatted configuration file's contents
|
79
|
+
def config_file_contents
|
80
|
+
output = []
|
81
|
+
output << HEADING
|
82
|
+
output << 'linters:' if linters_with_lints.any?
|
83
|
+
linters_with_lints.each do |linter, files|
|
84
|
+
output << generate_config_for_linter(linter, files)
|
85
|
+
end
|
86
|
+
output.join("\n\n")
|
87
|
+
end
|
88
|
+
|
89
|
+
# Constructs the configuration for excluding a linter in some files.
|
90
|
+
#
|
91
|
+
# @param linter [String] the name of the linter to exclude
|
92
|
+
# @param files [Array<String>] the files in which the linter is excluded
|
93
|
+
# @return [String] a Yaml-formatted configuration
|
94
|
+
def generate_config_for_linter(linter, files)
|
95
|
+
[].tap do |output|
|
96
|
+
output << " # Offense count: #{linters_lint_count[linter]}"
|
97
|
+
output << " #{linter}:"
|
98
|
+
output << ' exclude:'
|
99
|
+
files.each do |filename|
|
100
|
+
output << %{ - "#{filename}"}
|
101
|
+
end
|
102
|
+
end.join("\n")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/haml_lint/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml_lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brigade Engineering
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-03-
|
12
|
+
date: 2017-03-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: haml
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- lib/haml_lint/reporter.rb
|
161
161
|
- lib/haml_lint/reporter/checkstyle_reporter.rb
|
162
162
|
- lib/haml_lint/reporter/default_reporter.rb
|
163
|
+
- lib/haml_lint/reporter/disabled_config_reporter.rb
|
163
164
|
- lib/haml_lint/reporter/hash_reporter.rb
|
164
165
|
- lib/haml_lint/reporter/hooks.rb
|
165
166
|
- lib/haml_lint/reporter/json_reporter.rb
|