theme-check 0.8.3 → 0.9.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/theme-check.yml +3 -0
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +2 -1
  5. data/README.md +4 -1
  6. data/config/default.yml +37 -0
  7. data/docs/checks/content_for_header_modification.md +42 -0
  8. data/docs/checks/parser_blocking_script_tag.md +53 -0
  9. data/exe/theme-check-language-server +1 -2
  10. data/lib/theme_check.rb +8 -1
  11. data/lib/theme_check/analyzer.rb +72 -16
  12. data/lib/theme_check/check.rb +31 -6
  13. data/lib/theme_check/checks.rb +9 -1
  14. data/lib/theme_check/checks/content_for_header_modification.rb +41 -0
  15. data/lib/theme_check/checks/img_width_and_height.rb +18 -49
  16. data/lib/theme_check/checks/missing_template.rb +1 -0
  17. data/lib/theme_check/checks/parser_blocking_javascript.rb +6 -38
  18. data/lib/theme_check/checks/parser_blocking_script_tag.rb +20 -0
  19. data/lib/theme_check/checks/template_length.rb +3 -0
  20. data/lib/theme_check/checks/valid_html_translation.rb +1 -0
  21. data/lib/theme_check/config.rb +2 -0
  22. data/lib/theme_check/disabled_check.rb +6 -4
  23. data/lib/theme_check/disabled_checks.rb +25 -9
  24. data/lib/theme_check/html_check.rb +7 -0
  25. data/lib/theme_check/html_node.rb +52 -0
  26. data/lib/theme_check/html_visitor.rb +36 -0
  27. data/lib/theme_check/json_file.rb +8 -0
  28. data/lib/theme_check/language_server.rb +1 -0
  29. data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +1 -0
  30. data/lib/theme_check/language_server/diagnostics_tracker.rb +64 -0
  31. data/lib/theme_check/language_server/handler.rb +31 -26
  32. data/lib/theme_check/language_server/server.rb +1 -1
  33. data/lib/theme_check/liquid_check.rb +0 -4
  34. data/lib/theme_check/offense.rb +18 -0
  35. data/lib/theme_check/template.rb +8 -0
  36. data/lib/theme_check/theme.rb +7 -2
  37. data/lib/theme_check/version.rb +1 -1
  38. data/lib/theme_check/visitor.rb +2 -11
  39. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc820b814467926919858c11517a275e70dd07aea017285f315dc3309e4b49a3
4
- data.tar.gz: 949c2934821bb7270aa466c3430d8fb640e8af938fb239aa1a2a346c82580a50
3
+ metadata.gz: e5970832846bda5a0e7cb27c99ebef32382050c911350d1d208211849bef7d55
4
+ data.tar.gz: 89d3bb2d5a261c817dddfbf50ad9ac31a589f88fe4f2a2df23b8c5aaad51c4db
5
5
  SHA512:
6
- metadata.gz: 699907617f0401cd5737c7f774b7063fae97f17465a8ac06ad1e404992b969923e4de6ff877c5f85fb951a8af1433ac017ab651465132b69d6143ff77baa5495
7
- data.tar.gz: 93d69bd9b50561cc0f10940f4b5e7c5b19fcef43d105d0896b4ae484a3df13301cfc51f6470dff4b83b1e3410a3736f54d5097dca9a80763fa7c4790f1761018
6
+ metadata.gz: 2ee4f610dc461c6e70e870723f801ddb0f1e5381eebfc6622030af68486c2c6650c11e530be38456cf0df8666ecc5e78b26d16cf60428142e04f0ebde45edf9f
7
+ data.tar.gz: 36053d9337a817da4334a5341be1877f04d86b3f4d88606a2acccb2028c0a3a07227086183de5aa06bd44e9beeebd0a4650d08b746fdfbced854e945469d61a3
@@ -34,3 +34,6 @@ jobs:
34
34
  run: bundle install --jobs=3 --retry=3 --path=vendor/bundle
35
35
  - name: Run tests
36
36
  run: bundle exec rake
37
+ - name: Test runtime
38
+ # Testing that runtime can execute, not testing the results themselves
39
+ run: bundle exec theme-check ./test/theme | grep -q "files inspected"
data/CHANGELOG.md CHANGED
@@ -1,4 +1,19 @@
1
1
 
