haml_lint 0.28.0 → 0.29.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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/bin/haml-lint +1 -0
  3. data/config/default.yml +1 -0
  4. data/lib/haml_lint/adapter/haml_4.rb +2 -0
  5. data/lib/haml_lint/adapter/haml_5.rb +2 -0
  6. data/lib/haml_lint/adapter.rb +2 -0
  7. data/lib/haml_lint/cli.rb +5 -3
  8. data/lib/haml_lint/comment_configuration.rb +2 -0
  9. data/lib/haml_lint/configuration.rb +2 -0
  10. data/lib/haml_lint/configuration_loader.rb +36 -20
  11. data/lib/haml_lint/constants.rb +3 -3
  12. data/lib/haml_lint/directive.rb +4 -2
  13. data/lib/haml_lint/document.rb +3 -3
  14. data/lib/haml_lint/exceptions.rb +2 -0
  15. data/lib/haml_lint/file_finder.rb +2 -0
  16. data/lib/haml_lint/haml_visitor.rb +2 -0
  17. data/lib/haml_lint/lint.rb +2 -0
  18. data/lib/haml_lint/linter/alignment_tabs.rb +4 -2
  19. data/lib/haml_lint/linter/alt_text.rb +2 -0
  20. data/lib/haml_lint/linter/class_attribute_with_static_value.rb +3 -1
  21. data/lib/haml_lint/linter/classes_before_ids.rb +3 -1
  22. data/lib/haml_lint/linter/consecutive_comments.rb +2 -0
  23. data/lib/haml_lint/linter/consecutive_silent_scripts.rb +2 -0
  24. data/lib/haml_lint/linter/empty_object_reference.rb +2 -0
  25. data/lib/haml_lint/linter/empty_script.rb +2 -0
  26. data/lib/haml_lint/linter/final_newline.rb +2 -0
  27. data/lib/haml_lint/linter/html_attributes.rb +2 -0
  28. data/lib/haml_lint/linter/id_names.rb +2 -0
  29. data/lib/haml_lint/linter/implicit_div.rb +2 -0
  30. data/lib/haml_lint/linter/indentation.rb +3 -1
  31. data/lib/haml_lint/linter/inline_styles.rb +3 -1
  32. data/lib/haml_lint/linter/instance_variables.rb +2 -0
  33. data/lib/haml_lint/linter/leading_comment_space.rb +3 -1
  34. data/lib/haml_lint/linter/line_length.rb +1 -1
  35. data/lib/haml_lint/linter/multiline_pipe.rb +2 -2
  36. data/lib/haml_lint/linter/multiline_script.rb +2 -0
  37. data/lib/haml_lint/linter/object_reference_attributes.rb +2 -0
  38. data/lib/haml_lint/linter/repeated_id.rb +3 -1
  39. data/lib/haml_lint/linter/rubocop.rb +2 -0
  40. data/lib/haml_lint/linter/ruby_comments.rb +2 -0
  41. data/lib/haml_lint/linter/space_before_script.rb +1 -1
  42. data/lib/haml_lint/linter/space_inside_hash_attributes.rb +2 -0
  43. data/lib/haml_lint/linter/syntax.rb +2 -0
  44. data/lib/haml_lint/linter/tag_name.rb +2 -0
  45. data/lib/haml_lint/linter/trailing_whitespace.rb +2 -0
  46. data/lib/haml_lint/linter/unnecessary_interpolation.rb +2 -0
  47. data/lib/haml_lint/linter/unnecessary_string_output.rb +1 -1
  48. data/lib/haml_lint/linter/view_length.rb +6 -3
  49. data/lib/haml_lint/linter.rb +5 -3
  50. data/lib/haml_lint/linter_registry.rb +2 -0
  51. data/lib/haml_lint/linter_selector.rb +2 -0
  52. data/lib/haml_lint/logger.rb +2 -0
  53. data/lib/haml_lint/node_transformer.rb +2 -0
  54. data/lib/haml_lint/options.rb +9 -4
  55. data/lib/haml_lint/parsed_ruby.rb +2 -0
  56. data/lib/haml_lint/rake_task.rb +14 -2
  57. data/lib/haml_lint/report.rb +2 -0
  58. data/lib/haml_lint/reporter/checkstyle_reporter.rb +2 -0
  59. data/lib/haml_lint/reporter/default_reporter.rb +2 -0
  60. data/lib/haml_lint/reporter/disabled_config_reporter.rb +11 -3
  61. data/lib/haml_lint/reporter/hash_reporter.rb +2 -0
  62. data/lib/haml_lint/reporter/hooks.rb +2 -0
  63. data/lib/haml_lint/reporter/json_reporter.rb +2 -0
  64. data/lib/haml_lint/reporter/progress_reporter.rb +3 -1
  65. data/lib/haml_lint/reporter/utils.rb +2 -0
  66. data/lib/haml_lint/reporter.rb +2 -0
  67. data/lib/haml_lint/ruby_extractor.rb +3 -1
  68. data/lib/haml_lint/ruby_parser.rb +2 -0
  69. data/lib/haml_lint/runner.rb +11 -6
  70. data/lib/haml_lint/severity.rb +2 -0
  71. data/lib/haml_lint/tree/comment_node.rb +2 -0
  72. data/lib/haml_lint/tree/doctype_node.rb +2 -0
  73. data/lib/haml_lint/tree/filter_node.rb +2 -0
  74. data/lib/haml_lint/tree/haml_comment_node.rb +2 -0
  75. data/lib/haml_lint/tree/node.rb +20 -2
  76. data/lib/haml_lint/tree/null_node.rb +2 -0
  77. data/lib/haml_lint/tree/plain_node.rb +2 -0
  78. data/lib/haml_lint/tree/root_node.rb +2 -0
  79. data/lib/haml_lint/tree/script_node.rb +2 -0
  80. data/lib/haml_lint/tree/silent_script_node.rb +2 -0
  81. data/lib/haml_lint/tree/tag_node.rb +2 -0
  82. data/lib/haml_lint/utils.rb +2 -0
  83. data/lib/haml_lint/version.rb +1 -1
  84. data/lib/haml_lint.rb +2 -0
  85. metadata +5 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de1778be09762f2f6e9205045f63a6bfbc1966f1bc848e57c5bc22a52a8c0488
