theme-check 1.2.0 → 1.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/CONTRIBUTING.md +1 -1
- data/bin/theme-check +29 -0
- data/bin/theme-check-language-server +29 -0
- data/config/default.yml +11 -0
- data/config/theme_app_extension.yml +15 -0
- data/docs/checks/app_block_valid_tags.md +40 -0
- data/docs/checks/asset_size_app_block_css.md +1 -1
- data/docs/checks/missing_template.md +25 -0
- data/docs/checks/pagination_size.md +44 -0
- data/docs/checks/undefined_object.md +5 -0
- data/lib/theme_check/check.rb +2 -2
- data/lib/theme_check/checks/app_block_valid_tags.rb +36 -0
- data/lib/theme_check/checks/asset_size_css.rb +3 -3
- data/lib/theme_check/checks/asset_size_javascript.rb +2 -2
- data/lib/theme_check/checks/convert_include_to_render.rb +3 -1
- data/lib/theme_check/checks/deprecate_bgsizes.rb +1 -1
- data/lib/theme_check/checks/deprecate_lazysizes.rb +2 -2
- data/lib/theme_check/checks/img_lazy_loading.rb +1 -1
- data/lib/theme_check/checks/img_width_and_height.rb +3 -3
- data/lib/theme_check/checks/missing_template.rb +21 -5
- data/lib/theme_check/checks/pagination_size.rb +65 -0
- data/lib/theme_check/checks/parser_blocking_javascript.rb +1 -1
- data/lib/theme_check/checks/remote_asset.rb +2 -2
- data/lib/theme_check/checks/space_inside_braces.rb +26 -6
- data/lib/theme_check/checks/undefined_object.rb +1 -1
- data/lib/theme_check/checks/valid_html_translation.rb +1 -1
- data/lib/theme_check/checks.rb +11 -1
- data/lib/theme_check/cli.rb +18 -2
- data/lib/theme_check/corrector.rb +4 -0
- data/lib/theme_check/file_system_storage.rb +12 -0
- data/lib/theme_check/html_check.rb +0 -1
- data/lib/theme_check/html_node.rb +37 -16
- data/lib/theme_check/html_visitor.rb +17 -3
- data/lib/theme_check/json_check.rb +2 -2
- data/lib/theme_check/json_printer.rb +26 -0
- data/lib/theme_check/language_server/handler.rb +6 -2
- data/lib/theme_check/node.rb +6 -4
- data/lib/theme_check/offense.rb +56 -3
- data/lib/theme_check/parsing_helpers.rb +4 -3
- data/lib/theme_check/position.rb +98 -14
- data/lib/theme_check/regex_helpers.rb +5 -2
- data/lib/theme_check/theme.rb +2 -0
- data/lib/theme_check/version.rb +1 -1
- data/lib/theme_check.rb +1 -0
- data/theme-check.gemspec +1 -1
- metadata +12 -10
- data/bin/liquid-server +0 -4
- data/exe/theme-check-language-server.bat +0 -3
- data/exe/theme-check.bat +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bec2f54c12487d444bebd3bb0abad48ec133c4e9504be29857a58c87d82f589
|
4
|
+
data.tar.gz: 2cacd6af05aa3c2af8d40167a04532ed998d24049df7b277f70baf50f0a4e401
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95a61ee91b1a575dead56345172c5472cdb1c314b94aef37814f311ab54d39263a70d51192ea5d276188d06e8ddc32715f9693f7089157e3376bd7c885b1d30a
|
7
|
+
data.tar.gz: 6fe39a2b8944ceb34e48b5a4a84cbb1f544d870b9c38f36dff33ff2e226f76feabb612d9f9e98ce31c2c68209014b46d76adcd0a4dd37224aee3c2ee266e50d0
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,20 @@
|
|
1
1
|
|
2
|
+
v1.3.0 / 2021-08-26
|
3
|
+
==================
|
4
|
+
|
5
|
+
* Add `--output json` option for the CLI ([#392](https://github.com/shopify/theme-check/issues/392))
|
6
|
+
* Add PaginationSize check ([#359](https://github.com/shopify/theme-check/issues/359))
|
7
|
+
* Add ConvertIncludeToRender auto corrector ([#341](https://github.com/shopify/theme-check/issues/341))
|
8
|
+
* Add MissingTemplate auto corrector ([#388](https://github.com/shopify/theme-check/issues/388))
|
9
|
+
* Add `MissingTemplate` `ignore_missing` option ([#394](https://github.com/shopify/theme-check/issues/394))
|
10
|
+
* Fix Windows duplicate .bat file problem ([#400](https://github.com/shopify/theme-check/issues/400))
|
11
|
+
* Fix substring highlighting inside nodes ([#386](https://github.com/shopify/theme-check/issues/386))
|
12
|
+
* Add check for forbidden tags in theme app extension blocks ([#383](https://github.com/shopify/theme-check/issues/383))
|
13
|
+
* Improve HTML parsing of liquid attributes ([#381](https://github.com/shopify/theme-check/issues/381))
|
14
|
+
* Handle escaped file URIs in language server ([#360](https://github.com/shopify/theme-check/issues/360)) ([#382](https://github.com/shopify/theme-check/issues/382))
|
15
|
+
* Change asset size errors into suggestions ([#378](https://github.com/shopify/theme-check/issues/378))
|
16
|
+
* Switch to nokogiri 1.12, since it includes html5 support directly now ([#391](https://github.com/shopify/theme-check/issues/391))
|
17
|
+
|
2
18
|
v1.2.0 / 2021-07-15
|
3
19
|
==================
|
4
20
|
|
data/CONTRIBUTING.md
CHANGED
data/bin/theme-check
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'theme-check' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("theme-check", "theme-check")
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'theme-check-language-server' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("theme-check", "theme-check-language-server")
|
data/config/default.yml
CHANGED
@@ -23,6 +23,7 @@ LiquidTag:
|
|
23
23
|
MissingTemplate:
|
24
24
|
enabled: true
|
25
25
|
ignore: []
|
26
|
+
ignore_missing: []
|
26
27
|
|
27
28
|
NestedSnippet:
|
28
29
|
enabled: true
|
@@ -177,3 +178,13 @@ AssetSizeAppBlockCSS:
|
|
177
178
|
enabled: false
|
178
179
|
ignore: []
|
179
180
|
threshold_in_bytes: 100_000
|
181
|
+
|
182
|
+
AppBlockValidTags:
|
183
|
+
enabled: false
|
184
|
+
ignore: []
|
185
|
+
|
186
|
+
PaginationSize:
|
187
|
+
enabled: true
|
188
|
+
ignore: []
|
189
|
+
min_size: 1
|
190
|
+
max_size: 50
|
@@ -23,6 +23,7 @@ LiquidTag:
|
|
23
23
|
MissingTemplate:
|
24
24
|
enabled: true
|
25
25
|
ignore: []
|
26
|
+
ignore_missing: []
|
26
27
|
|
27
28
|
NestedSnippet:
|
28
29
|
enabled: true
|
@@ -110,11 +111,13 @@ ParserBlockingScriptTag:
|
|
110
111
|
|
111
112
|
AssetSizeJavaScript:
|
112
113
|
enabled: true
|
114
|
+
severity: suggestion
|
113
115
|
ignore: []
|
114
116
|
threshold_in_bytes: 10_000
|
115
117
|
|
116
118
|
AssetSizeCSS:
|
117
119
|
enabled: true
|
120
|
+
severity: suggestion
|
118
121
|
ignore: []
|
119
122
|
threshold_in_bytes: 100_000
|
120
123
|
|
@@ -144,10 +147,22 @@ HtmlParsingError:
|
|
144
147
|
|
145
148
|
AssetSizeAppBlockJavaScript:
|
146
149
|
enabled: true
|
150
|
+
severity: suggestion
|
147
151
|
ignore: []
|
148
152
|
threshold_in_bytes: 10_000
|
149
153
|
|
150
154
|
AssetSizeAppBlockCSS:
|
151
155
|
enabled: true
|
156
|
+
severity: suggestion
|
152
157
|
ignore: []
|
153
158
|
threshold_in_bytes: 100_000
|
159
|
+
|
160
|
+
AppBlockValidTags:
|
161
|
+
enabled: true
|
162
|
+
ignore: []
|
163
|
+
|
164
|
+
PaginationSize:
|
165
|
+
enabled: true
|
166
|
+
ignore: []
|
167
|
+
min_size: 1
|
168
|
+
max_size: 50
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Reject Forbidden Tags from Theme App Extension Blocks (`AppBlockValidTags`)
|
2
|
+
|
3
|
+
This rule exists to prevent theme app extension blocks from containing forbidden tags in their liquid code.
|
4
|
+
|
5
|
+
## Check Details
|
6
|
+
|
7
|
+
This rule verifies none of the below tags are used in theme app extension blocks.
|
8
|
+
|
9
|
+
- `{% javascript %}`
|
10
|
+
- `{% stylesheet %}`
|
11
|
+
- `{% include 'foo' %}`
|
12
|
+
- `{% layout 'foo' %}`
|
13
|
+
- `{% section 'foo' %}`
|
14
|
+
|
15
|
+
:-1: **Incorrect** code for this check occurs with the use of any of the above tags in the liquid code of theme app extension blocks.
|
16
|
+
|
17
|
+
## Check Options
|
18
|
+
|
19
|
+
The default configuration for theme app extensions is the following:
|
20
|
+
|
21
|
+
```yaml
|
22
|
+
AppBlockValidTags:
|
23
|
+
enabled: true
|
24
|
+
```
|
25
|
+
|
26
|
+
## When Not To Use It
|
27
|
+
|
28
|
+
This rule should not be disabled locally.
|
29
|
+
|
30
|
+
## Version
|
31
|
+
|
32
|
+
This check has been introduced in 1.3.0
|
33
|
+
|
34
|
+
## Resources
|
35
|
+
|
36
|
+
- [Rule Source][codesource]
|
37
|
+
- [Documentation Source][docsource]
|
38
|
+
|
39
|
+
[codesource]: /lib/theme_check/checks/app_block_valid_tags.rb
|
40
|
+
[docsource]: /docs/checks/app_block_valid_tags.md
|
@@ -25,8 +25,33 @@ The default configuration for this check is the following:
|
|
25
25
|
```yaml
|
26
26
|
MissingTemplate:
|
27
27
|
enabled: true
|
28
|
+
ignore_missing: []
|
28
29
|
```
|
29
30
|
|
31
|
+
### `ignore_missing`
|
32
|
+
|
33
|
+
Specify a list of patterns of missing template files to ignore.
|
34
|
+
|
35
|
+
While the `ignore` option will ignore all occurrences of `MissingTemplate` according to the file in which they appear, `ignore_missing` allows ignoring all occurrences of `MissingTemplate` based on the target template, the template being rendered.
|
36
|
+
|
37
|
+
For example:
|
38
|
+
|
39
|
+
```yaml
|
40
|
+
MissingTemplate:
|
41
|
+
ignore_missing:
|
42
|
+
- snippets/icon-*
|
43
|
+
```
|
44
|
+
|
45
|
+
Would ignore offenses on `{% render 'icon-missing' %}` across all theme files.
|
46
|
+
|
47
|
+
```yaml
|
48
|
+
MissingTemplate:
|
49
|
+
ignore:
|
50
|
+
- templates/index.liquid
|
51
|
+
```
|
52
|
+
|
53
|
+
Would ignore all `MissingTemplate` in `templates/index.liquid`, no mater the file being rendered.
|
54
|
+
|
30
55
|
## Version
|
31
56
|
|
32
57
|
This check has been introduced in Theme Check 0.1.0.
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Ensure `paginate` tags are used with performant sizes
|
2
|
+
|
3
|
+
## Check Details
|
4
|
+
|
5
|
+
This check is aimed at keeping response times low.
|
6
|
+
|
7
|
+
:-1: Examples of **incorrect** code for this check:
|
8
|
+
|
9
|
+
```liquid
|
10
|
+
<!-- Using too large of page size -->
|
11
|
+
{% paginate collection.products by 999 %}
|
12
|
+
```
|
13
|
+
|
14
|
+
:+1: Examples of **correct** code for this check:
|
15
|
+
|
16
|
+
```liquid
|
17
|
+
{% paginate collection.products by 12 %}
|
18
|
+
```
|
19
|
+
|
20
|
+
Use sizes that are integers below the `max_size`, and above the `min_size`.
|
21
|
+
|
22
|
+
## Check Options
|
23
|
+
|
24
|
+
The default configuration for this check is the following:
|
25
|
+
|
26
|
+
```yaml
|
27
|
+
PaginationSize:
|
28
|
+
enabled: true
|
29
|
+
ignore: []
|
30
|
+
min_size: 1
|
31
|
+
max_size: 50
|
32
|
+
```
|
33
|
+
|
34
|
+
## When Not To Use It
|
35
|
+
|
36
|
+
N/A
|
37
|
+
|
38
|
+
## Version
|
39
|
+
|
40
|
+
This check has been introduced in Theme Check 1.3.0.
|
41
|
+
|
42
|
+
## Resources
|
43
|
+
|
44
|
+
[paginate]: https://shopify.dev/api/liquid/objects/paginate
|
@@ -33,8 +33,13 @@ The default configuration for this check is the following:
|
|
33
33
|
```yaml
|
34
34
|
UndefinedObject:
|
35
35
|
enabled: true
|
36
|
+
exclude_snippets: true
|
36
37
|
```
|
37
38
|
|
39
|
+
### `exclude_snippets`
|
40
|
+
|
41
|
+
The `exclude_snippets` (Default: `true`) option determines whether to check for undefined objects in snippets file (as objects _may_ be defined as arguments)
|
42
|
+
|
38
43
|
## When Not To Use It
|
39
44
|
|
40
45
|
It is discouraged to disable this rule.
|
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, template: node&.template, markup: nil, line_number: nil, &block)
|
95
|
-
offenses << Offense.new(check: self, message: message, template: template, node: node, markup: markup, line_number: line_number, correction: block)
|
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)
|
96
96
|
end
|
97
97
|
|
98
98
|
def severity
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module ThemeCheck
|
3
|
+
# Reports errors when invalid tags are used in a Theme App
|
4
|
+
# Extension block
|
5
|
+
class AppBlockValidTags < LiquidCheck
|
6
|
+
severity :error
|
7
|
+
category :liquid
|
8
|
+
doc docs_url(__FILE__)
|
9
|
+
|
10
|
+
# Don't allow this check to be disabled with a comment,
|
11
|
+
# since we need to be able to enforce this server-side
|
12
|
+
can_disable false
|
13
|
+
|
14
|
+
OFFENSE_MSG = "Theme app extension blocks cannot contain %s tags"
|
15
|
+
|
16
|
+
def on_javascript(node)
|
17
|
+
add_offense(OFFENSE_MSG % 'javascript', node: node)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_stylesheet(node)
|
21
|
+
add_offense(OFFENSE_MSG % 'stylesheet', node: node)
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_include(node)
|
25
|
+
add_offense(OFFENSE_MSG % 'include', node: node)
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_layout(node)
|
29
|
+
add_offense(OFFENSE_MSG % 'layout', node: node)
|
30
|
+
end
|
31
|
+
|
32
|
+
def on_section(node)
|
33
|
+
add_offense(OFFENSE_MSG % 'section', node: node)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -13,12 +13,12 @@ module ThemeCheck
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def on_link(node)
|
16
|
-
return if node.attributes['rel']
|
17
|
-
file_size = href_to_file_size(node.attributes['href']
|
16
|
+
return if node.attributes['rel'] != "stylesheet"
|
17
|
+
file_size = href_to_file_size(node.attributes['href'])
|
18
18
|
return if file_size.nil?
|
19
19
|
return if file_size <= threshold_in_bytes
|
20
20
|
add_offense(
|
21
|
-
"CSS on every page load exceeding compressed size threshold (#{threshold_in_bytes} Bytes)
|
21
|
+
"CSS on every page load exceeding compressed size threshold (#{threshold_in_bytes} Bytes)",
|
22
22
|
node: node
|
23
23
|
)
|
24
24
|
end
|
@@ -16,7 +16,7 @@ module ThemeCheck
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def on_script(node)
|
19
|
-
file_size = src_to_file_size(node.attributes['src']
|
19
|
+
file_size = src_to_file_size(node.attributes['src'])
|
20
20
|
return if file_size.nil?
|
21
21
|
return if file_size <= threshold_in_bytes
|
22
22
|
add_offense(
|
@@ -28,7 +28,7 @@ module ThemeCheck
|
|
28
28
|
def src_to_file_size(src)
|
29
29
|
# We're kind of intentionally only looking at {{ 'asset' | asset_url }} or full urls in here.
|
30
30
|
# More complicated liquid statements are not in scope.
|
31
|
-
if src =~ /^#{
|
31
|
+
if src =~ /^#{LIQUID_VARIABLE}$/o && src =~ /asset_url/ && src =~ Liquid::QuotedString
|
32
32
|
asset_id = Regexp.last_match(0).gsub(START_OR_END_QUOTE, "")
|
33
33
|
asset = @theme.assets.find { |a| a.name.end_with?("/" + asset_id) }
|
34
34
|
return if asset.nil?
|
@@ -7,7 +7,9 @@ module ThemeCheck
|
|
7
7
|
doc docs_url(__FILE__)
|
8
8
|
|
9
9
|
def on_include(node)
|
10
|
-
add_offense("`include` is deprecated - convert it to `render`", node: node)
|
10
|
+
add_offense("`include` is deprecated - convert it to `render`", node: node) do |corrector|
|
11
|
+
corrector.replace(node, "render \'#{node.value.template_name_expr}\' ")
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
@@ -6,7 +6,7 @@ module ThemeCheck
|
|
6
6
|
doc docs_url(__FILE__)
|
7
7
|
|
8
8
|
def on_div(node)
|
9
|
-
class_list = node.attributes["class"]&.
|
9
|
+
class_list = node.attributes["class"]&.split(" ")
|
10
10
|
add_offense("Use the native loading=\"lazy\" attribute instead of lazysizes", node: node) if class_list&.include?("lazyload")
|
11
11
|
add_offense("Use the CSS imageset attribute instead of data-bgset", node: node) if node.attributes["data-bgset"]
|
12
12
|
end
|
@@ -6,11 +6,11 @@ module ThemeCheck
|
|
6
6
|
doc docs_url(__FILE__)
|
7
7
|
|
8
8
|
def on_img(node)
|
9
|
-
class_list = node.attributes["class"]&.
|
9
|
+
class_list = node.attributes["class"]&.split(" ")
|
10
10
|
add_offense("Use the native loading=\"lazy\" attribute instead of lazysizes", node: node) if class_list&.include?("lazyload")
|
11
11
|
add_offense("Use the native srcset attribute instead of data-srcset", node: node) if node.attributes["data-srcset"]
|
12
12
|
add_offense("Use the native sizes attribute instead of data-sizes", node: node) if node.attributes["data-sizes"]
|
13
|
-
add_offense("Do not set the data-sizes attribute to auto", node: node) if node.attributes["data-sizes"]
|
13
|
+
add_offense("Do not set the data-sizes attribute to auto", node: node) if node.attributes["data-sizes"] == "auto"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -8,7 +8,7 @@ module ThemeCheck
|
|
8
8
|
ACCEPTED_LOADING_VALUES = %w[lazy eager]
|
9
9
|
|
10
10
|
def on_img(node)
|
11
|
-
loading = node.attributes["loading"]&.
|
11
|
+
loading = node.attributes["loading"]&.downcase
|
12
12
|
return if ACCEPTED_LOADING_VALUES.include?(loading)
|
13
13
|
if loading == "auto"
|
14
14
|
add_offense("Prefer loading=\"lazy\" to defer loading of images", node: node)
|