theme-check 0.3.0 → 0.5.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/.rubocop.yml +7 -0
  3. data/CHANGELOG.md +50 -0
  4. data/CONTRIBUTING.md +5 -2
  5. data/README.md +9 -4
  6. data/RELEASING.md +2 -2
  7. data/config/default.yml +7 -0
  8. data/data/shopify_liquid/tags.yml +27 -0
  9. data/docs/checks/CHECK_DOCS_TEMPLATE.md +47 -0
  10. data/docs/checks/asset_size_javascript.md +79 -0
  11. data/docs/checks/convert_include_to_render.md +48 -0
  12. data/docs/checks/default_locale.md +46 -0
  13. data/docs/checks/deprecated_filter.md +46 -0
  14. data/docs/checks/liquid_tag.md +65 -0
  15. data/docs/checks/matching_schema_translations.md +93 -0
  16. data/docs/checks/matching_translations.md +72 -0
  17. data/docs/checks/missing_enable_comment.md +50 -0
  18. data/docs/checks/missing_required_template_files.md +26 -0
  19. data/docs/checks/missing_template.md +40 -0
  20. data/docs/checks/nested_snippet.md +69 -0
  21. data/docs/checks/parser_blocking_javascript.md +97 -0
  22. data/docs/checks/required_directories.md +25 -0
  23. data/docs/checks/required_layout_theme_object.md +28 -0
  24. data/docs/checks/space_inside_braces.md +63 -0
  25. data/docs/checks/syntax_error.md +49 -0
  26. data/docs/checks/template_length.md +50 -0
  27. data/docs/checks/translation_key_exists.md +63 -0
  28. data/docs/checks/undefined_object.md +53 -0
  29. data/docs/checks/unknown_filter.md +45 -0
  30. data/docs/checks/unused_assign.md +47 -0
  31. data/docs/checks/unused_snippet.md +32 -0
  32. data/docs/checks/valid_html_translation.md +53 -0
  33. data/docs/checks/valid_json.md +60 -0
  34. data/docs/checks/valid_schema.md +50 -0
  35. data/lib/theme_check.rb +4 -0
  36. data/lib/theme_check/asset_file.rb +34 -0
  37. data/lib/theme_check/check.rb +19 -9
  38. data/lib/theme_check/checks/asset_size_javascript.rb +74 -0
  39. data/lib/theme_check/checks/convert_include_to_render.rb +1 -1
  40. data/lib/theme_check/checks/default_locale.rb +1 -0
  41. data/lib/theme_check/checks/deprecated_filter.rb +1 -1
  42. data/lib/theme_check/checks/liquid_tag.rb +3 -3
  43. data/lib/theme_check/checks/matching_schema_translations.rb +1 -0
  44. data/lib/theme_check/checks/matching_translations.rb +1 -0
  45. data/lib/theme_check/checks/missing_enable_comment.rb +1 -0
  46. data/lib/theme_check/checks/missing_required_template_files.rb +1 -2
  47. data/lib/theme_check/checks/missing_template.rb +1 -0
  48. data/lib/theme_check/checks/nested_snippet.rb +1 -0
  49. data/lib/theme_check/checks/parser_blocking_javascript.rb +2 -1
  50. data/lib/theme_check/checks/required_directories.rb +1 -1
  51. data/lib/theme_check/checks/required_layout_theme_object.rb +1 -1
  52. data/lib/theme_check/checks/space_inside_braces.rb +1 -0
  53. data/lib/theme_check/checks/syntax_error.rb +1 -0
  54. data/lib/theme_check/checks/template_length.rb +1 -0
  55. data/lib/theme_check/checks/translation_key_exists.rb +1 -0
  56. data/lib/theme_check/checks/undefined_object.rb +29 -10
  57. data/lib/theme_check/checks/unknown_filter.rb +1 -0
  58. data/lib/theme_check/checks/unused_assign.rb +5 -3
  59. data/lib/theme_check/checks/unused_snippet.rb +1 -0
  60. data/lib/theme_check/checks/valid_html_translation.rb +1 -0
  61. data/lib/theme_check/checks/valid_json.rb +1 -0
  62. data/lib/theme_check/checks/valid_schema.rb +1 -0
  63. data/lib/theme_check/cli.rb +22 -6
  64. data/lib/theme_check/config.rb +2 -2
  65. data/lib/theme_check/in_memory_storage.rb +1 -1
  66. data/lib/theme_check/language_server.rb +10 -0
  67. data/lib/theme_check/language_server/completion_engine.rb +38 -0
  68. data/lib/theme_check/language_server/completion_helper.rb +25 -0
  69. data/lib/theme_check/language_server/completion_provider.rb +24 -0
  70. data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +47 -0
  71. data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +31 -0
  72. data/lib/theme_check/language_server/completion_providers/tag_completion_provider.rb +31 -0
  73. data/lib/theme_check/language_server/handler.rb +62 -6
  74. data/lib/theme_check/language_server/position_helper.rb +27 -0
  75. data/lib/theme_check/language_server/protocol.rb +41 -0
  76. data/lib/theme_check/language_server/server.rb +6 -1
  77. data/lib/theme_check/language_server/tokens.rb +55 -0
  78. data/lib/theme_check/offense.rb +51 -14
  79. data/lib/theme_check/regex_helpers.rb +15 -0
  80. data/lib/theme_check/remote_asset_file.rb +44 -0
  81. data/lib/theme_check/shopify_liquid.rb +1 -0
  82. data/lib/theme_check/shopify_liquid/tag.rb +16 -0
  83. data/lib/theme_check/theme.rb +7 -1
  84. data/lib/theme_check/version.rb +1 -1
  85. metadata +44 -2