4
- data.tar.gz: ecb4cc40e34424ba773dec9b252ef7618f60b9a14e63d7afba68164f41d49681
3
+ metadata.gz: a2b6e2913e09e73c44c78189a5766b3b30bb8999c010a61729843f038fdd6b72
4
+ data.tar.gz: 4b59c4427a7bf35b2f90eb03f4fe5c89fb4b6046cdedde5b2bc6137cca1b265d
5
5
  SHA512:
6
- metadata.gz: 7cdf82866d301aa55ba5891d364030f6657dcd492118be4bc06933a3158c88bb45d088fcdc6a0e60e72a983271781f5c1ab515aef5e9eff2b2a82ea23ef16cc1
7
- data.tar.gz: 68ae9a3bd3c9d7c2d3514577aae4513b755479b4c63c7fc08bfd5f45a8cbb1dd5495e4d2dd7f071988e3d8b84bb44959577786860b2f4c2eb5118f2e6257bd8b
6
+ metadata.gz: d1dc05e7ce0d8b5ad2cb268159ad51894f1bf17c883d3f23af222b8754f3d24fdbd73368466b55ceda9d587bf457b7961180818971d482110bbc0ad0cfb7f874
7
+ data.tar.gz: bc1553ea5bd67ee4d19e56ff7ed34fea91f4c286d2a8f09419ccae1ae19da7469c917d2a297e21b5b6e3bf8ad4457b3301c7c7282aca81c1a88102ff0c7fa931
data/bin/haml-lint CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'haml_lint'
4
5
  require 'haml_lint/cli'
data/config/default.yml CHANGED
@@ -91,6 +91,7 @@ linters:
91
91
  - Lint/BlockAlignment
92
92
  - Lint/EndAlignment
93
93
  - Lint/Void
94
+ - Layout/AlignHash
94
95
  - Layout/AlignParameters
95
96
  - Layout/ElseAlignment
96
97
  - Layout/EndOfLine
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  class Adapter
3
5
  # Adapts the Haml::Parser from Haml 4 for use in HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  class Adapter
3
5
  # Adapts the Haml::Parser from Haml 5 for use in HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/adapter/haml_4'
2
4
  require 'haml_lint/adapter/haml_5'
3
5
  require 'haml_lint/exceptions'
data/lib/haml_lint/cli.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint'
2
4
  require 'haml_lint/options'
3
5
 
@@ -21,8 +23,8 @@ module HamlLint
21
23
  def run(args)
22
24
  options = HamlLint::Options.new.parse(args)
23
25
  act_on_options(options)
24
- rescue StandardError => exception
25
- handle_exception(exception)
26
+ rescue StandardError => e
27
+ handle_exception(e)
26
28
  end
27
29
 
28
30
  private
@@ -92,7 +94,7 @@ module HamlLint
92
94
  # @return [HamlLint::Reporter]
93
95
  def reporter_from_options(options)
94
96
  if options[:auto_gen_config]
95
- HamlLint::Reporter::DisabledConfigReporter.new(log)
97
+ HamlLint::Reporter::DisabledConfigReporter.new(log, limit: options[:auto_gen_exclude_limit] || 15) # rubocop:disable Metrics/LineLength
96
98
  else
