haml_lint 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 350f098b45d24d55363ac279caf35694dfbdcfda
4
- data.tar.gz: 76c0227e9aeb398ac1397003f9c1bc943c99cf02
3
+ metadata.gz: fa23a0a6cf7859c1d52147bb83dffea555ca12ef
4
+ data.tar.gz: f68ba67d32f4d76cb0632b69ff10e3d801f4e0e8
5
5
  SHA512:
6
- metadata.gz: 4c9fd9c3c414411cd8a40d0334ca2f716259874a765f3c3ebf0ba3b8513c1993fb3147706986a1b6f234713a1e22be660e6d16081514cea582e68a4aade5dda9
7
- data.tar.gz: 32549d3f2c75d75451637be9dcd46b27ceb76db5e0255365ff9cc0a2ffc89e6dccfd2f424501fc6fb07bcb1277bc14fb35fecc5011c3d907ffde3e3bee7cabf9
6
+ metadata.gz: adbaa7dba069ef58a9522a8b5ad7ce39f21aa54a9aa3fe132799f6f2fee929f7510df2029bb6e55d2a4776a8fb1e091c5896ece3a3b1b73ffcc897df44b15c64
7
+ data.tar.gz: 8e8246c549c8322a202885179c301f98e5e818aefdb2badc9c0fa83ee4974366d88dee6da61f2a0df571df05829950be26e8ada196e00c4f3ad90ce024235655
data/config/default.yml CHANGED
@@ -27,6 +27,10 @@ linters:
27
27
  EmptyScript:
28
28
  enabled: true
29
29
 
30
+ FinalNewline:
31
+ enabled: true
32
+ present: true
33
+
30
34
  HtmlAttributes:
31
35
  enabled: true
32
36
 
@@ -79,6 +83,10 @@ linters:
79
83
  enabled: true
80
84
  style: space
81
85
 
86
+ Indentation:
87
+ enabled: true
88
+ character: space # or tab
89
+
82
90
  TagName:
83
91
  enabled: true
84
92
 
data/lib/haml_lint/cli.rb CHANGED
@@ -5,7 +5,7 @@ require 'sysexits'
5
5
 
6
6
  module HamlLint
7
7
  # Command line application interface.
8
- class CLI
8
+ class CLI # rubocop:disable Metrics/ClassLength
9
9
  # Create a CLI that outputs to the specified logger.
10
10
  #
11
11
  # @param logger [HamlLint::Logger]
@@ -38,8 +38,8 @@ module HamlLint
38
38
  if options[:help]
39
39
  print_help(options)
40
40
  Sysexits::EX_OK
41
- elsif options[:version]
42
- print_version
41
+ elsif options[:version] || options[:verbose_version]
42
+ print_version(options)
43
43
  Sysexits::EX_OK
44
44
  elsif options[:show_linters]
45
45
  print_available_linters
@@ -123,17 +123,34 @@ module HamlLint
123
123
  end
124
124
 
125
125
  # Outputs the application name and version.
126
- def print_version
126
+ def print_version(options)
127
127
  log.log "#{HamlLint::APP_NAME} #{HamlLint::VERSION}"
128
+
129
+ if options[:verbose_version]
130
+ log.log "haml #{Gem.loaded_specs['haml'].version}"
131
+ log.log "rubocop #{Gem.loaded_specs['rubocop'].version}"
132
+ log.log RUBY_DESCRIPTION
133
+ end
128
134
  end
129
135
 
130
136
  # Outputs the backtrace of an exception with instructions on how to report
131
137
  # the issue.
132
- def print_unexpected_exception(ex)
138
+ def print_unexpected_exception(ex) # rubocop:disable Metrics/AbcSize
133
139
  log.bold_error ex.message
134
140
  log.error ex.backtrace.join("\n")
135
141
  log.warning 'Report this bug at ', false
136
142
  log.info HamlLint::BUG_REPORT_URL
143
+ log.newline
144
+ log.success 'To help fix this issue, please include:'
145
+ log.log '- The above stack trace'
146
+ log.log '- Haml-Lint version: ', false
147
+ log.info HamlLint::VERSION
148
+ log.log '- Haml version: ', false
149
+ log.info Gem.loaded_specs['haml'].version
150
+ log.log '- RuboCop version: ', false
151
+ log.info Gem.loaded_specs['rubocop'].version
152
+ log.log '- Ruby version: ', false
153
+ log.info RUBY_VERSION
137
154
  end
