theme-check 0.8.0 → 0.9.1

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/theme-check.yml +3 -0
  3. data/CHANGELOG.md +44 -0
  4. data/CONTRIBUTING.md +2 -1
  5. data/README.md +4 -1
  6. data/RELEASING.md +5 -3
  7. data/config/default.yml +42 -1
  8. data/data/shopify_liquid/tags.yml +3 -0
  9. data/data/shopify_translation_keys.yml +1 -0
  10. data/docs/checks/asset_url_filters.md +56 -0
  11. data/docs/checks/content_for_header_modification.md +42 -0
  12. data/docs/checks/nested_snippet.md +1 -1
  13. data/docs/checks/parser_blocking_script_tag.md +53 -0
  14. data/docs/checks/space_inside_braces.md +28 -0
  15. data/exe/theme-check-language-server +1 -2
  16. data/lib/theme_check.rb +13 -1
  17. data/lib/theme_check/analyzer.rb +79 -13
  18. data/lib/theme_check/bug.rb +20 -0
  19. data/lib/theme_check/check.rb +36 -7
  20. data/lib/theme_check/checks.rb +47 -8
  21. data/lib/theme_check/checks/asset_url_filters.rb +46 -0
  22. data/lib/theme_check/checks/content_for_header_modification.rb +41 -0
  23. data/lib/theme_check/checks/img_width_and_height.rb +18 -49
  24. data/lib/theme_check/checks/missing_enable_comment.rb +4 -4
  25. data/lib/theme_check/checks/missing_template.rb +1 -0
  26. data/lib/theme_check/checks/nested_snippet.rb +1 -1
  27. data/lib/theme_check/checks/parser_blocking_javascript.rb +6 -38
  28. data/lib/theme_check/checks/parser_blocking_script_tag.rb +20 -0
  29. data/lib/theme_check/checks/remote_asset.rb +21 -79
  30. data/lib/theme_check/checks/space_inside_braces.rb +8 -2
  31. data/lib/theme_check/checks/template_length.rb +3 -0
  32. data/lib/theme_check/checks/valid_html_translation.rb +1 -0
  33. data/lib/theme_check/config.rb +2 -0
  34. data/lib/theme_check/disabled_check.rb +41 -0
  35. data/lib/theme_check/disabled_checks.rb +33 -29
  36. data/lib/theme_check/exceptions.rb +32 -0
  37. data/lib/theme_check/html_check.rb +7 -0
  38. data/lib/theme_check/html_node.rb +56 -0
  39. data/lib/theme_check/html_visitor.rb +38 -0
  40. data/lib/theme_check/json_file.rb +13 -1
  41. data/lib/theme_check/language_server.rb +2 -1
  42. data/lib/theme_check/language_server/completion_engine.rb +1 -1
  43. data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +1 -0
  44. data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +10 -8
  45. data/lib/theme_check/language_server/constants.rb +5 -1
  46. data/lib/theme_check/language_server/diagnostics_tracker.rb +64 -0
  47. data/lib/theme_check/language_server/document_link_engine.rb +2 -2
  48. data/lib/theme_check/language_server/handler.rb +63 -50
  49. data/lib/theme_check/language_server/server.rb +1 -1
  50. data/lib/theme_check/language_server/variable_lookup_finder.rb +295 -0
  51. data/lib/theme_check/liquid_check.rb +1 -4
  52. data/lib/theme_check/node.rb +12 -0
  53. data/lib/theme_check/offense.rb +30 -46
  54. data/lib/theme_check/position.rb +77 -0
  55. data/lib/theme_check/position_helper.rb +37 -0
  56. data/lib/theme_check/remote_asset_file.rb +3 -0
  57. data/lib/theme_check/shopify_liquid/tag.rb +13 -0
  58. data/lib/theme_check/template.rb +8 -0
  59. data/lib/theme_check/theme.rb +7 -2
  60. data/lib/theme_check/version.rb +1 -1
  61. data/lib/theme_check/visitor.rb +4 -14
  62. metadata +19 -4
  63. data/lib/theme_check/language_server/position_helper.rb +0 -27
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ class Position
5
+ include PositionHelper
6
+
7
+ def initialize(needle, contents, line_number_1_indexed)
8
+ @needle = needle
9
+ @contents = contents
10
+ @line_number_1_indexed = line_number_1_indexed
11
+ @start_row_column = nil
12
+ @end_row_column = nil
13
+ end
14
+
15
+ def start_line_index
16
+ from_row_column_to_index(contents, line_number, 0)
17
+ end
18
+
19
+ # 0-indexed, inclusive
20
+ def start_index
21
+ contents.index(needle, start_line_index) || start_line_index
22
+ end
23
+
24
+ # 0-indexed, exclusive
25
+ def end_index
26
+ start_index + needle.size
27
+ end
28
+
29
+ def start_row
30
+ start_row_column[0]
31
+ end
32
+
33
+ def start_column
34
+ start_row_column[1]
35
+ end
36
+
37
+ def end_row
38
+ end_row_column[0]
39
+ end
40
+
41
+ def end_column
42
+ end_row_column[1]
43
+ end
44
+
45
+ private
46
+
47
+ def contents
48
+ return '' unless @contents.is_a?(String) && !@contents.empty?
49
+ @contents
50
+ end
51
+
52
+ def line_number
53
+ return 0 if @line_number_1_indexed.nil?
54
+ bounded(0, @line_number_1_indexed - 1, contents.lines.size - 1)
55
+ end
56
+
57
+ def needle
58
+ if @needle.nil? && !contents.empty? && !@line_number_1_indexed.nil?
59
+ contents.lines(chomp: true)[line_number] || ''
60
+ elsif contents.empty? || @needle.nil?
61
+ ''
62
+ else
63
+ @needle
64
+ end
65
+ end
66
+
67
+ def start_row_column
68
+ return @start_row_column unless @start_row_column.nil?
69
+ @start_row_column = from_index_to_row_column(contents, start_index)
70
+ end
71
+
72
+ def end_row_column
73
+ return @end_row_column unless @end_row_column.nil?
74
+ @end_row_column = from_index_to_row_column(contents, end_index)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ # Note: Everything is 0-indexed here.
3
+
4
+ module ThemeCheck
5
+ module PositionHelper
6
+ def from_row_column_to_index(content, row, col)
7
+ return 0 unless content.is_a?(String) && !content.empty?
8
+ return 0 unless row.is_a?(Integer) && col.is_a?(Integer)
9
+ i = 0
10
+ result = 0
11
+ safe_row = bounded(0, row, content.lines.size - 1)
12
+ lines = content.lines
13
+ line_size = lines[i].size
14
+ while i < safe_row
15
+ result += line_size
16
+ i += 1
17
+ line_size = lines[i].size
18
+ end
19
+ result += bounded(0, col, line_size - 1)
20
+ result
21
+ end
22
+
23
+ def from_index_to_row_column(content, index)
24
+ return [0, 0] unless content.is_a?(String) && !content.empty?
25
+ return [0, 0] unless index.is_a?(Integer)
26
+ safe_index = bounded(0, index, content.size - 1)
27
+ lines = content[0..safe_index].lines
28
+ row = lines.size - 1
29
+ col = lines.last.size - 1
30
+ [row, col]
31
+ end
32
+
33
+ def bounded(a, x, b)
34
+ [a, [x, b].min].max
35
+ end
36
+ end
37
+ end
@@ -35,6 +35,9 @@ module ThemeCheck
35
35
  end