97
99
  options.fetch(:reporter, HamlLint::Reporter::DefaultReporter).new(log)
98
100
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Determines what linters are enabled or disabled via comments.
3
5
  class CommentConfiguration
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Stores runtime configuration for the application.
3
5
  #
@@ -6,24 +6,34 @@ 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
+ AUTO_GENERATED_FILE = '.haml-lint_todo.yml'
10
10
  DEFAULT_CONFIG_PATH = File.join(HamlLint::HOME, 'config', 'default.yml').freeze
11
- CONFIG_FILE_NAME = '.haml-lint.yml'.freeze
11
+ CONFIG_FILE_NAME = '.haml-lint.yml'
12
12
 
13
13
  class << self
14
14
  # Load configuration file given the current working directory the
15
15
  # application is running within.
16
- def load_applicable_config
17
- directory = File.expand_path(Dir.pwd)
18
- config_file = possible_config_files(directory).find(&:file?)
19
-
16
+ # @param config_file [String] optional path to the config file to load
17
+ # @param options [Hash]
18
+ # @option options :exclude_files [Array<String>] files that should not
19
+ # be loaded even if they're requested via inherits_from
20
+ # @return [HamlLint::Configuration]
21
+ def load_applicable_config(config_file = nil, options = {})
22
+ config_file ||= default_path_to_config
20
23
  if config_file
21
- load_file(config_file.to_path)
24
+ load_file(config_file, options)
22
25
  else
23
26
  default_configuration
24
27
  end
25
28
  end
26
29
 
30
+ # Path to the default config file, if it exists
31
+ def default_path_to_config
32
+ directory = File.expand_path(Dir.pwd)
33
+ config_file = possible_config_files(directory).find(&:file?)
34
+ config_file ? config_file.to_path : nil
35
+ end
36
+
27
37
  # Loads the built-in default configuration.
28
38
  def default_configuration
29
39
  @default_configuration ||= load_from_file(DEFAULT_CONFIG_PATH)
@@ -32,18 +42,23 @@ module HamlLint
32
42
  # Loads a configuration, ensuring it extends the default configuration.
33
43
  #
34
44
  # @param file [String]
35
- # @param loaded_files [Array<String>] any previously loaded files in an
36
- # inheritance chain
45
+ # @param context [Hash]
46
+ # @option context :loaded_files [Array<String>] any previously loaded
47
+ # files in an inheritance chain
48
+ # @option context :exclude_files [Array<String>] files that should not
49
+ # be loaded even if they're requested via inherits_from
37
50
  # @return [HamlLint::Configuration]
38
- def load_file(file, loaded_files = [])
51
+ def load_file(file, context = {})
52
+ context[:loaded_files] ||= []
53
+ context[:exclude_files] ||= []
39
54
  config = load_from_file(file)
40
55
 
41
- [default_configuration, resolve_inheritance(config, loaded_files), config]
56
+ [default_configuration, resolve_inheritance(config, context), config]
42
57
  .reduce { |acc, elem| acc.merge(elem) }
43
- rescue Psych::SyntaxError, Errno::ENOENT => error
58
+ rescue Psych::SyntaxError, Errno::ENOENT => e
44
59
  raise HamlLint::Exceptions::ConfigurationError,
45
- "Unable to load configuration from '#{file}': #{error}",
46
- error.backtrace
60
+ "Unable to load configuration from '#{file}': #{e}",
61
+ e.backtrace
47
62
  end
48
63
 
49
64
  # Creates a configuration from the specified hash, ensuring it extends the
@@ -97,12 +112,13 @@ module HamlLint
97
112
  # @param loaded_files [Array<String>] previously loaded files in the
98
113
  # inheritance chain
99
114
  # @return [HamlLint::Configuration, nil]
100
- def resolve(file, loaded_files)
115
+ def resolve(file, context)
101
116
  return unless File.exist?(file)
102
- return if loaded_files.include?(file)
117
+ return if context[:loaded_files].include?(file)
118
+ return if context[:exclude_files].include?(file)
103
119
 
104
- loaded_files << file
105
- load_file(file, loaded_files)
120
+ context[:loaded_files] << file
121
+ load_file(file, context)
106
122
  end
107
123
 
108
124
  # Resolves the chain of `inherits_from` directives in a configuration.
@@ -111,9 +127,9 @@ module HamlLint
111
127
  # @param loaded_files [Array<String>] any previously loaded files in an
112
128
  # inheritance chain
113
129
  # @return [HamlLint::Configuration]
114
- def resolve_inheritance(config, loaded_files)
130
+ def resolve_inheritance(config, context)
115
131
  Array(config['inherits_from'])