138
155
  end
139
156
  end
@@ -35,12 +35,15 @@ module HamlLint
35
35
  private
36
36
 
37
37
  # @param source [String] Haml code to parse
38
- # @raise [Haml::Parser::Error] if there was a problem parsing the document
38
+ # @raise [HamlLint::Exceptions::ParseError] if there was a problem parsing
39
39
  def process_source(source)
40
40
  @source = strip_frontmatter(source)
41
41
  @source_lines = @source.split("\n")
42
42
 
43
43
  @tree = process_tree(Haml::Parser.new(@source, Haml::Options.new).parse)
44
+ rescue Haml::Error => ex
45
+ error = HamlLint::Exceptions::ParseError.new(ex.message, ex.line)
46
+ raise error
44
47
  end
45
48
 
46
49
  # Processes the {Haml::Parser::ParseNode} tree and returns a tree composed
@@ -9,6 +9,9 @@ module HamlLint::Exceptions
9
9
  # Raised when an invalid file path is specified
10
10
  class InvalidFilePath < StandardError; end
11
11
 
12
+ # Raised when a problem occurs parsing a HAML document.
13
+ class ParseError < ::Haml::SyntaxError; end
14
+
12
15
  # Raised when attempting to execute `Runner` with options that would result in
13
16
  # no linters being enabled.
14
17
  class NoLintersError < StandardError; end
@@ -0,0 +1,21 @@
1
+ module HamlLint
2
+ # Checks for final newlines at the end of a file.
3
+ class Linter::FinalNewline < Linter
4
+ include LinterRegistry
5
+
6
+ def visit_root(_node)
7
+ return if document.source.empty?
8
+
9
+ dummy_node = Struct.new(:line).new(document.source_lines.count)
10
+ ends_with_newline = document.source.end_with?("\n")
11
+
12
+ if config['present']
13
+ record_lint(dummy_node,
14
+ 'Files should end with a trailing newline') unless ends_with_newline
15
+ else
16
+ record_lint(dummy_node,
17
+ 'Files should not end with a trailing newline') if ends_with_newline
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module HamlLint
2
+ # Checks the character used for indentation.
3
+ class Linter::Indentation < Linter
4
+ include LinterRegistry
5
+
6
+ # Allowed leading indentation for each character type.
7
+ INDENT_REGEX = {
8
+ space: /^[ ]*(?!\t)/,
9
+ tab: /^\t*(?![ ])/,
10
+ }
11
+
12
+ def visit_root(_node)
13
+ regex = INDENT_REGEX[config['character'].to_sym]
14
+ dummy_node = Struct.new(:line)
15
+
16
+ document.source_lines.each_with_index do |line, index|
17
+ next if line =~ regex
18
+
19
+ record_lint dummy_node.new(index + 1), 'Line contains tabs in indentation'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -30,7 +30,7 @@ module HamlLint
30
30
  private
31
31
 
32
32
  def outputs_string_literal?(script_node)
33
- tree = parse_ruby(script_node.script)
33
+ return unless tree = parse_ruby(script_node.script)
34
34
  [:str, :dstr].include?(tree.type) &&
35
35
  !starts_with_reserved_character?(tree.children.first)
36
36
  rescue ::Parser::SyntaxError # rubocop:disable Lint/HandleExceptions
@@ -22,7 +22,6 @@ module HamlLint
22
22
  #
23
23
  # @param output [String] the output to send
24
24
  # @param newline [true,false] whether to append a newline
25
- # @return [nil]
26
25
  def log(output, newline = true)
27
26
  @out.print(output)
28
27
  @out.print("\n") if newline
@@ -32,7 +31,6 @@ module HamlLint
32
31
  # If output destination is not a TTY, behaves the same as {#log}.
33
32
  #
34
33
  # @param args [Array<String>]
35
- # @return [nil]
36
34
  def bold(*args)
37
35
  color('1', *args)
38
36
  end
