haml_lint 0.23.2 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|