116
- .map { |config_file| resolve(config_file, loaded_files) }
132
+ .map { |config_file| resolve(config_file, context) }
117
133
  .compact
118
134
  .reduce { |acc, elem| acc.merge(elem) } || config
119
135
  end
@@ -3,8 +3,8 @@
3
3
  # Global application constants.
4
4
  module HamlLint
5
5
  HOME = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze
6
- APP_NAME = 'haml-lint'.freeze
6
+ APP_NAME = 'haml-lint'
7
7
 
8
- REPO_URL = 'https://github.com/brigade/haml-lint'.freeze
9
- BUG_REPORT_URL = "#{REPO_URL}/issues".freeze
8
+ REPO_URL = 'https://github.com/sds/haml-lint'
9
+ BUG_REPORT_URL = "#{REPO_URL}/issues"
10
10
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Handles linter configuration transformation via Haml comments.
3
5
  class Directive
4
- LINTER_REGEXP = /(?:[A-Z]\w+)/
6
+ LINTER_REGEXP = /(?:[A-Z]\w+)/.freeze
5
7
 
6
8
  DIRECTIVE_REGEXP = /
7
9
  # "haml-lint:" with optional spacing
@@ -12,7 +14,7 @@ module HamlLint
12
14
 
13
15
  # "all" or a comma-separated list (with optional spaces) of linters
14
16
  (?<linters>all | (?:#{LINTER_REGEXP}\s*,\s*)* #{LINTER_REGEXP})
15
- /x
17
+ /x.freeze
16
18
 
17
19
  # Constructs a directive from source code as a given line.
18
20
  #
@@ -6,7 +6,7 @@ module HamlLint
6
6
  # Represents a parsed Haml document and its associated metadata.
7
7
  class Document
8
8
  # File name given to source code parsed from just a string.
9
- STRING_SOURCE = '(string)'.freeze
9
+ STRING_SOURCE = '(string)'
10
10
 
11
11
  # @return [HamlLint::Configuration] Configuration used to parse template
12
12
  attr_reader :config
@@ -46,8 +46,8 @@ module HamlLint
46
46
  @source_lines = @source.split(/\r\n|\r|\n/)
47
47
 
48
48
  @tree = process_tree(HamlLint::Adapter.detect_class.new(@source).parse)
49
- rescue Haml::Error => ex
50
- error = HamlLint::Exceptions::ParseError.new(ex.message, ex.line)
49
+ rescue Haml::Error => e
50
+ error = HamlLint::Exceptions::ParseError.new(e.message, e.line)
51
51
  raise error
52
52
  end
53
53
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Collection of exceptions that can be raised by the HAML Lint application.
2
4
  module HamlLint::Exceptions
3
5
  # Raised when a {Configuration} could not be loaded from a file.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'find'
2
4
 
3
5
  module HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Provides an interface which when included allows a class to visit nodes in
3
5
  # the parse tree of a HAML document.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Contains information about a problem or issue with a HAML document.
3
5
  class Lint
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for tabs that are placed for alignment of tag content
3
5
  class Linter::AlignmentTabs < Linter
4
- REGEX = /[^\s*]\t+/
6
+ REGEX = /[^\s*]\t+/.freeze
5
7
 
6
8
  def visit_tag(node)
7
- if REGEX.match(node.source_code)
9
+ if REGEX.match?(node.source_code)
8
10
  record_lint(node, 'Avoid using tabs for alignment')
9
11
  end
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for missing `alt` attributes on `img` tags.
3
5
  class Linter::AltText < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for class attributes defined in tag attribute hash with static
3
5
  # values.
@@ -18,7 +20,7 @@ module HamlLint
18
20
 
19
21
  STATIC_TYPES = %i[str sym].freeze
20
22
 
21
- VALID_CLASS_REGEX = /^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$/
23
+ VALID_CLASS_REGEX = /^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$/.freeze
22
24
 
23
25
  def visit_tag(node)
24
26
  return unless contains_class_attribute?(node.dynamic_attributes_sources)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks that classes are listed before IDs in tags.
3
5
  class Linter::ClassesBeforeIds < Linter
@@ -9,7 +11,7 @@ module HamlLint
9
11
  '#' => :id,
10
12
  }.freeze
11
13
 
12
- MSG = '%s should be listed before %s (%s should precede %s)'.freeze
14
+ MSG = '%s should be listed before %s (%s should precede %s)'
13
15
 
14
16
  def visit_tag(node)
15
17
  # Convert ".class#id" into [.class, #id] (preserving order)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for multiple lines of code comments that can be condensed.
3
5
  class Linter::ConsecutiveComments < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for multiple consecutive silent script markers that could be
3
5
  # condensed into a :ruby filter block.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for empty object references (e.g. `%div[]`).
3
5
  class Linter::EmptyObjectReference < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for empty scripts.
3
5
  class Linter::EmptyScript < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for final newlines at the end of a file.
3
5
  class Linter::FinalNewline < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for the setting of attributes via HTML shorthand syntax on elements
3
5
  # (e.g. `%tag(lang=en)`).
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for `id` attributes in specific cases on tags.
3
5
  class Linter::IdNames < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for unnecessary uses of the `%div` prefix where a class name or ID
3
5
  # already implies a div.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks the character used for indentation.
3
5
  class Linter::Indentation < Linter
@@ -9,7 +11,7 @@ module HamlLint
9
11
  tab: /^\t*(?![ ])/,
10
12
  }.freeze
