theme-check 1.5.2 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/theme-check.yml +12 -4
- data/CHANGELOG.md +37 -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 +46 -17
- data/lib/theme_check/asset_file.rb +13 -2
- data/lib/theme_check/check.rb +3 -3
- data/lib/theme_check/checks/asset_size_css.rb +15 -0
- data/lib/theme_check/checks/asset_size_css_stylesheet_tag.rb +18 -1
- data/lib/theme_check/checks/convert_include_to_render.rb +2 -1
- 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_required_template_files.rb +21 -7
- 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/translation_key_exists.rb +3 -1
- 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 +8 -6
- data/lib/theme_check/checks/valid_json.rb +1 -1
- data/lib/theme_check/checks.rb +4 -2
- data/lib/theme_check/cli.rb +7 -4
- data/lib/theme_check/corrector.rb +21 -12
- data/lib/theme_check/disabled_check.rb +3 -3
- data/lib/theme_check/disabled_checks.rb +9 -9
- data/lib/theme_check/file_system_storage.rb +7 -2
- data/lib/theme_check/html_node.rb +40 -32
- data/lib/theme_check/html_visitor.rb +24 -12
- data/lib/theme_check/in_memory_storage.rb +5 -1
- data/lib/theme_check/json_check.rb +2 -2
- data/lib/theme_check/json_file.rb +9 -4
- data/lib/theme_check/language_server/diagnostics_tracker.rb +8 -8
- data/lib/theme_check/language_server/handler.rb +88 -6
- data/lib/theme_check/language_server/messenger.rb +57 -0
- data/lib/theme_check/language_server/server.rb +105 -40
- data/lib/theme_check/language_server.rb +1 -0
- data/lib/theme_check/{template.rb → liquid_file.rb} +6 -20
- 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 -230
- data/lib/theme_check/offense.rb +41 -15
- data/lib/theme_check/position.rb +1 -1
- data/lib/theme_check/regex_helpers.rb +1 -15
- data/lib/theme_check/theme.rb +1 -1
- data/lib/theme_check/theme_file.rb +18 -1
- data/lib/theme_check/theme_file_rewriter.rb +57 -0
- data/lib/theme_check/version.rb +1 -1
- data/lib/theme_check.rb +11 -9
- data/theme-check.gemspec +2 -1
- metadata +23 -6
data/lib/theme_check/offense.rb
CHANGED
@@ -5,13 +5,13 @@ module ThemeCheck
|
|
5
5
|
|
6
6
|
MAX_SOURCE_EXCERPT_SIZE = 120
|
7
7
|
|
8
|
-
attr_reader :check, :message, :
|
8
|
+
attr_reader :check, :message, :theme_file, :node, :markup, :line_number, :correction
|
9
9
|
|
10
10
|
def initialize(
|
11
11
|
check:, # instance of a ThemeCheck::Check
|
12
12
|
message: nil, # error message for the offense
|
13
|
-
|
14
|
-
node: nil, # Node
|
13
|
+
theme_file: nil, # ThemeFile
|
14
|
+
node: nil, # Node
|
15
15
|
markup: nil, # string
|
16
16
|
line_number: nil, # line number of the error (1-indexed)
|
17
17
|
# node_markup_offset is the index inside node.markup to start
|
@@ -39,11 +39,11 @@ module ThemeCheck
|
|
39
39
|
end
|
40
40
|
|
41
41
|
@node = node
|
42
|
-
@
|
42
|
+
@theme_file = nil
|
43
43
|
if node
|
44
|
-
@
|
45
|
-
elsif
|
46
|
-
@
|
44
|
+
@theme_file = node.theme_file
|
45
|
+
elsif theme_file
|
46
|
+
@theme_file = theme_file
|
47
47
|
end
|
48
48
|
|
49
49
|
@markup = if markup
|
@@ -62,7 +62,7 @@ module ThemeCheck
|
|
62
62
|
|
63
63
|
@position = Position.new(
|
64
64
|
@markup,
|
65
|
-
@
|
65
|
+
@theme_file&.source,
|
66
66
|
line_number_1_indexed: @line_number,
|
67
67
|
node_markup_offset: node_markup_offset,
|
68
68
|
node_markup: node&.markup
|
@@ -72,7 +72,7 @@ module ThemeCheck
|
|
72
72
|
def source_excerpt
|
73
73
|
return unless line_number
|
74
74
|
@source_excerpt ||= begin
|
75
|
-
excerpt =
|
75
|
+
excerpt = theme_file.source_excerpt(line_number)
|
76
76
|
if excerpt.size > MAX_SOURCE_EXCERPT_SIZE
|
77
77
|
excerpt[0, MAX_SOURCE_EXCERPT_SIZE - 3] + '...'
|
78
78
|
else
|
@@ -126,12 +126,12 @@ module ThemeCheck
|
|
126
126
|
end
|
127
127
|
|
128
128
|
def location
|
129
|
-
tokens = [
|
129
|
+
tokens = [theme_file&.relative_path, line_number].compact
|
130
130
|
tokens.join(":") if tokens.any?
|
131
131
|
end
|
132
132
|
|
133
133
|
def location_range
|
134
|
-
tokens = [
|
134
|
+
tokens = [theme_file&.relative_path, start_index, end_index].compact
|
135
135
|
tokens.join(":") if tokens.any?
|
136
136
|
end
|
137
137
|
|
@@ -141,9 +141,35 @@ module ThemeCheck
|
|
141
141
|
|
142
142
|
def correct
|
143
143
|
if correctable?
|
144
|
-
corrector = Corrector.new(
|
144
|
+
corrector = Corrector.new(theme_file: theme_file)
|
145
145
|
correction.call(corrector)
|
146
146
|
end
|
147
|
+
rescue => e
|
148
|
+
ThemeCheck.bug(<<~EOS)
|
149
|
+
Exception while running `Offense#correct`:
|
150
|
+
```
|
151
|
+
#{e.class}: #{e.message}
|
152
|
+
#{e.backtrace.join("\n ")}
|
153
|
+
```
|
154
|
+
|
155
|
+
Offense:
|
156
|
+
```
|
157
|
+
#{JSON.pretty_generate(to_h)}
|
158
|
+
```
|
159
|
+
Check options:
|
160
|
+
```
|
161
|
+
#{check.options.pretty_inspect}
|
162
|
+
```
|
163
|
+
Markup:
|
164
|
+
```
|
165
|
+
#{markup}
|
166
|
+
```
|
167
|
+
Node.Markup:
|
168
|
+
```
|
169
|
+
#{node&.markup}
|
170
|
+
```
|
171
|
+
EOS
|
172
|
+
exit(2)
|
147
173
|
end
|
148
174
|
|
149
175
|
def whole_theme?
|
@@ -165,7 +191,7 @@ module ThemeCheck
|
|
165
191
|
alias_method :eql?, :==
|
166
192
|
|
167
193
|
def to_s
|
168
|
-
if
|
194
|
+
if theme_file
|
169
195
|
"#{message} at #{location}"
|
170
196
|
else
|
171
197
|
message
|
@@ -173,7 +199,7 @@ module ThemeCheck
|
|
173
199
|
end
|
174
200
|
|
175
201
|
def to_s_range
|
176
|
-
if
|
202
|
+
if theme_file
|
177
203
|
"#{message} at #{location_range}"
|
178
204
|
else
|
179
205
|
message
|
@@ -183,7 +209,7 @@ module ThemeCheck
|
|
183
209
|
def to_h
|
184
210
|
{
|
185
211
|
check: check.code_name,
|
186
|
-
path:
|
212
|
+
path: theme_file&.relative_path,
|
187
213
|
severity: check.severity_value,
|
188
214
|
start_line: start_line,
|
189
215
|
start_column: start_column,
|
data/lib/theme_check/position.rb
CHANGED
@@ -5,6 +5,7 @@ module ThemeCheck
|
|
5
5
|
LIQUID_TAG = /#{Liquid::TagStart}.*?#{Liquid::TagEnd}/om
|
6
6
|
LIQUID_VARIABLE = /#{Liquid::VariableStart}.*?#{Liquid::VariableEnd}/om
|
7
7
|
LIQUID_TAG_OR_VARIABLE = /#{LIQUID_TAG}|#{LIQUID_VARIABLE}/om
|
8
|
+
HTML_LIQUID_PLACEHOLDER = /≬[0-9a-z]+#*≬/m
|
8
9
|
START_OR_END_QUOTE = /(^['"])|(['"]$)/
|
9
10
|
|
10
11
|
def matches(s, re)
|
@@ -16,20 +17,5 @@ module ThemeCheck
|
|
16
17
|
end
|
17
18
|
matches
|
18
19
|
end
|
19
|
-
|
20
|
-
def href_to_file_size(href)
|
21
|
-
# asset_url (+ optional stylesheet_tag) variables
|
22
|
-
if href =~ /^#{LIQUID_VARIABLE}$/o && href =~ /asset_url/ && href =~ Liquid::QuotedString
|
23
|
-
asset_id = Regexp.last_match(0).gsub(START_OR_END_QUOTE, "")
|
24
|
-
asset = @theme.assets.find { |a| a.name.end_with?("/" + asset_id) }
|
25
|
-
return if asset.nil?
|
26
|
-
asset.gzipped_size
|
27
|
-
|
28
|
-
# remote URLs
|
29
|
-
elsif href =~ %r{^(https?:)?//}
|
30
|
-
asset = RemoteAssetFile.from_src(href)
|
31
|
-
asset.gzipped_size
|
32
|
-
end
|
33
|
-
end
|
34
20
|
end
|
35
21
|
end
|
data/lib/theme_check/theme.rb
CHANGED
@@ -6,6 +6,8 @@ module ThemeCheck
|
|
6
6
|
def initialize(relative_path, storage)
|
7
7
|
@relative_path = relative_path
|
8
8
|
@storage = storage
|
9
|
+
@source = nil
|
10
|
+
@eol = "\n"
|
9
11
|
end
|
10
12
|
|
11
13
|
def path
|
@@ -20,8 +22,23 @@ module ThemeCheck
|
|
20
22
|
relative_path.sub_ext('').to_s
|
21
23
|
end
|
22
24
|
|
25
|
+
# For the corrector to work properly, we should have a
|
26
|
+
# simple mental model of the internal representation of eol
|
27
|
+
# characters (Windows uses \r\n, Linux uses \n).
|
28
|
+
#
|
29
|
+
# Parser::Source::Buffer strips the \r from the source file, so if
|
30
|
+
# you are autocorrecting the file you might lose that info and
|
31
|
+
# cause a git diff. It also makes the node.start_index/end_index
|
32
|
+
# calculation break. That's not cool.
|
33
|
+
#
|
34
|
+
# So in here we track whether the source file has \r\n in it and
|
35
|
+
# we'll make sure that the file we write has the same eol as the
|
36
|
+
# source file.
|
23
37
|
def source
|
24
|
-
@source
|
38
|
+
return @source if @source
|
39
|
+
@source = @storage.read(@relative_path)
|
40
|
+
@eol = @source.include?("\r\n") ? "\r\n" : "\n"
|
41
|
+
@source = @source.gsub("\r\n", "\n")
|
25
42
|
end
|
26
43
|
|
27
44
|
def json?
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'parser'
|
4
|
+
|
5
|
+
module ThemeCheck
|
6
|
+
class ThemeFileRewriter
|
7
|
+
def initialize(name, source)
|
8
|
+
@buffer = Parser::Source::Buffer.new(name, source: source)
|
9
|
+
@rewriter = Parser::Source::TreeRewriter.new(
|
10
|
+
@buffer
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def insert_before(node, content)
|
15
|
+
@rewriter.insert_before(
|
16
|
+
range(node.start_index, node.end_index),
|
17
|
+
content
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def insert_after(node, content)
|
22
|
+
@rewriter.insert_after(
|
23
|
+
range(node.start_index, node.end_index),
|
24
|
+
content
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def replace(node, content)
|
29
|
+
@rewriter.replace(
|
30
|
+
range(node.start_index, node.end_index),
|
31
|
+
content
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def wrap(node, insert_before, insert_after)
|
36
|
+
@rewriter.wrap(
|
37
|
+
range(node.start_index, node.end_index),
|
38
|
+
insert_before,
|
39
|
+
insert_after,
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
@rewriter.process
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def range(start_index, end_index)
|
50
|
+
Parser::Source::Range.new(
|
51
|
+
@buffer,
|
52
|
+
start_index,
|
53
|
+
end_index,
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/theme_check/version.rb
CHANGED
data/lib/theme_check.rb
CHANGED
@@ -4,20 +4,23 @@ require "liquid"
|
|
4
4
|
require_relative "theme_check/version"
|
5
5
|
require_relative "theme_check/bug"
|
6
6
|
require_relative "theme_check/exceptions"
|
7
|
+
require_relative "theme_check/theme_file_rewriter"
|
7
8
|
require_relative "theme_check/theme_file"
|
9
|
+
require_relative "theme_check/liquid_file"
|
10
|
+
require_relative "theme_check/asset_file"
|
11
|
+
require_relative "theme_check/json_file"
|
8
12
|
require_relative "theme_check/analyzer"
|
9
13
|
require_relative "theme_check/check"
|
10
14
|
require_relative "theme_check/checks_tracking"
|
15
|
+
require_relative "theme_check/liquid_check"
|
16
|
+
require_relative "theme_check/html_check"
|
17
|
+
require_relative "theme_check/json_check"
|
11
18
|
require_relative "theme_check/cli"
|
12
19
|
require_relative "theme_check/disabled_check"
|
13
20
|
require_relative "theme_check/disabled_checks"
|
14
|
-
require_relative "theme_check/liquid_check"
|
15
21
|
require_relative "theme_check/locale_diff"
|
16
|
-
require_relative "theme_check/asset_file"
|
17
22
|
require_relative "theme_check/remote_asset_file"
|
18
23
|
require_relative "theme_check/regex_helpers"
|
19
|
-
require_relative "theme_check/json_check"
|
20
|
-
require_relative "theme_check/json_file"
|
21
24
|
require_relative "theme_check/json_helpers"
|
22
25
|
require_relative "theme_check/position_helper"
|
23
26
|
require_relative "theme_check/position"
|
@@ -25,22 +28,21 @@ require_relative "theme_check/language_server"
|
|
25
28
|
require_relative "theme_check/checks"
|
26
29
|
require_relative "theme_check/config"
|
27
30
|
require_relative "theme_check/node"
|
31
|
+
require_relative "theme_check/liquid_node"
|
32
|
+
require_relative "theme_check/html_node"
|
28
33
|
require_relative "theme_check/offense"
|
29
34
|
require_relative "theme_check/printer"
|
30
35
|
require_relative "theme_check/json_printer"
|
31
36
|
require_relative "theme_check/shopify_liquid"
|
32
|
-
require_relative "theme_check/storage"
|
33
37
|
require_relative "theme_check/string_helpers"
|
38
|
+
require_relative "theme_check/storage"
|
34
39
|
require_relative "theme_check/file_system_storage"
|
35
40
|
require_relative "theme_check/in_memory_storage"
|
36
41
|
require_relative "theme_check/tags"
|
37
|
-
require_relative "theme_check/template"
|
38
42
|
require_relative "theme_check/theme"
|
39
|
-
require_relative "theme_check/visitor"
|
40
43
|
require_relative "theme_check/corrector"
|
41
|
-
require_relative "theme_check/
|
44
|
+
require_relative "theme_check/liquid_visitor"
|
42
45
|
require_relative "theme_check/html_visitor"
|
43
|
-
require_relative "theme_check/html_check"
|
44
46
|
|
45
47
|
Dir[__dir__ + "/theme_check/checks/*.rb"].each { |file| require file }
|
46
48
|
|
data/theme-check.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
-
spec.add_dependency('liquid', '>= 5.0
|
27
|
+
spec.add_dependency('liquid', '>= 5.1.0')
|
28
28
|
spec.add_dependency('nokogiri', '>= 1.12')
|
29
|
+
spec.add_dependency('parser', '~> 3')
|
29
30
|
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: 1.
|
4
|
+
version: 1.7.0
|
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-09-
|
11
|
+
date: 2021-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: liquid
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.0
|
19
|
+
version: 5.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.0
|
26
|
+
version: 5.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: nokogiri
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: parser
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3'
|
41
55
|
description:
|
42
56
|
email:
|
43
57
|
- marcandre.cournoyer@shopify.com
|
@@ -203,12 +217,16 @@ files:
|
|
203
217
|
- lib/theme_check/language_server/document_link_providers/render_document_link_provider.rb
|
204
218
|
- lib/theme_check/language_server/document_link_providers/section_document_link_provider.rb
|
205
219
|
- lib/theme_check/language_server/handler.rb
|
220
|
+
- lib/theme_check/language_server/messenger.rb
|
206
221
|
- lib/theme_check/language_server/protocol.rb
|
207
222
|
- lib/theme_check/language_server/server.rb
|
208
223
|
- lib/theme_check/language_server/tokens.rb
|
209
224
|
- lib/theme_check/language_server/uri_helper.rb
|
210
225
|
- lib/theme_check/language_server/variable_lookup_finder.rb
|
211
226
|
- lib/theme_check/liquid_check.rb
|
227
|
+
- lib/theme_check/liquid_file.rb
|
228
|
+
- lib/theme_check/liquid_node.rb
|
229
|
+
- lib/theme_check/liquid_visitor.rb
|
212
230
|
- lib/theme_check/locale_diff.rb
|
213
231
|
- lib/theme_check/node.rb
|
214
232
|
- lib/theme_check/offense.rb
|
@@ -228,11 +246,10 @@ files:
|
|
228
246
|
- lib/theme_check/storage.rb
|
229
247
|
- lib/theme_check/string_helpers.rb
|
230
248
|
- lib/theme_check/tags.rb
|
231
|
-
- lib/theme_check/template.rb
|
232
249
|
- lib/theme_check/theme.rb
|
233
250
|
- lib/theme_check/theme_file.rb
|
251
|
+
- lib/theme_check/theme_file_rewriter.rb
|
234
252
|
- lib/theme_check/version.rb
|
235
|
-
- lib/theme_check/visitor.rb
|
236
253
|
- packaging/homebrew/theme_check.base.rb
|
237
254
|
- theme-check.gemspec
|
238
255
|
homepage: https://github.com/Shopify/theme-check
|