2
+ v0.9.0 / 2021-05-28
3
+ ==================
4
+
5
+ * Introduce HtmlCheck, and convert ParserBlockingJavaScript & ImgWidthAndHeight to it
6
+ * Move `script-tag` validation from ParserBlockingJavaScript to ParserBlockingScriptTag
7
+ * Add ability to ignore individual checks using file patterns
8
+ * Introduce single file and whole theme checks to optimize LSP diagnostics
9
+ * Fix TemplateLength counter not being reseted on each document
10
+ * Add missing category to ValidHTMLTranslation
11
+ * Set Ruby default encodings to UTF-8 to fix encoding issues
12
+ * Add ContentForHeaderModification check to prevent relying on the content of ``content_for_header`
13
+ * Fix `Content-Length` in LSP responses
14
+ * Fix disabling checks that emit offences in `on_end`
15
+ * Fix completion bug in `filter_completion_provider`
16
+
2
17
  v0.8.3 / 2021-05-17
3
18
  ==================
4
19
 
data/CONTRIBUTING.md CHANGED
@@ -41,7 +41,8 @@ Under `lib/theme_check/checks`, create new Ruby file with a unique name describi
41
41
  ```ruby
42
42
  module ThemeCheck
43
43
  # Does one thing, and does it well!
44
- # NOTE: inherit from JsonCheck to implement a JSON based check.
44
+ # NOTE: inherit from `JsonCheck` to implement a JSON-based check, and from `HtmlCheck`
45
+ # to implement an HTML-based one. See other checks in `lib/theme_check/checks` for examples.
45
46
  class MyCheckName < LiquidCheck
46
47
  severity :suggestion # :error or :style
47
48
 
data/README.md CHANGED
@@ -92,11 +92,14 @@ root: dist
92
92
  require:
93
93
  - ./path/to/my_custom_check.rb
94
94
 
95
- # Disable some checks
96
95
  TemplateLength:
96
+ # Disable some checks
97
97
  enabled: false
98
98
  # Or configure options
99
99
  max_length: 300
100
+ # Or ignore certain paths
101
+ ignore:
102
+ - snippets/icon-*
100
103
 
101
104
  # Enable a custom check
102
105
  MyCustomCheck
data/config/default.yml CHANGED
@@ -7,92 +7,129 @@ ignore:
7
7
 
8
8
  ConvertIncludeToRender:
9
9
  enabled: true
10
+ ignore: []
10
11
 
11
12
  LiquidTag:
12
13
  enabled: true
14
+ ignore: []
13
15
  min_consecutive_statements: 4
14
16
 
15
17
  MissingTemplate:
16
18
  enabled: true
19
+ ignore: []
17
20
 
18
21
  NestedSnippet:
19
22
  enabled: true
23
+ ignore: []
20
24
  max_nesting_level: 3
21
25
 
22
26
  RequiredLayoutThemeObject:
23
27
  enabled: true
28
+ ignore: []
24
29
 
25
30
  SpaceInsideBraces:
26
31
  enabled: true
32
+ ignore: []
27
33
 
28
34
  SyntaxError:
29
35
  enabled: true
36
+ ignore: []
30
37
 
31
38
  TemplateLength:
32
39
  enabled: true
40
+ ignore: []
33
41
  max_length: 200
34
42
  # Exclude content of {% schema %} in line count
35
43
  exclude_schema: true
36
44
 
37
45
  UnknownFilter:
38
46
  enabled: true
47
+ ignore: []
39
48
 
40
49
  UnusedAssign:
41
50
  enabled: true
51
+ ignore: []
42
52
 
43
53
  UnusedSnippet:
44
54
  enabled: true
55
+ ignore: []
45
56
 
46
57
  MatchingSchemaTranslations:
47
58
  enabled: true
59
+ ignore: []
48
60
 
49
61
  MatchingTranslations:
50
62
  enabled: true
63
+ ignore: []
51
64
 
52
65
  DefaultLocale:
53
66
  enabled: true
67
+ ignore: []
54
68
 
55
69
  TranslationKeyExists:
56
70
  enabled: true
71
+ ignore: []
57
72
 
58
73
  ValidHTMLTranslation:
59
74
  enabled: true
75
+ ignore: []
60
76
 
61
77
  ValidJson:
62
78
  enabled: true
79
+ ignore: []
63
80
 
64
81
  ValidSchema:
65
82
  enabled: true
83
+ ignore: []
66
84
 
67
85
  MissingRequiredTemplateFiles:
68
86
  enabled: true
87
+ ignore: []
69
88
 
70
89
  UndefinedObject:
71
90
  enabled: true
91
+ ignore: []
72
92
  exclude_snippets: true
73
93
 
74
94
  RequiredDirectories:
75
95
  enabled: true
96
+ ignore: []
76
97
 
77
98
  DeprecatedFilter:
78
99
  enabled: true
100
+ ignore: []
79
101
 
80
102
  MissingEnableComment:
81
103
  enabled: true
104
+ ignore: []
82
105
 
83
106
  ParserBlockingJavaScript:
84
107
  enabled: true
108
+ ignore: []
109
+
110
+ ParserBlockingScriptTag:
111
+ enabled: true
85
112
 
86
113
  AssetSizeJavaScript:
87
114
  enabled: false
115
+ ignore: []
88
116
  threshold_in_bytes: 10_000