11
13
 
12
- LEADING_SPACES_REGEX = /^( +)(?! )/
14
+ LEADING_SPACES_REGEX = /^( +)(?! )/.freeze
13
15
 
14
16
  def visit_root(root)
15
17
  character = config['character'].to_sym
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Detects use of inline `style` attributes on any tag
3
5
  class Linter::InlineStyles < Linter
4
6
  include LinterRegistry
5
7
 
6
- MESSAGE = 'Do not use inline style attributes'.freeze
8
+ MESSAGE = 'Do not use inline style attributes'
7
9
 
8
10
  def visit_tag(node)
9
11
  if node.has_hash_attribute?(:style)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for the presence of instance variables
3
5
  class Linter::InstanceVariables < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for comments that don't have a leading space.
3
5
  class Linter::LeadingCommentSpace < Linter
@@ -6,7 +8,7 @@ module HamlLint
6
8
  def visit_haml_comment(node)
7
9
  # Skip if the node spans multiple lines starting on the second line,
8
10
  # or starts with a space
9
- return if node.text =~ /\A(\s*|\s+\S.*)$/
11
+ return if node.text =~ /\A#*(\s*|\s+\S.*)$/
10
12
 
11
13
  record_lint(node, 'Comment should have a space after the `#`')
12
14
  end
@@ -10,7 +10,7 @@ module HamlLint
10
10
  # @api private
11
11
  DummyNode = Struct.new(:line)
12
12
 
13
- MSG = 'Line is too long. [%d/%d]'.freeze
13
+ MSG = 'Line is too long. [%d/%d]'
14
14
 
15
15
  def visit_root(root)
16
16
  max_length = config['max']
@@ -6,7 +6,7 @@ module HamlLint
6
6
  include LinterRegistry
7
7
 
8
8
  MESSAGE = "Don't use the `|` character to split up lines. " \
9
- 'Wrap on commas or extract code into helper.'.freeze
9
+ 'Wrap on commas or extract code into helper.'
10
10
 
11
11
  def visit_tag(node)
12
12
  check(node)
@@ -31,7 +31,7 @@ module HamlLint
31
31
 
32
32
  private
33
33
 
34
- MULTILINE_PIPE_REGEX = /\s+\|\s*$/
34
+ MULTILINE_PIPE_REGEX = /\s+\|\s*$/.freeze
35
35
 
36
36
  def line_text_for_node(node)
37
37
  document.source_lines[node.line - 1]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks scripts spread over multiple lines.
3
5
  class Linter::MultilineScript < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for uses of the object reference syntax for assigning the class and
3
5
  # ID attributes for an element (e.g. `%div[@user]`).
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Detects repeated instances of an element ID in a file
3
5
  class Linter::RepeatedId < Linter
4
6
  include LinterRegistry
5
7
 
6
- MESSAGE_FORMAT = %{Do not repeat id "#%s" on the page}.freeze
8
+ MESSAGE_FORMAT = %{Do not repeat id "#%s" on the page}
7
9
 
8
10
  def visit_root(_node)
9
11
  @id_map = Hash.new { |hash, key| hash[key] = [] }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/ruby_extractor'
2
4
  require 'rubocop'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for Ruby comments that can be written as HAML comments.
3
5
  class Linter::RubyComments < Linter
@@ -5,7 +5,7 @@ module HamlLint
5
5
  class Linter::SpaceBeforeScript < Linter
6
6
  include LinterRegistry
7
7
 
8
- MESSAGE_FORMAT = 'The %s symbol should have one space separating it from code'.freeze
8
+ MESSAGE_FORMAT = 'The %s symbol should have one space separating it from code'
9
9
 
10
10
  ALLOWED_SEPARATORS = [' ', '#'].freeze
11
11
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for spaces inside the braces of hash attributes
3
5
  # (e.g. `%tag{ lang: en }` vs `%tag{lang: en}`).
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # A catch-all linter for syntax violations raised by the Haml parser.
3
5
  class Linter::Syntax < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for tag names with uppercase letters.
