theme-check 1.6.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/docs/api/html_check.md +7 -7
  4. data/docs/api/liquid_check.md +10 -10
  5. data/docs/checks/convert_include_to_render.md +1 -1
  6. data/docs/checks/missing_enable_comment.md +1 -1
  7. data/lib/theme_check/analyzer.rb +15 -15
  8. data/lib/theme_check/asset_file.rb +1 -1
  9. data/lib/theme_check/check.rb +2 -2
  10. data/lib/theme_check/checks/html_parsing_error.rb +2 -2
  11. data/lib/theme_check/checks/matching_translations.rb +1 -1
  12. data/lib/theme_check/checks/missing_template.rb +6 -6
  13. data/lib/theme_check/checks/nested_snippet.rb +2 -2
  14. data/lib/theme_check/checks/required_layout_theme_object.rb +2 -2
  15. data/lib/theme_check/checks/syntax_error.rb +5 -5
  16. data/lib/theme_check/checks/template_length.rb +2 -2
  17. data/lib/theme_check/checks/undefined_object.rb +7 -7
  18. data/lib/theme_check/checks/unused_assign.rb +4 -4
  19. data/lib/theme_check/checks/unused_snippet.rb +7 -7
  20. data/lib/theme_check/checks/valid_json.rb +1 -1
  21. data/lib/theme_check/checks.rb +2 -2
  22. data/lib/theme_check/cli.rb +1 -1
  23. data/lib/theme_check/corrector.rb +6 -6
  24. data/lib/theme_check/disabled_check.rb +3 -3
  25. data/lib/theme_check/disabled_checks.rb +9 -9
  26. data/lib/theme_check/html_node.rb +36 -28
  27. data/lib/theme_check/html_visitor.rb +6 -6
  28. data/lib/theme_check/in_memory_storage.rb +1 -1
  29. data/lib/theme_check/json_check.rb +2 -2
  30. data/lib/theme_check/language_server/diagnostics_tracker.rb +8 -8
  31. data/lib/theme_check/{template.rb → liquid_file.rb} +2 -2
  32. data/lib/theme_check/liquid_node.rb +291 -0
  33. data/lib/theme_check/{visitor.rb → liquid_visitor.rb} +4 -4
  34. data/lib/theme_check/locale_diff.rb +5 -5
  35. data/lib/theme_check/node.rb +12 -225
  36. data/lib/theme_check/offense.rb +15 -15
  37. data/lib/theme_check/position.rb +1 -1
  38. data/lib/theme_check/theme.rb +1 -1
  39. data/lib/theme_check/{template_rewriter.rb → theme_file_rewriter.rb} +1 -1
  40. data/lib/theme_check/version.rb +1 -1
  41. data/lib/theme_check.rb +11 -10
  42. data/theme-check.gemspec +1 -1
  43. metadata +8 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d1302267ab60bbc2471f2f22491a88b64f6021869064717bacaf79d39d31f97
4
- data.tar.gz: d67dabb3456b2a9b6f06235962dab7fc74be3e4ffa0dc7582004c212bc98de6b
3
+ metadata.gz: e992338f154cdf5da965bae74af6907af89156170b5bdcf599f8f15b9708bb87
4
+ data.tar.gz: 27071bf8d98359410d2486a62502f2e7453465771b932a77a6c27785ba00abbb
5
5
  SHA512:
6
- metadata.gz: 87f6c5f2418d5929ef94c59b718770d674206cf6fa1d2a3039789dd6dac8fbf1c31e53dc11c495808ee6ddae5ea796cfa2b8bc6b4734fdc7d37b8660703d2233
7
- data.tar.gz: 14b5ed0c2444f3d42449a7f88a95e9e280997fa5d4893a16cca2472e918d70a9d26ce1c46977a7bb51e8d3e082f8240fac163c89c3c95e7dcd3cc57227d2b4ae
6
+ metadata.gz: 33969efb3cc9bd670ce7a15a419e7419824e8e48ab5951e1f527f116e3aec42ca01c214eb50cd0eb1058fd6c5975c353f3b84024b990dcbad3a45f27cbb9380f
7
+ data.tar.gz: 410dd3f410c5dd0fe23533eae5716d8bfefec6fd4bc57e68c77dfe14832e7c498854d2dc6728b25467188d887860d97d92747cf915ab1c669f40226b46a371ad
data/CHANGELOG.md CHANGED
@@ -1,4 +1,10 @@
1
1
 
