theme-check 1.6.1 → 1.6.2
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/CHANGELOG.md +6 -0
- data/docs/api/html_check.md +7 -7
- data/docs/api/liquid_check.md +10 -10
- data/docs/checks/convert_include_to_render.md +1 -1
- data/docs/checks/missing_enable_comment.md +1 -1
- data/lib/theme_check/analyzer.rb +15 -15
- data/lib/theme_check/asset_file.rb +1 -1
- data/lib/theme_check/check.rb +2 -2
- data/lib/theme_check/checks/html_parsing_error.rb +2 -2
- data/lib/theme_check/checks/matching_translations.rb +1 -1
- data/lib/theme_check/checks/missing_template.rb +6 -6
- data/lib/theme_check/checks/nested_snippet.rb +2 -2
- data/lib/theme_check/checks/required_layout_theme_object.rb +2 -2
- data/lib/theme_check/checks/syntax_error.rb +5 -5
- data/lib/theme_check/checks/template_length.rb +2 -2
- data/lib/theme_check/checks/undefined_object.rb +7 -7
- data/lib/theme_check/checks/unused_assign.rb +4 -4
- data/lib/theme_check/checks/unused_snippet.rb +7 -7
- data/lib/theme_check/checks/valid_json.rb +1 -1
- data/lib/theme_check/checks.rb +2 -2
- data/lib/theme_check/cli.rb +1 -1
- data/lib/theme_check/corrector.rb +6 -6
- data/lib/theme_check/disabled_check.rb +3 -3
- data/lib/theme_check/disabled_checks.rb +9 -9
- data/lib/theme_check/html_node.rb +36 -28
- data/lib/theme_check/html_visitor.rb +6 -6
- data/lib/theme_check/in_memory_storage.rb +1 -1
- data/lib/theme_check/json_check.rb +2 -2
- data/lib/theme_check/language_server/diagnostics_tracker.rb +8 -8
- data/lib/theme_check/{template.rb → liquid_file.rb} +2 -2
- data/lib/theme_check/liquid_node.rb +291 -0
- data/lib/theme_check/{visitor.rb → liquid_visitor.rb} +4 -4
- data/lib/theme_check/locale_diff.rb +5 -5
- data/lib/theme_check/node.rb +12 -225
- data/lib/theme_check/offense.rb +15 -15
- data/lib/theme_check/position.rb +1 -1
- data/lib/theme_check/theme.rb +1 -1
- data/lib/theme_check/{template_rewriter.rb → theme_file_rewriter.rb} +1 -1
- data/lib/theme_check/version.rb +1 -1
- data/lib/theme_check.rb +11 -10
- data/theme-check.gemspec +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e992338f154cdf5da965bae74af6907af89156170b5bdcf599f8f15b9708bb87
|
4
|
+
data.tar.gz: 27071bf8d98359410d2486a62502f2e7453465771b932a77a6c27785ba00abbb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
|
data/docs/api/html_check.md
CHANGED
@@ -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
|
20
|
-
node.value
|
21
|
-
node.
|
22
|
-
node.parent
|
23
|
-
node.children
|
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
|
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.
|
30
|
+
node.attributes["class"] # Get the class attribute of the img element.
|
31
31
|
end
|
32
32
|
|
33
33
|
def on_a(node)
|
data/docs/api/liquid_check.md
CHANGED
@@ -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
|
20
|
-
node.value
|
21
|
-
node.
|
22
|
-
node.parent
|
23
|
-
node.children
|
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
|
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
|
42
|
-
add_offense("Describe the problem...",
|
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
|
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
|
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
|
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
|
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
|
|
data/lib/theme_check/analyzer.rb
CHANGED
@@ -32,12 +32,12 @@ module ThemeCheck
|
|
32
32
|
def analyze_theme
|
33
33
|
reset
|
34
34
|
|
35
|
-
liquid_visitor =
|
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 |
|
39
|
-
liquid_visitor.
|
40
|
-
html_visitor.
|
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 =
|
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 |
|
57
|
-
liquid_visitor.
|
58
|
-
html_visitor.
|
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 =
|
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 |
|
66
|
-
if
|
67
|
-
liquid_visitor.
|
68
|
-
html_visitor.
|
69
|
-
elsif
|
70
|
-
@json_checks.single_file.call(:on_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
|
data/lib/theme_check/check.rb
CHANGED
@@ -91,8 +91,8 @@ module ThemeCheck
|
|
91
91
|
@offenses ||= []
|
92
92
|
end
|
93
93
|
|
94
|
-
def add_offense(message, node: nil,
|
95
|
-
offenses << Offense.new(check: self, message: message,
|
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,
|
9
|
-
add_offense("HTML in this template can not be parsed: #{exception.message}",
|
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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module ThemeCheck
|
3
|
-
# Reports missing include/render/section
|
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
|
-
|
16
|
-
if
|
17
|
-
add_missing_offense("snippets/#{
|
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
|
-
|
25
|
-
add_missing_offense("sections/#{
|
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.
|
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.
|
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.
|
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.
|
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.
|
11
|
-
add_exception_as_offense(warning,
|
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,
|
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,
|
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
|
-
|
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.
|
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}]",
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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 |
|
27
|
-
add_offense("This
|
28
|
-
corrector.remove(@theme,
|
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| @
|
34
|
+
theme.snippets.reject { |t| @used_snippets.include?(t.name) }
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|