3
5
  class Linter::TagName < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for trailing whitespace.
3
5
  class Linter::TrailingWhitespace < Linter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Checks for unnecessary uses of string interpolation.
3
5
  #
@@ -11,7 +11,7 @@ module HamlLint
11
11
  class Linter::UnnecessaryStringOutput < Linter
12
12
  include LinterRegistry
13
13
 
14
- MESSAGE = '`= "..."` should be rewritten as `...`'.freeze
14
+ MESSAGE = '`= "..."` should be rewritten as `...`'
15
15
 
16
16
  def visit_tag(node)
17
17
  if tag_has_inline_script?(node) && inline_content_is_string?(node)
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Detects overly long views.
3
5
  class Linter::ViewLength < Linter
4
6
  include LinterRegistry
5
7
 
6
- MSG = 'View template is too long [%d/%d]'.freeze
8
+ MSG = 'View template is too long [%d/%d]'
7
9
 
8
10
  DummyNode = Struct.new(:line)
9
11
 
10
- def visit_root(_root)
12
+ def visit_root(root)
11
13
  max = config['max']
12
14
  line_count = document.source_lines.count
15
+ node = root.children.first
13
16
 
14
- if line_count > max
17
+ if line_count > max && !node.disabled?(self)
15
18
  record_lint(DummyNode.new(0), format(MSG, line_count, max))
16
19
  end
17
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Base implementation for all lint checks.
3
5
  #
@@ -27,14 +29,14 @@ module HamlLint
27
29
  @lints = []
28
30
  visit(document.tree)
29
31
  @lints
30
- rescue Parser::SyntaxError => ex
31
- location = ex.diagnostic.location
32
+ rescue Parser::SyntaxError => e
33
+ location = e.diagnostic.location
32
34
  @lints <<
33
35
  HamlLint::Lint.new(
34
36
  HamlLint::Linter::Syntax.new(config),
35
37
  document.file,
36
38
  location.line,
37
- ex.to_s,
39
+ e.to_s,
38
40
  :error
39
41
  )
40
42
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  class NoSuchLinter < StandardError; end
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Chooses the appropriate linters to run given the specified configuration.
3
5
  class LinterSelector
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Encapsulates all communication to an output source.
3
5
  class Logger
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Responsible for transforming {Haml::Parser::ParseNode} objects into
3
5
  # corresponding {HamlLint::Tree::Node} objects.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
2
4
 
3
5
  module HamlLint
@@ -24,10 +26,8 @@ module HamlLint
24
26
  @options[:files] = args.empty? ? ['.'] : args
25
27
 
26
28
  @options
27
- rescue OptionParser::InvalidOption => ex
28
- raise Exceptions::InvalidCLIOption,
29
- ex.message,
30
- ex.backtrace
29
+ rescue OptionParser::InvalidOption => e
30
+ raise Exceptions::InvalidCLIOption, e.message, e.backtrace
31
31
  end
32
32
 
33
33
  private
@@ -37,6 +37,11 @@ module HamlLint
37
37
  @options[:auto_gen_config] = true
38
38
  end
39
39
 
40
+ parser.on('--auto-gen-exclude-limit limit', Integer,
41
+ 'Number of failures to allow in the TODO list before the entire rule is excluded') do |limit| # rubocop:disable Metrics/LineLength
42
+ @options[:auto_gen_exclude_limit] = limit
43
+ end
44
+
40
45
  parser.on('-i', '--include-linter linter,...', Array,
41
46
  'Specify which linters you want to run') do |linters|
42
47
  @options[:included_linters] = linters
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'delegate'
2
4
 
3
5
  module HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake'
2
4
  require 'rake/tasklib'
3
5
  require 'haml_lint/constants'
@@ -35,9 +37,18 @@ module HamlLint
35
37
  # @return [String]
36
38
  attr_accessor :name
37
39
 
38
- # Configuration file to use.
40
+ # Set the configuration file or path.
41
+ #
42
+ # @param config [String,File]
43
+ def config=(config)
44
+ @config = config.is_a?(String) ? File.open(config, 'r') : config
45
+ end
46
+
47
+ # Return the configuration file path.
39
48
  # @return [String]
40
- attr_accessor :config
49
+ def config
50
+ @config.path
51
+ end
41
52
 
42
53
  # List of files to lint (can contain shell globs).
43
54
  #
@@ -131,6 +142,7 @@ module HamlLint
131
142
  def parse_args
132
143
  cli_args = config ? ['--config', config] : []
133
144
  cli_args.concat(['--fail-level', fail_level]) if fail_level
145
+ cli_args
134
146
  end
135
147
  end