117
+ ignore: []
89
118
 
90
119
  AssetSizeCSS:
91
120
  enabled: false
121
+ ignore: []
92
122
  threshold_in_bytes: 100_000
123
+ ignore: []
93
124
 
94
125
  ImgWidthAndHeight:
95
126
  enabled: true
127
+ ignore: []
96
128
 
97
129
  RemoteAsset:
98
130
  enabled: true
131
+ ignore: []
132
+
133
+ ContentForHeaderModification:
134
+ enabled: true
135
+ ignore: []
@@ -0,0 +1,42 @@
1
+ # Do not depend on the content of `content_for_header` (`ContentForHeaderModification`)
2
+
3
+ Do not rely on the content of `content_for_header` as it might change in the future, which could cause your Liquid code behavior to change.
4
+
5
+ ## Check Details
6
+
7
+ :-1: Examples of **incorrect** code for this check:
8
+
9
+ ```liquid
10
+ {% assign parts = content_for_header | split: ',' %}
11
+ ```
12
+
13
+ :+1: Examples of **correct** code for this check:
14
+
15
+ The only acceptable usage of `content_for_header` is:
16
+
17
+ ```liquid
18
+ {{ content_for_header }}
19
+ ```
20
+
21
+ ## Check Options
22
+
23
+ The default configuration for this check is the following:
24
+
25
+ ```yaml
26
+ ContentForHeaderModification:
27
+ enabled: true
28
+ ```
29
+
30
+ ## Version
31
+
32
+ This check has been introduced in Theme Check 0.9.0.
33
+
34
+ ## Resources
35
+
36
+ - [Rule Source][codesource]
37
+ - [Documentation Source][docsource]
38
+ - [`theme.liquid` template considerations][considerations]
39
+
40
+ [codesource]: /lib/theme_check/checks/check_class_name.rb
41
+ [docsource]: /docs/checks/check_class_name.md
42
+ [considerations]: https://shopify.dev/docs/themes/theme-templates/theme-liquid#template-considerations
@@ -0,0 +1,53 @@
1
+ # Discourage use of parser-blocking `script_tag` filter (`ParserBlockingScriptTag`)
2
+
3
+ The `script_tag` filter emits a parser-blocking script tag.
4
+
5
+ See the [ParserBlockingJavaScript check documentation][parser_blocking_javascript] for why this is generally discouraged.
6
+
7
+ ## Check Details
8
+
9
+ This check is aimed at eliminating parser-blocking JavaScript on themes.
10
+
11
+ :-1: Examples of **incorrect** code for this check:
12
+
13
+ ```liquid
14
+ <!-- The script_tag filter outputs a parser-blocking script -->
15
+ {{ 'app-code.js' | asset_url | script_tag }}
16
+ ```
17
+
18
+ :+1: Examples of **correct** code for this check:
19
+
20
+ ```liquid
21
+ <!-- Good. Using the asset_url filter + defer -->
22
+ <script src="{{ 'theme.js' | asset_url }}" defer></script>
23
+
24
+ <!-- Also good. Using the asset_url filter + async -->
25
+ <script src="{{ 'theme.js' | asset_url }}" async></script>
26
+ ```
27
+
28
+ ## Check Options
29
+
30
+ The default configuration for this check is the following:
31
+
32
+ ```yaml
33
+ ParserBlockingScriptTag:
34
+ enabled: true
35
+ ```
36
+
37
+ ## When Not To Use It
38
+
39
+ 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.
40
+
41
+ It is discouraged to turn this rule off.
42
+
43
+ ## Version
44
+
45
+ This check has been introduced in Theme Check 0.9.0.
46
+
47
+ ## Resources
48
+
49
+ - [ParserBlockingJavaScript check][parser_blocking_javascript]
50
+ - [Documentation Source][docsource]
51
+
52
+ [parser_blocking_javascript]: /docs/checks/parser_blocking_javascript.md
53
+ [docsource]: /docs/checks/parser_blocking_script_tag.md
@@ -6,7 +6,6 @@ require 'theme_check'
6
6
  if ENV["THEME_CHECK_DEBUG"] == "true"
7
7
  $DEBUG = true
8
8
  end
9
- # Force encoding to UTF-8 to fix VSCode
10
- Encoding.default_external = Encoding::UTF_8
9
+
11
10
  status_code = ThemeCheck::LanguageServer.start
12
11
  exit! status_code
data/lib/theme_check.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require "liquid"
3
3
 
4
+ require_relative "theme_check/version"
4
5
  require_relative "theme_check/bug"
5
6
  require_relative "theme_check/exceptions"
6
7
  require_relative "theme_check/analyzer"
@@ -35,6 +36,12 @@ require_relative "theme_check/template"
35
36
  require_relative "theme_check/theme"
36
37
  require_relative "theme_check/visitor"