2
+ v1.6.2 / 2021-09-16
3
+ ===================
4
+
5
+ * SpaceInsideBraces fixup for tags without arguments ([#458](https://github.com/shopify/theme-check/issues/458))
6
+ * Fix UnusedAssign bug when variable used in for loop range by bumping Liquid to 5.1 ([#456](https://github.com/shopify/theme-check/issues/456))
7
+
2
8
  v1.6.1 / 2021-09-15
3
9
  ===================
4
10
 
@@ -16,18 +16,18 @@ module ThemeCheck
16
16
  severity :suggestion # :error or :style
17
17
 
18
18
  def on_document(node)
19
- # Called with the root node of all templates
20
- node.value # is an instance of Nokogiri::XML::Node
21
- node.template # is the template being analyzed, See lib/theme_check/template.rb.
22
- node.parent # is the parent node.
23
- node.children # are the children nodes.
19
+ # Called with the root node of all theme files
20
+ node.value # is an instance of Nokogiri::XML::Node
21
+ node.theme_file # is the html_file being analyzed, See lib/theme_check/theme_file.rb.
22
+ node.parent # is the parent node.
23
+ node.children # are the children nodes.
24
24
  # See lib/theme_check/html_node.rb for more helper methods
25
- theme # Gives you access to all the templates in the theme. See lib/theme_check/theme.rb.
25
+ theme # Gives you access to all the theme files in the theme. See lib/theme_check/theme.rb.
26
26
  end
27
27
 
28
28
  def on_img(node)
29
29
  # Called for every <img> element in the file.
30
- node.attrbutes["class"] # Get the class attribute of the img element.
30
+ node.attributes["class"] # Get the class attribute of the img element.
31
31
  end
32
32
 
33
33
  def on_a(node)
@@ -16,13 +16,13 @@ module ThemeCheck
16
16
  severity :suggestion # :error or :style
17
17
 
18
18
  def on_document(node)
19
- # Called with the root node of all templates
20
- node.value # is the original Liquid object for this node. See Liquid source code for details.
21
- node.template # is the template being analyzed, See lib/theme_check/template.rb.
22
- node.parent # is the parent node.
23
- node.children # are the children nodes.
19
+ # Called with the root node of all liquid_file
20
+ node.value # is the original Liquid object for this node. See Liquid source code for details.
21
+ node.theme_file # is the liquid_file being analyzed, See lib/theme_check/liquid_file.rb.
22
+ node.parent # is the parent node.
23
+ node.children # are the children nodes.
24
24
  # See lib/theme_check/node.rb for more helper methods
25
- theme # Gives you access to all the templates in the theme. See lib/theme_check/theme.rb.
25
+ theme # Gives you access to all the theme files in the theme. See lib/theme_check/theme.rb.
26
26
  end
27
27
 
28
28
  def on_node(node)
@@ -38,8 +38,8 @@ module ThemeCheck
38
38
 
39
39
  # If you find an issue, add an offense:
40
40
  add_offense("Describe the problem...", node: node)
41
- # Or, if the offense is related to the whole template:
42
- add_offense("Describe the problem...", template: node.template)
41
+ # Or, if the offense is related to the whole theme file:
42
+ add_offense("Describe the problem...", theme_file: node.theme_file)
43
43
  end
44
44
 
45
45
  def on_assign(node)
@@ -50,7 +50,7 @@ module ThemeCheck
50
50
  # Called for every `String` (including inside if conditions).
51
51
  if node.parent.block?
52
52
  # If parent is a block, `node.value` is a String written directly to the output when
53
- # the template is rendered.
53
+ # the theme file is rendered.
54
54
  end
55
55
  end
56
56
 
@@ -59,7 +59,7 @@ module ThemeCheck
59
59
  end
60
60
 
61
61
  def on_error(exception)
62
- # Called each time a Liquid exception is raised while parsing the template
62
+ # Called each time a Liquid exception is raised while parsing the theme file
63
63
  end
64
64
 
65
65
  def on_end
@@ -2,7 +2,7 @@
2
2
 
3
3
  The `include` tag is [deprecated][deprecated]. This tag exists to enforce the use of the `render` tag instead of `include`.
4
4
 
5
- The `include` tag works similarly to the `render` tag, but it lets the code inside of the snippet to access and overwrite the variables within its parent template. The `include` tag has been deprecated because the way that it handles variables reduces performance and makes theme code harder to both read and maintain.
5
+ The `include` tag works similarly to the `render` tag, but it lets the code inside of the snippet to access and overwrite the variables within its parent theme file. The `include` tag has been deprecated because the way that it handles variables reduces performance and makes theme code harder to both read and maintain.
6
6
 
7
7
  ## Check Details
8
8
 
@@ -1,6 +1,6 @@
1
1
  # Prevent missing theme-check-enable comments (`MissingEnableComment`)
2
2
 
3
- When `theme-check-disable` is used in the middle of a template, the corresponding `theme-check-enable` comment should also be included.
3
+ When `theme-check-disable` is used in the middle of a theme file, the corresponding `theme-check-enable` comment should also be included.
4
4
 
5
5
  ## Check Details
6
6
 
@@ -32,12 +32,12 @@ module ThemeCheck
32
32
  def analyze_theme
33
33
  reset
34
34
 
35
- liquid_visitor = Visitor.new(@liquid_checks, @disabled_checks)
35
+ liquid_visitor = LiquidVisitor.new(@liquid_checks, @disabled_checks)
36
36
  html_visitor = HtmlVisitor.new(@html_checks)
37
37
  ThemeCheck.with_liquid_c_disabled do
38
- @theme.liquid.each do |template|
39
- liquid_visitor.visit_template(template)
40
- html_visitor.visit_template(template)
38
+ @theme.liquid.each do |liquid_file|
39
+ liquid_visitor.visit_liquid_file(liquid_file)
40
+ html_visitor.visit_liquid_file(liquid_file)
41
41
  end
42
42
  end
43
43
 
@@ -51,23 +51,23 @@ module ThemeCheck
51
51
 
52
52
  ThemeCheck.with_liquid_c_disabled do
53
53
  # Call all checks that run on the whole theme
54
- liquid_visitor = Visitor.new(@liquid_checks.whole_theme, @disabled_checks)
54
+ liquid_visitor = LiquidVisitor.new(@liquid_checks.whole_theme, @disabled_checks)
55
55
  html_visitor = HtmlVisitor.new(@html_checks.whole_theme)
56
- @theme.liquid.each do |template|
57
- liquid_visitor.visit_template(template)
58
- html_visitor.visit_template(template)
56
+ @theme.liquid.each do |liquid_file|
57
+ liquid_visitor.visit_liquid_file(liquid_file)
58
+ html_visitor.visit_liquid_file(liquid_file)
59
59
  end
60
60
  @theme.json.each { |json_file| @json_checks.whole_theme.call(:on_file, json_file) }
61
61
 
62
62
  # Call checks that run on a single files, only on specified file
63
- liquid_visitor = Visitor.new(@liquid_checks.single_file, @disabled_checks)
63
+ liquid_visitor = LiquidVisitor.new(@liquid_checks.single_file, @disabled_checks)
64
64
  html_visitor = HtmlVisitor.new(@html_checks.single_file)
65
- files.each do |file|
66
- if file.liquid?
67
- liquid_visitor.visit_template(file)
68
- html_visitor.visit_template(file)
69
- elsif file.json?
70
- @json_checks.single_file.call(:on_file, file)
65
+ files.each do |theme_file|
66
+ if theme_file.liquid?
67
+ liquid_visitor.visit_liquid_file(theme_file)
68
+ html_visitor.visit_liquid_file(theme_file)
69
+ elsif theme_file.json?
70
+ @json_checks.single_file.call(:on_file, theme_file)
71
71
  end
72
72
  end
73
73
  end
@@ -10,7 +10,7 @@ module ThemeCheck
10
10
  end
11
11
 
12
12
  def rewriter
13
- @rewriter ||= TemplateRewriter.new(@relative_path, source)
13
+ @rewriter ||= ThemeFileRewriter.new(@relative_path, source)
14
14
  end
15
15
 
16
16
  def write
@@ -91,8 +91,8 @@ module ThemeCheck
91
91
  @offenses ||= []
92
92
  end
93
93
 
94
- def add_offense(message, node: nil, template: node&.template, markup: nil, line_number: nil, node_markup_offset: 0, &block)
95
- offenses << Offense.new(check: self, message: message, template: template, node: node, markup: markup, line_number: line_number, node_markup_offset: node_markup_offset, correction: block)
94
+ def add_offense(message, node: nil, theme_file: node&.theme_file, markup: nil, line_number: nil, node_markup_offset: 0, &block)
95
+ offenses << Offense.new(check: self, message: message, theme_file: theme_file, node: node, markup: markup, line_number: line_number, node_markup_offset: node_markup_offset, correction: block)
96
96
  end
97
97
 
98
98
  def severity
@@ -5,8 +5,8 @@ module ThemeCheck
5
5
  category :html
6
6
  doc docs_url(__FILE__)
7
7
 
8
- def on_parse_error(exception, template)
9
- add_offense("HTML in this template can not be parsed: #{exception.message}", template: template)
8
+ def on_parse_error(exception, theme_file)
9
+ add_offense("HTML in this template can not be parsed: #{exception.message}", theme_file: theme_file)
10
10
  end
11
11
  end
12
12
  end
@@ -23,7 +23,7 @@ module ThemeCheck
23
23
 
24
24
  @files.each do |file|
25
25
  diff = LocaleDiff.new(@theme.default_locale_json.content, file.content)
26
- diff.add_as_offenses(self, template: file)
26
+ diff.add_as_offenses(self, theme_file: file)
27
27
  end
28
28
  end
29
29
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- # Reports missing include/render/section template
3
+ # Reports missing include/render/section liquid file
4
4
  class MissingTemplate < LiquidCheck
5
5
  severity :suggestion
6
6
  category :liquid
@@ -12,17 +12,17 @@ module ThemeCheck
12
12
  end
13
13
 
14
14
  def on_include(node)
15
- template = node.value.template_name_expr
16
- if template.is_a?(String)
17
- add_missing_offense("snippets/#{template}", node: node)
15
+ snippet = node.value.template_name_expr
16
+ if snippet.is_a?(String)
17
+ add_missing_offense("snippets/#{snippet}", node: node)
18
18
  end
19
19
  end
20
20
 
21
21
  alias_method :on_render, :on_include
22
22
 
23
23
  def on_section(node)
24
- template = node.value.section_name
25
- add_missing_offense("sections/#{template}", node: node)
24
+ section = node.value.section_name
25
+ add_missing_offense("sections/#{section}", node: node)
26
26
  end
27
27
 
28
28
  private
@@ -26,12 +26,12 @@ module ThemeCheck
26
26
  end
27
27
 
28
28
  def on_document(node)
29
- @templates[node.template.name] = TemplateInfo.new(Set.new)
29
+ @templates[node.theme_file.name] = TemplateInfo.new(Set.new)
30
30
  end
31
31
 
32
32
  def on_include(node)
33
33
  if node.value.template_name_expr.is_a?(String)
34
- @templates[node.template.name].includes << node
34
+ @templates[node.theme_file.name].includes << node
35
35
  end
36
36
  end
37
37
  alias_method :on_render, :on_include
@@ -14,7 +14,7 @@ module ThemeCheck
14
14
  end
15
15
 
16
16
  def on_document(node)
17
- @layout_theme_node = node if node.template.name == LAYOUT_FILENAME
17
+ @layout_theme_node = node if node.theme_file.name == LAYOUT_FILENAME
18
18
  end
19
19
 
20
20
  def on_variable(node)
@@ -25,7 +25,7 @@ module ThemeCheck
25
25
  end
26
26
 
27
27
  def after_document(node)
28
- return unless node.template.name == LAYOUT_FILENAME
28
+ return unless node.theme_file.name == LAYOUT_FILENAME
29
29
 
30
30
  add_missing_object_offense("content_for_layout") unless @content_for_layout_found
31
31
  add_missing_object_offense("content_for_header") unless @content_for_header_found
@@ -7,23 +7,23 @@ module ThemeCheck
7
7
  doc docs_url(__FILE__)
8
8
 
9
9
  def on_document(node)
10
- node.template.warnings.each do |warning|
11
- add_exception_as_offense(warning, template: node.template)
10
+ node.theme_file.warnings.each do |warning|
11
+ add_exception_as_offense(warning, theme_file: node.theme_file)
12
12
  end
13
13
  end
14
14
 
15
15
  def on_error(exception)
16
- add_exception_as_offense(exception, template: theme[exception.template_name])
16
+ add_exception_as_offense(exception, theme_file: theme[exception.template_name])
17
17
  end
18
18
 
19
19
  private
20
20
 
21
- def add_exception_as_offense(exception, template:)
21
+ def add_exception_as_offense(exception, theme_file:)
22
22
  add_offense(
23
23
  exception.to_s(false).sub(/ in ".*"$/, ''),
24
24
  line_number: exception.line_number,
25
25
  markup: exception.markup_context&.sub(/^in "(.*)"$/, '\1'),
26
- template: template,
26
+ theme_file: theme_file,
27
27
  )
28
28
  end
29
29
  end
@@ -29,9 +29,9 @@ module ThemeCheck
29
29
  end
30
30
 
31
31
  def after_document(node)
32
- lines = node.template.source.count("\n") - @excluded_lines
32
+ lines = node.theme_file.source.count("\n") - @excluded_lines
33
33
  if lines > @max_length
34
- add_offense("Template has too many lines [#{lines}/#{@max_length}]", template: node.template)
34
+ add_offense("Template has too many lines [#{lines}/#{@max_length}]", theme_file: node.theme_file)
35
35
  end
36
36
  end
37
37
 
@@ -62,22 +62,22 @@ module ThemeCheck
62
62
 
63
63
  def on_document(node)
64
64
  return if ignore?(node)
65
- @files[node.template.name] = TemplateInfo.new
65
+ @files[node.theme_file.name] = TemplateInfo.new
66
66
  end
67
67
 
68
68
  def on_assign(node)
69
69
  return if ignore?(node)
70
- @files[node.template.name].all_assigns[node.value.to] = node
70
+ @files[node.theme_file.name].all_assigns[node.value.to] = node
71
71
  end
72
72
 
73
73
  def on_capture(node)
74
74
  return if ignore?(node)
75
- @files[node.template.name].all_captures[node.value.instance_variable_get('@to')] = node
75
+ @files[node.theme_file.name].all_captures[node.value.instance_variable_get('@to')] = node
76
76
  end
77
77
 
78
78
  def on_for(node)
79
79
  return if ignore?(node)
80
- @files[node.template.name].all_forloops[node.value.variable_name] = node
80
+ @files[node.theme_file.name].all_forloops[node.value.variable_name] = node
81
81
  end
82
82
 
83
83
  def on_include(_node)
@@ -90,7 +90,7 @@ module ThemeCheck
90
90
  return unless node.value.template_name_expr.is_a?(String)
91
91
 
92
92
  snippet_name = "snippets/#{node.value.template_name_expr}"
93
- @files[node.template.name].add_render(
93
+ @files[node.theme_file.name].add_render(
94
94
  name: snippet_name,
95
95
  node: node,
96
96
  )
@@ -98,7 +98,7 @@ module ThemeCheck
98
98
 
99
99
  def on_variable_lookup(node)
100
100
  return if ignore?(node)
101
- @files[node.template.name].add_variable_lookup(
101
+ @files[node.theme_file.name].add_variable_lookup(
102
102
  name: node.value.name,
103
103
  node: node,
104
104
  )
@@ -130,7 +130,7 @@ module ThemeCheck
130
130
  private
131
131
 
132
132
  def ignore?(node)
133
- @exclude_snippets && node.template.snippet?
133
+ @exclude_snippets && node.theme_file.snippet?
134
134
  end
135
135
 
136
136
  def each_template
@@ -25,21 +25,21 @@ module ThemeCheck
25
25
  end
26
26
 
27
27
  def on_document(node)
28
- @templates[node.template.name] = TemplateInfo.new(Set.new, {}, Set.new)
28
+ @templates[node.theme_file.name] = TemplateInfo.new(Set.new, {}, Set.new)
29
29
  end
30
30
 
31
31
  def on_assign(node)
32
- @templates[node.template.name].assign_nodes[node.value.to] = node
32
+ @templates[node.theme_file.name].assign_nodes[node.value.to] = node
33
33
  end
34
34
 
35
35
  def on_include(node)
36
36
  if node.value.template_name_expr.is_a?(String)
37
- @templates[node.template.name].includes << "snippets/#{node.value.template_name_expr}"
37
+ @templates[node.theme_file.name].includes << "snippets/#{node.value.template_name_expr}"
38
38
  end
39
39
  end
40
40
 
41
41
  def on_variable_lookup(node)
42
- @templates[node.template.name].used_assigns << node.value.name
42
+ @templates[node.theme_file.name].used_assigns << node.value.name
43
43
  end
44
44
 
45
45
  def on_end
@@ -8,30 +8,30 @@ module ThemeCheck
8
8
  doc docs_url(__FILE__)
9
9
 
10
10
  def initialize
11
- @used_templates = Set.new
11
+ @used_snippets = Set.new
12
12
  end
13
13
 
14
14
  def on_include(node)
15
15
  if node.value.template_name_expr.is_a?(String)
16
- @used_templates << "snippets/#{node.value.template_name_expr}"
16
+ @used_snippets << "snippets/#{node.value.template_name_expr}"
17
17
  else
18
18
  # Can't reliably track unused snippets if an expression is used, ignore this check
19
- @used_templates.clear
19
+ @used_snippets.clear
20
20
  ignore!
21
21
  end
22
22
  end
23
23
  alias_method :on_render, :on_include
24
24
 
25
25
  def on_end
26
- missing_snippets.each do |template|
27
- add_offense("This template is not used", template: template) do |corrector|
28
- corrector.remove(@theme, template.relative_path.to_s)
26
+ missing_snippets.each do |theme_file|
27
+ add_offense("This snippet is not used", theme_file: theme_file) do |corrector|
28
+ corrector.remove(@theme, theme_file.relative_path.to_s)
29
29
  end
30
30
  end
31
31
  end
32
32
 
33
33
  def missing_snippets
34
- theme.snippets.reject { |t| @used_templates.include?(t.name) }
34
+ theme.snippets.reject { |t| @used_snippets.include?(t.name) }
35
35
  end
36
36
  end
37
37
  end
@@ -8,7 +8,7 @@ module ThemeCheck
8
8
  def on_file(file)
9
9
  if file.parse_error
10
10
  message = format_json_parse_error(file.parse_error)
11
- add_offense(message, template: file)
11
+ add_offense(message, theme_file: file)
12
12
  end
13
13
  end
14
14
  end