136
148
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Contains information about all lints detected during a scan.
3
5
  class Report
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: false
2
+
1
3
  module HamlLint
2
4
  # Outputs report as an XML checkstyle document.
3
5
  class Reporter::CheckstyleReporter < Reporter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/reporter/utils'
2
4
 
3
5
  module HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/reporter/progress_reporter'
2
4
 
3
5
  module HamlLint
@@ -23,10 +25,11 @@ module HamlLint
23
25
  # Create the reporter that will display the report and write the config.
24
26
  #
25
27
  # @param _log [HamlLint::Logger]
26
- def initialize(_log)
27
- super
28
+ def initialize(log, limit: 15)
29
+ super(log)
28
30
  @linters_with_lints = Hash.new { |hash, key| hash[key] = [] }
29
31
  @linters_lint_count = Hash.new(0)
32
+ @exclude_limit = limit
30
33
  end
31
34
 
32
35
  # A hash of linters with the files that have that type of lint.
@@ -41,6 +44,11 @@ module HamlLint
41
44
  # name list values
42
45
  attr_reader :linters_with_lints
43
46
 
47
+ # Number of offenses to allow before simply disabling the linter
48
+ #
49
+ # @return [Integer] file exclude limit
50
+ attr_reader :exclude_limit
51
+
44
52
  # Prints the standard progress reporter output and writes the new config file.
45
53
  #
46
54
  # @param report [HamlLint::Report]
@@ -97,7 +105,7 @@ module HamlLint
97
105
  output << " #{linter}:"
98
106
  # disable the linter when there are many files with offenses.
99
107
  # exclude the affected files otherwise.
100
- if files.count > 15
108
+ if files.count > exclude_limit
101
109
  output << ' enabled: false'
102
110
  else
103
111
  output << ' exclude:'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Outputs report as a Ruby Hash for easy use by other tools.
3
5
  class Reporter::HashReporter < Reporter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  class Reporter
3
5
  # A collection of hook methods for incremental processing.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/reporter/hash_reporter'
2
4
 
3
5
  module HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rainbow'
2
4
  require 'haml_lint/reporter/utils'
3
5
 
@@ -7,7 +9,7 @@ module HamlLint
7
9
  class Reporter::ProgressReporter < Reporter
8
10
  include Reporter::Utils
9
11
 
10
- DOT = '.'.freeze
12
+ DOT = '.'
11
13
 
12
14
  def display_report(report)
13
15
  lints = report.lints
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  class Reporter
3
5
  # Formatting helpers for printing the default report format.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/reporter/hooks'
2
4
 
3
5
  module HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Utility class for extracting Ruby script from a HAML file that can then be
3
5
  # linted with a Ruby linter (i.e. is "legal" Ruby). The goal is to turn this:
@@ -122,7 +124,7 @@ module HamlLint
122
124
  visit_script(node, &block)
123
125
  end
124
126
 
125
- def visit_filter(node) # rubocop:disable Metrics/AbcSize
127
+ def visit_filter(node)
126
128
  if node.filter_type == 'ruby'
127
129
  node.text.split("\n").each_with_index do |line, index|
128
130
  add_line(line, node.line + index + 1, false)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubocop'
2
4
  require 'rubocop/ast/builder'
3
5
  require 'parser/current'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint
2
4
  # Responsible for running the applicable linters against the desired files.
3
5
  class Runner
@@ -57,12 +59,15 @@ module HamlLint
57
59
  # @param options [Hash]
58
60
  # @return [HamlLint::Configuration]
59
61
  def load_applicable_config(options)
60
- if options[:config_file]
61
- HamlLint::ConfigurationLoader.load_file(options[:config_file])
62
- elsif options[:config]
62
+ if options[:config]
63
63
  options[:config]
64
+ elsif options[:auto_gen_config]
65
+ HamlLint::ConfigurationLoader.load_applicable_config(
66
+ options[:config_file],
67
+ exclude_files: [HamlLint::ConfigurationLoader::AUTO_GENERATED_FILE]
68
+ )
64
69
  else
65
- HamlLint::ConfigurationLoader.load_applicable_config
70
+ HamlLint::ConfigurationLoader.load_applicable_config(options[:config_file])
66
71
  end
67
72
  end
68
73
 
@@ -75,9 +80,9 @@ module HamlLint
75
80
  def collect_lints(file, linter_selector, config)
76
81
  begin
77
82
  document = HamlLint::Document.new(File.read(file), file: file, config: config)
78
- rescue HamlLint::Exceptions::ParseError => ex
83
+ rescue HamlLint::Exceptions::ParseError => e
79
84
  return [HamlLint::Lint.new(HamlLint::Linter::Syntax.new(config), file,
80
- ex.line, ex.to_s, :error)]
85
+ e.line, e.to_s, :error)]
81
86
  end