36
36
 
37
37
  @content = res.body
38
+
39
+ rescue OpenSSL::SSL::SSLError, Zlib::StreamError, *NET_HTTP_EXCEPTIONS
40
+ @contents = ''
38
41
  end
39
42
 
40
43
  def gzipped_size
@@ -8,6 +8,19 @@ module ThemeCheck
8
8
 
9
9
  def labels
10
10
  @tags ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/tags.yml"))
11
+ .to_set
12
+ end
13
+
14
+ def tag_regex(tag)
15
+ return unless labels.include?(tag)
16
+ @tag_regexes ||= {}
17
+ @tag_regexes[tag] ||= /\A#{Liquid::TagStart}-?\s*#{tag}/m
18
+ end
19
+
20
+ def liquid_tag_regex(tag)
21
+ return unless labels.include?(tag)
22
+ @tag_liquid_regexes ||= {}
23
+ @tag_liquid_regexes[tag] ||= /^\s*#{tag}/m
11
24
  end
12
25
  end
13
26
  end
@@ -32,6 +32,14 @@ module ThemeCheck
32
32
  relative_path.sub_ext('').to_s
33
33
  end
34
34
 
35
+ def json?
36
+ false
37
+ end
38
+
39
+ def liquid?
40
+ true
41
+ end
42
+
35
43
  def template?