@@ -41,7 +39,6 @@ module HamlLint
41
39
  # If output destination is not a TTY, behaves the same as {#log}.
42
40
  #
43
41
  # @param args [Array<String>]
44
- # @return [nil]
45
42
  def error(*args)
46
43
  color(31, *args)
47
44
  end
@@ -50,7 +47,6 @@ module HamlLint
50
47
  # If output destination is not a TTY, behaves the same as {#log}.
51
48
  #
52
49
  # @param args [Array<String>]
53
- # @return [nil]
54
50
  def bold_error(*args)
55
51
  color('1;31', *args)
56
52
  end
@@ -59,7 +55,6 @@ module HamlLint
59
55
  # If output destination is not a TTY, behaves the same as {#log}.
60
56
  #
61
57
  # @param args [Array<String>]
62
- # @return [nil]
63
58
  def success(*args)
64
59
  color(32, *args)
65
60
  end
@@ -68,29 +63,23 @@ module HamlLint
68
63
  # If output destination is not a TTY, behaves the same as {#log}.
69
64
  #
70
65
  # @param args [Array<String>]
71
- # @return [nil]
72
66
  def warning(*args)
73
67
  color(33, *args)
74
68
  end
75
69
 
76
- # Print specified output in bold face in a color indicative of a warning.
77
- # If output destination is not a TTY, behaves the same as {#log}.
78
- #
79
- # @param args [Array<String>]
80
- # @return [nil]
81
- def bold_warning(*args)
82
- color('1;33', *args)
83
- end
84
-
85
70
  # Print the specified output in a color indicating information.
86
71
  # If output destination is not a TTY, behaves the same as {#log}.
87
72
  #
88
73
  # @param args [Array<String>]
89
- # @return [nil]
90
74
  def info(*args)
91
75
  color(36, *args)
92
76
  end
93
77
 
78
+ # Print a blank line.
79
+ def newline
80
+ log('')
81
+ end
82
+
94
83
  # Whether this logger is outputting to a TTY.
95
84
  #
96
85
  # @return [true,false]
@@ -14,15 +14,15 @@ module HamlLint
14
14
  @document = document
15
15
  end
16
16
 
17
- # Transforms the given {Haml::Parser::ParseNode} into its corresponding
18
- # {HamlLint::Tree::Node}.
17
+ # Converts the given HAML parse node into its corresponding HAML-Lint parse
18
+ # node.
19
+ #
20
+ # @param haml_node [Haml::Parser::ParseNode]
21
+ # @return [HamlLint::Tree::Node]
19
22
  def transform(haml_node)
20
23
  node_class = "#{HamlLint::Utils.camel_case(haml_node.type.to_s)}Node"
21
24
 
22
25
  HamlLint::Tree.const_get(node_class).new(@document, haml_node)
23
- rescue NameError
24
- # TODO: Wrap in parser error?
25
- raise
26
26
  end
27
27
  end
28
28
  end
@@ -91,6 +91,10 @@ module HamlLint
91
91
  parser.on_tail('-v', '--version', 'Display version') do
92
92
  @options[:version] = true
93
93
  end
94
+
95
+ parser.on_tail('-V', '--verbose-version', 'Display verbose version information') do
96
+ @options[:verbose_version] = true
97
+ end
94
98
  end
95
99
  end
96
100
  end
@@ -50,7 +50,7 @@ module HamlLint
50
50
  def collect_lints(file, linter_selector, config)
51
51
  begin
52
52
  document = HamlLint::Document.new(File.read(file), file: file, config: config)
53
- rescue Haml::Error => ex
53
+ rescue HamlLint::Exceptions::ParseError => ex
54
54
  return [HamlLint::Lint.new(nil, file, ex.line, ex.to_s, :error)]
55
55
  end
56
56
 
@@ -142,9 +142,10 @@ module HamlLint::Tree
142
142
  # @example For `%tag.class(lang=en)`, this returns:
143
143
  # "lang=en"
144
144
  #
145
- # @return [String] source without the surrounding parentheses
145
+ # @return [String,nil] source without the surrounding parentheses, or `nil`
146
+ # if it has not been defined
146
147
  def html_attributes_source