82
87
 
83
88
  linter_selector.linters_for_file(file).map do |linter|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'delegate'
2
4
 
3
5
  module HamlLint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint::Tree
2
4
  # Represents a visible XHTML comment in a HAML document.
3
5
  class CommentNode < Node
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint::Tree
2
4
  # Represents a doctype definition for a HAML document.
3
5
  class DoctypeNode < Node
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint::Tree
2
4
  # Represents a filter node which contains arbitrary code.
3
5
  class FilterNode < Node
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/directive'
2
4
 
3
5
  module HamlLint::Tree
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/comment_configuration'
2
4
 
3
5
  module HamlLint::Tree
@@ -102,7 +104,10 @@ module HamlLint::Tree
102
104
  def line_numbers
103
105
  return (line..line) unless @value && text
104
106
 
105
- (line..line + lines.count)
107
+ end_line = line + lines.count
108
+ end_line = nontrivial_end_line if line == end_line
109
+
110
+ (line..end_line)
106
111
  end
107
112
 
108
113
  # The previous node to be traversed in the tree.
@@ -124,7 +129,7 @@ module HamlLint::Tree
124
129
  next_sibling = siblings.next(self)
125
130
  return next_sibling if next_sibling
126
131
 
127
- parent.successor if parent
132
+ parent&.successor
128
133
  end
129
134
 
130
135
  # Returns the next node that appears after this node in the document.
@@ -152,6 +157,19 @@ module HamlLint::Tree
152
157
 
153
158
  private
154
159
 
160
+ # Discovers the end line of the node when there are no lines.
161
+ #
162
+ # @return [Integer] the end line of the node
163
+ def nontrivial_end_line
164
+ if (last_child = children.last)
165
+ last_child.line_numbers.end - 1
166
+ elsif successor
167
+ successor.line_numbers.begin - 1
168
+ else
169
+ @document.source_lines.count
170
+ end
171
+ end
172
+
155
173
  # The siblings of this node within the tree.
156
174
  #
157
175
  # @api private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint::Tree
2
4
  # A null object version of a node that can be used as a safe default.
3
5
  class NullNode < Node
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint::Tree
2
4
  # Represents a node that contains plain text.
3
5
  class PlainNode < Node
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/tree/null_node'
2
4
 
3
5
  module HamlLint::Tree
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml_lint/parsed_ruby'
2
4
 
3
5
  module HamlLint::Tree
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint::Tree
2
4
  # Represents a HAML silent script node (`- some_expression`) which executes
3
5
  # code without producing output.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HamlLint::Tree
2
4
  # Represents a tag node in a HAML document.
3
5
  class TagNode < Node # rubocop:disable ClassLength
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  module HamlLint
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the gem version.
4
4
  module HamlLint
5
- VERSION = '0.28.0'.freeze
5
+ VERSION = '0.29.0'
6
6
  end
data/lib/haml_lint.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Need to load haml before we can reference some Haml modules in our code
2
4
  require 'haml'
3
5
 
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml_lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.28.0
4
+ version: 0.29.0
5
5
  platform: ruby
6
6
  authors:
7
- - Brigade Engineering
8
7
  - Shane da Silva
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2018-06-07 00:00:00.000000000 Z
11
+ date: 2019-05-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: haml
@@ -95,7 +94,6 @@ dependencies:
95
94
  version: '1.1'
96
95
  description: Configurable tool for writing clean and consistent HAML
97
96
  email:
98
- - eng@brigade.com
99
97
  - shane@dasilva.io
100
98
  executables:
101
99
  - haml-lint
@@ -185,7 +183,7 @@ files:
185
183
  - lib/haml_lint/tree/tag_node.rb
186
184
  - lib/haml_lint/utils.rb
187
185
  - lib/haml_lint/version.rb
188
- homepage: https://github.com/brigade/haml-lint
186
+ homepage: https://github.com/sds/haml-lint
189
187
  licenses:
190
188
  - MIT
191
189
  metadata: {}
@@ -197,15 +195,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
197
195
  requirements:
198
196
  - - ">="
199
197
  - !ruby/object:Gem::Version
200
- version: 2.2.0
198
+ version: 2.4.0
201
199
  required_rubygems_version: !ruby/object:Gem::Requirement
202
200
  requirements:
203
201
  - - ">="
204
202
  - !ruby/object:Gem::Version
205
203
  version: '0'
206
204
  requirements: []
207
- rubyforge_project:
208
- rubygems_version: 2.7.6
205
+ rubygems_version: 3.0.3
209
206
  signing_key:
210
207
  specification_version: 4
211
208
  summary: HAML lint tool