37
38
  require_relative "theme_check/corrector"
38
- require_relative "theme_check/version"
39
+ require_relative "theme_check/html_node"
40
+ require_relative "theme_check/html_visitor"
41
+ require_relative "theme_check/html_check"
39
42
 
40
43
  Dir[__dir__ + "/theme_check/checks/*.rb"].each { |file| require file }
44
+
45
+ # UTF-8 is the default internal and external encoding, like in Rails & Shopify.
46
+ Encoding.default_external = Encoding::UTF_8
47
+ Encoding.default_internal = Encoding::UTF_8
@@ -7,6 +7,7 @@ module ThemeCheck
7
7
 
8
8
  @liquid_checks = Checks.new
9
9
  @json_checks = Checks.new
10
+ @html_checks = Checks.new
10
11
 
11
12
  checks.each do |check|
12
13
  check.theme = @theme
@@ -16,33 +17,58 @@ module ThemeCheck
16
17
  @liquid_checks << check
17
18
  when JsonCheck
18
19
  @json_checks << check
20
+ when HtmlCheck
21
+ @html_checks << check
19
22
  end
20
23
  end
21
-
22
- @visitor = Visitor.new(@liquid_checks)
23
24
  end
24
25
 
25
26
  def offenses
26
- @liquid_checks.flat_map(&:offenses) + @json_checks.flat_map(&:offenses)
27
+ @liquid_checks.flat_map(&:offenses) +
28
+ @json_checks.flat_map(&:offenses) +
29
+ @html_checks.flat_map(&:offenses)
27
30
  end
28
31
 
29
- def offenses_clear!
30
- @liquid_checks.each do |check|
31
- check.offenses.clear
32
- end
32
+ def analyze_theme
33
+ reset
33
34
 
34
- @json_checks.each do |check|
35
- check.offenses.clear
35
+ liquid_visitor = Visitor.new(@liquid_checks, @disabled_checks)
36
+ html_visitor = HtmlVisitor.new(@html_checks)
37
+ @theme.liquid.each do |template|
38
+ liquid_visitor.visit_template(template)
39
+ html_visitor.visit_template(template)
36
40
  end
37
- end
38
41
 
39
- def analyze_theme
40
- offenses_clear!
41
- @theme.liquid.each { |template| @visitor.visit_template(template) }
42
42
  @theme.json.each { |json_file| @json_checks.call(:on_file, json_file) }
43
- @liquid_checks.call(:on_end)
44
- @json_checks.call(:on_end)
45
- offenses
43
+
44
+ finish
45
+ end
46
+
47
+ def analyze_files(files)
48
+ reset
49
+
50
+ # Call all checks that run on the whole theme
51
+ liquid_visitor = Visitor.new(@liquid_checks.whole_theme, @disabled_checks)
52
+ html_visitor = HtmlVisitor.new(@html_checks.whole_theme)
53
+ @theme.liquid.each do |template|
54
+ liquid_visitor.visit_template(template)
55
+ html_visitor.visit_template(template)
56
+ end
57
+ @theme.json.each { |json_file| @json_checks.whole_theme.call(:on_file, json_file) }
58
+
59
+ # Call checks that run on a single files, only on specified file
60
+ liquid_visitor = Visitor.new(@liquid_checks.single_file, @disabled_checks)
61
+ html_visitor = HtmlVisitor.new(@html_checks.single_file)
62
+ files.each do |file|
63
+ if file.liquid?
64
+ liquid_visitor.visit_template(file)
65
+ html_visitor.visit_template(file)
66
+ elsif file.json?
67
+ @json_checks.single_file.call(:on_file, file)
68
+ end
69
+ end
70
+
71
+ finish
46
72
  end
47
73
 
48
74
  def uncorrectable_offenses
@@ -59,5 +85,35 @@ module ThemeCheck
59
85
  @theme.liquid.each(&:write)
60
86
  end
61
87
  end
88
+
89
+ private
90
+
91
+ def reset
92
+ @disabled_checks = DisabledChecks.new
93
+
94
+ @liquid_checks.each do |check|
95
+ check.offenses.clear
96
+ end
97
+
98
+ @html_checks.each do |check|
99
+ check.offenses.clear
100
+ end
101
+
102
+ @json_checks.each do |check|
103
+ check.offenses.clear
104
+ end
105
+ end
106
+
107
+ def finish
108
+ @liquid_checks.call(:on_end)
109
+ @html_checks.call(:on_end)
110
+ @json_checks.call(:on_end)
111
+
112
+ @disabled_checks.remove_disabled_offenses(@liquid_checks)
113
+ @disabled_checks.remove_disabled_offenses(@json_checks)
114
+ @disabled_checks.remove_disabled_offenses(@html_checks)
115
+
116
+ offenses
117
+ end
62
118
  end
63
119
  end