@@ -0,0 +1,97 @@
1
+ # Discourage use of parser-blocking JavaScript (`ParserBlockingJavaScript`)
2
+
3
+ The `defer` or `async` attributes are extremely important on script tags. When neither of those attributes are used, a script tag will block the construction and rendering of the DOM until the script is _loaded_, _parsed_ and _executed_. It also creates congestion on the Network, messes with the resource priorities and significantly delays the rendering of the page.
4
+
5
+ Considering that JavaScript on Shopify themes should always be used to progressively _enhance_ the experience of the site, themes should never make use of parser-blocking script tags.
6
+
7
+ As a general rule, use `defer` if the order of execution matters, `async` otherwise. When in doubt, choose either one and get 80/20 of the benefits.
8
+
9
+ ## Check Details
10
+
11
+ This check is aimed at eliminating parser-blocking JavaScript on themes.
12
+
13
+ :-1: Examples of **incorrect** code for this check:
14
+
15
+ ```liquid
16
+ <!-- The script_tag filter outputs a parser-blocking script -->
17
+ {{ 'app-code.js' | asset_url | script_tag }}
18
+
19
+ <!-- jQuery is typically loaded synchronously because inline scripts depend on $, don't do that. -->
20
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
21
+ ...
22
+ <button id="thing">Click me!</button>
23
+ <script>
24
+ $('#thing').click(() => {
25
+ alert('Oh. Hi Mark!');
26
+ });
27
+ </script>
28
+ ```
29
+
30
+ :+1: Examples of **correct** code for this check:
31
+
32
+ ```liquid
33
+ <!-- Good. Using the asset_url filter + defer -->
34
+ <script src="{{ 'theme.js' | asset_url }}" defer><script>
35
+
36
+ <!-- Also good. Using the asset_url filter + async -->
37
+ <script src="{{ 'theme.js' | asset_url }}" async><script>
38
+
39
+ <!-- Better than synchronous jQuery -->
40
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js" defer><script>
41
+ ...
42
+ <button id="thing">Click me!</button>
43
+ <script>
44
+ // Because we're using `defer`, jQuery is guaranteed to
45
+ // be loaded when DOMContentLoaded fires. This technique
46
+ // could be used as a first step to refactor an old theme
47
+ // that inline depends on jQuery.
48
+ document.addEventListener('DOMContentLoaded', () => {
49
+ $('#thing').click(() => {
50
+ alert('Oh. Hi Mark!');
51
+ });
52
+ });
53
+ </script>
54
+
55
+ <!-- Even better. Web Native (no jQuery). -->
56
+ <button id="thing">Click Me</button>
57
+ <script>
58
+ const button = document.getElementById('thing');
59
+ button.addEventListener('click', () => {
60
+ alert('Oh. Hi Mark!');
61
+ });
62
+ </script>
63
+
64
+ <!-- Best -->
65
+ <script src="{{ 'theme.js' | asset_url }}" defer></script>
66
+ ...
67
+ <button id="thing">Click Me</button>
68
+ ```
69
+
70
+ ## Check Options
71
+
72
+ The default configuration for this check is the following:
73
+
74
+ ```yaml
75
+ ParserBlockingJavaScript:
76
+ enabled: true
77
+ ```
78
+
79
+ ## When Not To Use It
80
+
81
+ This should only be turned off with the `theme-check-disable` comment when there's no better way to accomplish what you're doing than with a parser-blocking script.
82
+
83
+ It is discouraged to turn this rule off.
84
+
85
+ ## Version
86
+
87
+ This check has been introduced in Theme Check 0.3.0.
88
+
89
+ ## Resources
90
+
91
+ - [Lighthouse Render-Blocking Resources Audit][render-blocking]
92
+ - [Rule Source][codesource]
93
+ - [Documentation Source][docsource]
94
+
95
+ [render-blocking]: https://web.dev/render-blocking-resources/
96
+ [codesource]: /lib/theme_check/checks/parser_blocking_javascript.rb
97
+ [docsource]: /docs/checks/parser_blocking_javascript.md
@@ -0,0 +1,25 @@
1
+ # Prevent missing directories (`RequiredDirectories`)
2
+
3
+ This check exists to warn theme developers about missing required directories in their structure.
4
+
5
+ ## Check Options
6
+
7
+ The default configuration for this check is the following:
8
+
9
+ ```yaml
10
+ RequiredDirectories:
11
+ enabled: true
12
+ ```
13
+
14
+ ## Version
15
+
16
+ This check has been introduced in Theme Check 0.1.0.
17
+
18
+ ## Resources
19
+
20
+ - [Shopify Theme File Structure](https://shopify.dev/tutorials/develop-theme-files)
21
+ - [Rule Source][codesource]
22
+ - [Documentation Source][docsource]
23
+
24
+ [codesource]: /lib/theme_check/checks/required_directories.rb
25
+ [docsource]: /docs/checks/required_directories.md
@@ -0,0 +1,28 @@
1
+ # Prevent missing required objects in theme.liquid (`RequiredLayoutThemeObject`)
2
+
3
+ ## Check Details
4
+
5
+ This check prevents missing `{{ content_for_header }}` and `{{ content_for_layout }}` objects in `layout/theme.liquid`.
6
+
7
+ ## Check Options
8
+
9
+ The default configuration for this check is the following:
10
+
11
+ ```yaml
12
+ RequiredLayoutThemeObject:
13
+ enabled: true
14
+ ```
15
+
16
+ ## Version
17
+
18
+ This check has been introduced in Theme Check 0.1.0.
19
+
20
+ ## Resources
21
+
22
+ - [Shopify theme.liquid requirements][themeliquid]
23
+ - [Rule Source][codesource]
24
+ - [Documentation Source][docsource]
25
+
26
+ [codesource]: /lib/theme_check/checks/required_layout_theme_object.rb
27
+ [docsource]: /docs/checks/required_layout_theme_object.md
28
+ [themeliquid]: https://shopify.dev/docs/themes/theme-templates/theme-liquid
@@ -0,0 +1,63 @@
1
+ # Ensure consistent spacing inside Liquid tags and variables (`SpaceInsideBraces`)
2
+
3
+ Warns against inconsistent spacing inside liquid tags and variables.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at eliminating ugly Liquid:
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ <!-- Around braces -->
13
+ {% assign x = 1%}
14
+ {{ x}}
15
+ {{x }}
16
+
17
+ <!-- After commas and semicolons -->
18
+ {% form 'type', object, key:value %}
19
+ {% endform %}
20
+ ```
21
+
22
+ :+1: Examples of **correct** code for this check:
23
+
24
+ ```liquid
25
+ {% assign x = 1 %}
26
+ {{ x }}
27
+ {% form 'type', object, key: value, key2: value %}
28
+ {% endform %}
29
+ {{ "ignore:stuff, indeed" }}
30
+ {% render 'product-card',
31
+ product_card_product: product_recommendation,
32
+ show_vendor: section.settings.show_vendor,
33
+ media_size: section.settings.product_recommendations_image_ratio,
34
+ center_align_text: section.settings.center_align_text
35
+ %}
36
+ ```
37
+
38
+ ## Check Options
39
+
40
+ The default configuration for this check is the following:
41
+
42
+ ```yaml
43
+ SpaceInsideBraces:
44
+ enabled: true
45
+ ```
46
+
47
+ ## When Not To Use It
48
+
49
+ If you don't care about the look of your code.
50
+
51
+ ## Version
52
+
53
+ This check has been introduced in Theme Check 0.1.0.
54
+
55
+ ## Resources
56
+
57
+ - [Liquid Style Guide][styleguide]
58
+ - [Rule Source][codesource]
59
+ - [Documentation Source][docsource]
60
+
61
+ [styleguide]: https://github.com/Shopify/liquid-style-guide
62
+ [codesource]: /lib/theme_check/checks/space_inside_braces.rb
63
+ [docsource]: /docs/checks/space_inside_braces.md
@@ -0,0 +1,49 @@
1
+ # Prevent Syntax Errors (`SyntaxError`)
2
+
3
+ This check exists to inform the user of Liquid syntax error earlier.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at eliminating syntax errors.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {% include 'muffin'
13
+ {% assign foo = 1 }}
14
+ {% unknown %}
15
+ {% if collection | size > 0 %}
16
+ ```
17
+
18
+ :+1: Examples of **correct** code for this check:
19
+
20
+ ```liquid
21
+ {% include 'muffin' %}
22
+ {% assign foo = 1 %}
23
+ {% if collection.size > 0 %}
24
+ ```
25
+
26
+ ## Check Options
27
+
28
+ The default configuration for this check is the following:
29
+
30
+ ```yaml
31
+ SyntaxError:
32
+ enabled: true
33
+ ```
34
+
35
+ ## When Not To Use It
36
+
37
+ It is not safe to disable this rule.
38
+
39
+ ## Version
40
+
41
+ This check has been introduced in Theme Check 0.1.0.
42
+
43
+ ## Resources
44
+
45
+ - [Rule Source][codesource]
46
+ - [Documentation Source][docsource]
47
+
48
+ [codesource]: /lib/theme_check/checks/syntax_error.rb
49
+ [docsource]: /docs/checks/syntax_error.md
@@ -0,0 +1,50 @@
1
+ # Discourage the use of large template files (`TemplateLength`)
2
+
3
+ This check exists to discourage the use of large template files. Use snippets to componentize your theme.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at eliminating large template files.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ - Files that have more lines than the threshold
12
+
13
+ :+1: Examples of **correct** code for this check:
14
+
15
+ - Files that have less lines than the threshold
16
+
17
+ ## Check Options
18
+
19
+ The default configuration for this check is the following:
20
+
21
+ ```yaml
22
+ TemplateLength:
23
+ enabled: true
24
+ max_length: 200
25
+ exclude_schema: true
26
+ ```
27
+
28
+ ### `max_length`
29
+
30
+ The `max_length` (Default: `200`) option determines the maximum number of lines allowed inside a liquid file.
31
+
32
+ ### `exclude_schema`
33
+
34
+ The `exclude_schema` (Default: `true`) option determines if the schema lines from a template should be excluded from the line count.
35
+
36
+ ## When Not To Use It
37
+
38
+ If you don't care about template lengths, then it's safe to disable this rule.
39
+
40
+ ## Version
41
+
42
+ This check has been introduced in Theme Check 0.1.0.
43
+
44
+ ## Resources
45
+
46
+ - [Rule Source][codesource]
47
+ - [Documentation Source][docsource]
48
+
49
+ [codesource]: /lib/theme_check/checks/template_length.rb
50
+ [docsource]: /docs/checks/template_length.md
@@ -0,0 +1,63 @@
1
+ # Prevent use of undefined translations (`TranslationKeyExists`)
2
+
3
+ This check exists to prevent translation errors in themes.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at eliminating the use of translations that do not exist.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {% comment %}locales/en.default.json{% endcomment %}
13
+ {
14
+ "greetings": "Hello, world!",
15
+ "general": {
16
+ "close": "Close"
17
+ }
18
+ }
19
+
20
+ {% comment %}templates/index.liquid{% endcomment %}
21
+ {{ "notfound" | t }}
22
+ ```
23
+
24
+ :+1: Examples of **correct** code for this check:
25
+
26
+ ```liquid
27
+ {% comment %}locales/en.default.json{% endcomment %}
28
+ {
29
+ "greetings": "Hello, world!",
30
+ "general": {
31
+ "close": "Close"
32
+ }
33
+ }
34
+
35
+ {% comment %}templates/index.liquid{% endcomment %}
36
+ {{ "greetings" | t }}
37
+ {{ "general.close" | t }}
38
+ ```
39
+
40
+ ## Check Options
41
+
42
+ The default configuration for this check is the following:
43
+
44
+ ```yaml
45
+ TranslationKeyExists:
46
+ enabled: true
47
+ ```
48
+
49
+ ## When Not To Use It
50
+
51
+ It is not safe to disable this check.
52
+
53
+ ## Version
54
+
55
+ This check has been introduced in Theme Check 0.1.0.
56
+
57
+ ## Resources
58
+
59
+ - [Rule Source][codesource]
60
+ - [Documentation Source][docsource]
61
+
62
+ [codesource]: /lib/theme_check/checks/translation_key_exists.rb
63
+ [docsource]: /docs/checks/translation_key_exists.md
@@ -0,0 +1,53 @@
1
+ # Prevent undefined object errors (`UndefinedObject`)
2
+
3
+ This check prevents errors by making sure that no undefined variables are being used
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at eliminating undefined object errors.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {% assign greetings = "Hello" %}
13
+ {% if greeting == "Hello" %}
14
+
15
+ {{ articl }}
16
+ {{ prodcut }}
17
+ ```
18
+
19
+ :+1: Examples of **correct** code for this check:
20
+
21
+ ```liquid
22
+ {% assign greetings = "Hello" %}
23
+ {% if greetings == "Hello" %}
24
+
25
+ {{ article }}
26
+ {{ product }}
27
+ ```
28
+
29
+ ## Check Options
30
+
31
+ The default configuration for this check is the following:
32
+
33
+ ```yaml
34
+ UndefinedObject:
35
+ enabled: true
36
+ ```
37
+
38
+ ## When Not To Use It
39
+
40
+ It is discouraged to disable this rule.
41
+
42
+ ## Version
43
+
44
+ This check has been introduced in Theme Check 0.1.0.
45
+
46
+ ## Resources
47
+
48
+ - [Shopify Object Reference](https://shopify.dev/docs/themes/liquid/reference/objects)
49
+ - [Rule Source][codesource]
50
+ - [Documentation Source][docsource]
51
+
52
+ [codesource]: /lib/theme_check/checks/undefined_object.rb
53
+ [docsource]: /docs/checks/undefined_object.md
@@ -0,0 +1,45 @@
1
+ # Prevent use of unknown filters (`UnknownFilter`)
2
+
3
+ This check exists to prevent user errors.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at preventing the use of unknown filters.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {{ x | some_unknown_filter }}
13
+ ```
14
+
15
+ :+1: Examples of **correct** code for this check:
16
+
17
+ ```liquid
18
+ {{ x | upcase }}
19
+ ```
20
+
21
+ ## Check Options
22
+
23
+ The default configuration for this check is the following:
24
+
25
+ ```yaml
26
+ UnknownFilter:
27
+ enabled: true
28
+ ```
29
+
30
+ ## When Not To Use It
31
+
32
+ It is not safe to disable this rule.
33
+
34
+ ## Version
35
+
36
+ This check has been introduced in Theme Check 0.1.0.
37
+
38
+ ## Resources
39
+
40
+ - [Shopify Filter Reference](https://shopify.dev/docs/themes/liquid/reference/filters)
41
+ - [Rule Source][codesource]
42
+ - [Documentation Source][docsource]
43
+
44
+ [codesource]: /lib/theme_check/checks/unknown_filter.rb
45
+ [docsource]: /docs/checks/unknown_filter.md