36
44
  name.start_with?('templates')
37
45
  end
@@ -52,8 +52,13 @@ module ThemeCheck
52
52
  @all ||= json + liquid + assets
53
53
  end
54
54
 
55
- def [](name)
56
- all.find { |t| t.name == name }
55
+ def [](name_or_relative_path)
56
+ case name_or_relative_path
57
+ when Pathname
58
+ all.find { |t| t.relative_path == name_or_relative_path }
59
+ else
60
+ all.find { |t| t.name == name_or_relative_path }
61
+ end
57
62
  end
58
63
 
59
64
  def templates
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- VERSION = "0.8.0"
3
+ VERSION = "0.9.1"
4
4
  end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
3
  class Visitor
4
- def initialize(checks)
4
+ attr_reader :checks
5
+
6
+ def initialize(checks, disabled_checks)
5
7
  @checks = checks
8
+ @disabled_checks = disabled_checks
6
9
  end
7
10
 
8
11
  def visit_template(template)
9
- @disabled_checks = DisabledChecks.new
10
12
  visit(Node.new(template.root, nil, template))
11
13
  rescue Liquid::Error => exception
12
14
  exception.template_name = template.name
@@ -29,20 +31,8 @@ module ThemeCheck
29
31
  @disabled_checks.update(node) if node.comment?
30
32
  end
31
33
 
32
- def visit_children(node)
33
- node.children.each { |child| visit(child) }
34
- end
35
-
36
34
  def call_checks(method, *args)
37
35
  checks.call(method, *args)
38
36
  end
39
-
40
- def checks
41
- return @checks unless @disabled_checks.any?
42
-
43
- return @checks.always_enabled if @disabled_checks.all_disabled?
44
-
45
- @checks.except_for(@disabled_checks)
46
- end
47
37
  end
48
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: theme-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-André Cournoyer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-13 00:00:00.000000000 Z
11
+ date: 2021-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -72,6 +72,8 @@ files:
72
72
  - docs/checks/CHECK_DOCS_TEMPLATE.md
73
73
  - docs/checks/asset_size_css.md
74
74
  - docs/checks/asset_size_javascript.md
75
+ - docs/checks/asset_url_filters.md
76
+ - docs/checks/content_for_header_modification.md
75
77
  - docs/checks/convert_include_to_render.md
76
78
  - docs/checks/default_locale.md
77
79
  - docs/checks/deprecated_filter.md
@@ -84,6 +86,7 @@ files:
84
86
  - docs/checks/missing_template.md
85
87
  - docs/checks/nested_snippet.md
86
88
  - docs/checks/parser_blocking_javascript.md
89
+ - docs/checks/parser_blocking_script_tag.md
87
90
  - docs/checks/remote_asset.md
88
91
  - docs/checks/required_directories.md
89
92
  - docs/checks/required_layout_theme_object.md
@@ -104,10 +107,13 @@ files:
104
107
  - lib/theme_check.rb
105
108
  - lib/theme_check/analyzer.rb
106
109
  - lib/theme_check/asset_file.rb
110
+ - lib/theme_check/bug.rb
107
111
  - lib/theme_check/check.rb
108
112
  - lib/theme_check/checks.rb
109
113
  - lib/theme_check/checks/asset_size_css.rb
110
114
  - lib/theme_check/checks/asset_size_javascript.rb
115
+ - lib/theme_check/checks/asset_url_filters.rb
116
+ - lib/theme_check/checks/content_for_header_modification.rb
111
117
  - lib/theme_check/checks/convert_include_to_render.rb
112
118
  - lib/theme_check/checks/default_locale.rb
113
119
  - lib/theme_check/checks/deprecated_filter.rb
@@ -120,6 +126,7 @@ files:
120
126
  - lib/theme_check/checks/missing_template.rb
121
127
  - lib/theme_check/checks/nested_snippet.rb
122
128
  - lib/theme_check/checks/parser_blocking_javascript.rb
129
+ - lib/theme_check/checks/parser_blocking_script_tag.rb
123
130
  - lib/theme_check/checks/remote_asset.rb
124
131
  - lib/theme_check/checks/required_directories.rb
125
132
  - lib/theme_check/checks/required_layout_theme_object.rb
@@ -138,8 +145,13 @@ files:
138
145
  - lib/theme_check/cli.rb
139
146
  - lib/theme_check/config.rb
140
147
  - lib/theme_check/corrector.rb
148
+ - lib/theme_check/disabled_check.rb
141
149
  - lib/theme_check/disabled_checks.rb
150
+ - lib/theme_check/exceptions.rb
142
151
  - lib/theme_check/file_system_storage.rb
152
+ - lib/theme_check/html_check.rb
153
+ - lib/theme_check/html_node.rb
154
+ - lib/theme_check/html_visitor.rb
143
155
  - lib/theme_check/in_memory_storage.rb
144
156
  - lib/theme_check/json_check.rb
145
157
  - lib/theme_check/json_file.rb
@@ -153,18 +165,21 @@ files:
153
165
  - lib/theme_check/language_server/completion_providers/render_snippet_completion_provider.rb
154
166
  - lib/theme_check/language_server/completion_providers/tag_completion_provider.rb
155
167
  - lib/theme_check/language_server/constants.rb
168
+ - lib/theme_check/language_server/diagnostics_tracker.rb
156
169
  - lib/theme_check/language_server/document_link_engine.rb
157
170
  - lib/theme_check/language_server/handler.rb
158
- - lib/theme_check/language_server/position_helper.rb
159
171
  - lib/theme_check/language_server/protocol.rb
160
172
  - lib/theme_check/language_server/server.rb
161
173
  - lib/theme_check/language_server/tokens.rb
174
+ - lib/theme_check/language_server/variable_lookup_finder.rb
162
175
  - lib/theme_check/liquid_check.rb
163
176
  - lib/theme_check/locale_diff.rb
164
177
  - lib/theme_check/node.rb
165
178
  - lib/theme_check/offense.rb
166
179
  - lib/theme_check/packager.rb
167
180
  - lib/theme_check/parsing_helpers.rb
181
+ - lib/theme_check/position.rb
182
+ - lib/theme_check/position_helper.rb
168
183
  - lib/theme_check/printer.rb
169
184
  - lib/theme_check/regex_helpers.rb
170
185
  - lib/theme_check/releaser.rb
@@ -203,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
218
  - !ruby/object:Gem::Version
204
219
  version: '0'
205
220
  requirements: []
206
- rubygems_version: 3.0.3
221
+ rubygems_version: 3.2.17
207
222
  signing_key:
208
223
  specification_version: 4
209
224
  summary: A Shopify Theme Linter
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
- # Note: Everything is 0-indexed here.
3
-
4
- module ThemeCheck
5
- module LanguageServer
6
- module PositionHelper
7
- def from_line_column_to_index(content, row, col)
8
- i = 0
9
- result = 0
10
- lines = content.lines
11
- while i < row
12
- result += lines[i].size
13
- i += 1
14
- end
15
- result += col
16
- result
17
- end
18
-
19
- def from_index_to_line_column(content, index)
20
- lines = content[0..index].lines
21
- row = lines.size - 1
22
- col = lines.last.size - 1
23
- [row, col]
24
- end
25
- end
26
- end
27
- end