147
- dynamic_attributes_source[:html] || ''
148
+ dynamic_attributes_source[:html][/\A\((.*)\)\z/, 1] if html_attributes?
148
149
  end
149
150
 
150
151
  # Name of the HTML tag.
@@ -169,7 +170,7 @@ module HamlLint::Tree
169
170
  # @return [String,nil] string source of object reference or `nil` if it has
170
171
  # not been defined
171
172
  def object_reference_source
172
- (@value[:object_ref] if object_reference?) || ''
173
+ @value[:object_ref][/\A\[(.*)\]\z/, 1] if object_reference?
173
174
  end
174
175
 
175
176
  # Whether this node had a `<` after it signifying that outer whitespace
@@ -185,7 +186,7 @@ module HamlLint::Tree
185
186
  #
186
187
  # @return [true,false]
187
188
  def remove_outer_whitespace?
188
- @value[:nuke_inner_whitespace]
189
+ @value[:nuke_outer_whitespace]
189
190
  end
190
191
 
191
192
  # Returns the script source that will be evaluated to produce this tag's
@@ -196,16 +197,6 @@ module HamlLint::Tree
196
197
  (@value[:value] if @value[:parse]) || ''
197
198
  end
198
199
 
199
- # Returns the static inner content for this tag.
200
- #
201
- # If this tag contains dynamic content of any kind, this will still return
202
- # an empty string, and you'll have to use {#script} to obtain the source.
203
- #
204
- # @return [String]
205
- def text
206
- (@value[:value] if @value[:parse]) || ''
207
- end
208
-
209
200
  private
210
201
 
211
202
  def parsed_attributes
@@ -61,6 +61,9 @@ module HamlLint
61
61
  end
62
62
 
63
63
  # Converts a string containing underscores/hyphens/spaces into CamelCase.
64
+ #
65
+ # @param str [String]
66
+ # @return [String]
64
67
  def camel_case(str)
65
68
  str.split(/_|-| /).map { |part| part.sub(/^\w/) { |c| c.upcase } }.join
66
69
  end
@@ -110,6 +113,8 @@ module HamlLint
110
113
 
111
114
  # Calls a block of code with a modified set of environment variables,
112
115
  # restoring them once the code has executed.
116
+ #
117
+ # @param env [Hash] environment variables to set
113
118
  def with_environment(env)
114
119
  old_env = {}
115
120
  env.each do |var, value|
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module HamlLint
3
- VERSION = '0.14.1'
3
+ VERSION = '0.15.0'
4
4
  end
data/lib/haml_lint.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # Need to load haml before we can reference some Haml modules in our code
2
+ require 'haml'
3
+
1
4
  require 'haml_lint/constants'
2
5
  require 'haml_lint/exceptions'
3
6
  require 'haml_lint/configuration'
@@ -17,8 +20,6 @@ require 'haml_lint/runner'
17
20
  require 'haml_lint/utils'
18
21
  require 'haml_lint/version'
19
22
 
20
- require 'haml'
21
-
22
23
  # Load all parse tree node classes
23
24
  require 'haml_lint/tree/node'
24
25
  require 'haml_lint/node_transformer'
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.14.1
4
+ version: 0.15.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: 2015-06-10 00:00:00.000000000 Z
12
+ date: 2015-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: haml
@@ -109,8 +109,10 @@ files:
109
109
  - lib/haml_lint/linter/consecutive_comments.rb
110
110
  - lib/haml_lint/linter/consecutive_silent_scripts.rb
111
111
  - lib/haml_lint/linter/empty_script.rb
112
+ - lib/haml_lint/linter/final_newline.rb
112
113
  - lib/haml_lint/linter/html_attributes.rb
113
114
  - lib/haml_lint/linter/implicit_div.rb
115
+ - lib/haml_lint/linter/indentation.rb
114
116
  - lib/haml_lint/linter/leading_comment_space.rb
115
117
  - lib/haml_lint/linter/line_length.rb
116
118
  - lib/haml_lint/linter/multiline_pipe.rb
@@ -174,3 +176,4 @@ signing_key:
174
176
  specification_version: 4
175
177
  summary: HAML lint tool
176
178
  test_files: []
179
+ has_rdoc: