theme-check 1.7.2 → 1.8.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/data/shopify_liquid/filters.yml +1 -0
- data/docs/checks/TEMPLATE.md.erb +24 -19
- data/exe/theme-check-language-server +0 -4
- data/lib/theme_check/checks/matching_schema_translations.rb +12 -5
- data/lib/theme_check/checks/required_layout_theme_object.rb +9 -4
- data/lib/theme_check/checks/unused_assign.rb +3 -2
- data/lib/theme_check/checks/unused_snippet.rb +1 -1
- data/lib/theme_check/corrector.rb +40 -3
- data/lib/theme_check/language_server/bridge.rb +18 -4
- data/lib/theme_check/language_server/handler.rb +4 -1
- data/lib/theme_check/language_server/io_messenger.rb +2 -0
- data/lib/theme_check/language_server/protocol.rb +4 -0
- data/lib/theme_check/language_server/server.rb +21 -4
- data/lib/theme_check/liquid_node.rb +33 -0
- data/lib/theme_check/locale_diff.rb +27 -8
- data/lib/theme_check/position.rb +4 -4
- data/lib/theme_check/tags.rb +0 -1
- data/lib/theme_check/theme_file_rewriter.rb +13 -0
- data/lib/theme_check/version.rb +1 -1
- data/lib/theme_check.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8f59cffd194662dc9f66474d70310caeec0a713a3029c92efaefbf605ee69bc
|
4
|
+
data.tar.gz: 7bc65dd34a4b387c13cb0395d3d1cec4d60095a7ba2c3e6fa8fc5fa50bea2df8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ed214b8d5abb83dd3b9ede347fc52f6ed4cce4ddc42b2e0879c24e54b21c0ff30055b5ac8b3e45c3fa5da9efc5da5343c168c6cd818af863d5a73e4841b796b
|
7
|
+
data.tar.gz: 8777e953d57ae33ce11c8bd527e061567ddc179dad28c612d1c7e6f80dd8a5d2534e786b86d5f55d944695c10c08f34b3aeb26057700b50b7b6642fbf8007290
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,20 @@
|
|
1
1
|
|
2
|
+
v1.8.0 / 2021-11-09
|
3
|
+
===================
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
**New corrections for the following checks:**
|
8
|
+
|
9
|
+
* `MissingRequiredTemplateFiles` ([#462](https://github.com/shopify/theme-check/issues/462))
|
10
|
+
* `RequiredLayoutThemeObject` ([#484](https://github.com/shopify/theme-check/issues/484))
|
11
|
+
* `UnusedAssign` ([#380](https://github.com/shopify/theme-check/issues/380))
|
12
|
+
|
13
|
+
## Fixes
|
14
|
+
|
15
|
+
* Add support for `preload_tag` filter
|
16
|
+
* Minor Language Server improvements (close logs) ([#472](https://github.com/shopify/theme-check/issues/472))
|
17
|
+
|
2
18
|
v1.7.2 / 2021-09-24
|
3
19
|
===================
|
4
20
|
|
data/docs/checks/TEMPLATE.md.erb
CHANGED
@@ -1,47 +1,52 @@
|
|
1
1
|
# Check Title (`<%= class_name %>`)
|
2
2
|
|
3
|
-
|
3
|
+
_Version THEME_CHECK_VERSION+_
|
4
4
|
|
5
|
-
|
5
|
+
A short description of what the check does.
|
6
6
|
|
7
|
-
|
7
|
+
A brief paragraph explaining why the check exists (what best practice is it enforcing, and why is it important?).
|
8
8
|
|
9
|
-
|
9
|
+
## Examples
|
10
|
+
|
11
|
+
The following examples contain code snippets that either fail or pass this check.
|
12
|
+
|
13
|
+
### ✗ Fail
|
10
14
|
|
11
15
|
```liquid
|
12
16
|
```
|
13
17
|
|
14
|
-
|
18
|
+
### ✓ Pass
|
15
19
|
|
16
20
|
```liquid
|
17
21
|
```
|
18
22
|
|
19
|
-
##
|
23
|
+
## Options
|
20
24
|
|
21
|
-
The default configuration for this check
|
25
|
+
The following example contains the default configuration for this check:
|
22
26
|
|
23
27
|
```yaml
|
24
28
|
<%= class_name %>:
|
25
|
-
enabled:
|
26
|
-
|
29
|
+
enabled: false
|
30
|
+
severity: suggestion
|
31
|
+
other_option: 10_000
|
27
32
|
```
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
| Parameter | Description |
|
35
|
+
| --- | --- |
|
36
|
+
| enabled | Whether the check is enabled. |
|
37
|
+
| severity | The [severity](https://shopify.developers/themes/tools/theme-check/configuration#check-severity) of the check. |
|
38
|
+
| other_option | A description of the option. |
|
34
39
|
|
35
|
-
|
40
|
+
## Disabling this check
|
36
41
|
|
37
|
-
|
42
|
+
[ This check is safe to disable. You might want to disable this check if ... | Disabling this check isn't recommended because ... ].
|
38
43
|
|
39
|
-
This check
|
44
|
+
[ This check is disabled by default when <condition>. ]
|
40
45
|
|
41
46
|
## Resources
|
42
47
|
|
43
|
-
- [Rule
|
44
|
-
- [Documentation
|
48
|
+
- [Rule source][codesource]
|
49
|
+
- [Documentation source][docsource]
|
45
50
|
|
46
51
|
[codesource]: /<%= code_source %>
|
47
52
|
[docsource]: /<%= doc_source %>
|
@@ -7,7 +7,6 @@ module ThemeCheck
|
|
7
7
|
|
8
8
|
def on_schema(node)
|
9
9
|
schema = JSON.parse(node.value.nodelist.join)
|
10
|
-
|
11
10
|
# Get all locales used in the schema
|
12
11
|
used_locales = Set.new([theme.default_locale])
|
13
12
|
visit_object(schema) do |_, locales|
|
@@ -19,11 +18,17 @@ module ThemeCheck
|
|
19
18
|
visit_object(schema) do |key, locales|
|
20
19
|
missing = used_locales - locales
|
21
20
|
if missing.any?
|
22
|
-
add_offense("#{key} missing translations for #{missing.join(', ')}", node: node)
|
21
|
+
add_offense("#{key} missing translations for #{missing.join(', ')}", node: node) do |corrector|
|
22
|
+
key = key.split(".")
|
23
|
+
missing.each do |language|
|
24
|
+
corrector.schema_corrector(schema, key + [language], "TODO")
|
25
|
+
end
|
26
|
+
corrector.replace_block_body(node, schema)
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
26
|
-
check_locales(schema
|
31
|
+
check_locales(schema, node: node)
|
27
32
|
|
28
33
|
rescue JSON::ParserError
|
29
34
|
# Ignored, handled in ValidSchema.
|
@@ -31,14 +36,16 @@ module ThemeCheck
|
|
31
36
|
|
32
37
|
private
|
33
38
|
|
34
|
-
def check_locales(
|
39
|
+
def check_locales(schema, node:)
|
40
|
+
locales = schema["locales"]
|
35
41
|
return unless locales.is_a?(Hash)
|
36
42
|
|
37
43
|
default_locale = locales[theme.default_locale]
|
44
|
+
|
38
45
|
if default_locale
|
39
46
|
locales.each_pair do |name, content|
|
40
47
|
diff = LocaleDiff.new(default_locale, content)
|
41
|
-
diff.add_as_offenses(self, key_prefix: ["locales", name], node: node)
|
48
|
+
diff.add_as_offenses(self, key_prefix: ["locales", name], node: node, schema: schema)
|
42
49
|
end
|
43
50
|
else
|
44
51
|
add_offense("Missing default locale in key: locales", node: node)
|
@@ -27,14 +27,19 @@ module ThemeCheck
|
|
27
27
|
def after_document(node)
|
28
28
|
return unless node.theme_file.name == LAYOUT_FILENAME
|
29
29
|
|
30
|
-
add_missing_object_offense("content_for_layout") unless @content_for_layout_found
|
31
|
-
add_missing_object_offense("content_for_header") unless @content_for_header_found
|
30
|
+
add_missing_object_offense("content_for_layout", "</body>") unless @content_for_layout_found
|
31
|
+
add_missing_object_offense("content_for_header", "</head>") unless @content_for_header_found
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
-
def add_missing_object_offense(name)
|
37
|
-
add_offense("#{LAYOUT_FILENAME} must include {{#{name}}}", node: @layout_theme_node)
|
36
|
+
def add_missing_object_offense(name, tag)
|
37
|
+
add_offense("#{LAYOUT_FILENAME} must include {{#{name}}}", node: @layout_theme_node) do
|
38
|
+
if @layout_theme_node.source.index(tag)
|
39
|
+
@layout_theme_node.source.insert(@layout_theme_node.source.index(tag), " {{ #{name} }}\n ")
|
40
|
+
@layout_theme_node.markup = @layout_theme_node.source
|
41
|
+
end
|
42
|
+
end
|
38
43
|
end
|
39
44
|
end
|
40
45
|
end
|
@@ -46,8 +46,9 @@ module ThemeCheck
|
|
46
46
|
@templates.each_pair do |_, info|
|
47
47
|
used = info.collect_used_assigns(@templates)
|
48
48
|
info.assign_nodes.each_pair do |name, node|
|
49
|
-
|
50
|
-
|
49
|
+
next if used.include?(name)
|
50
|
+
add_offense("`#{name}` is never used", node: node) do |corrector|
|
51
|
+
corrector.remove(node)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
@@ -25,7 +25,7 @@ module ThemeCheck
|
|
25
25
|
def on_end
|
26
26
|
missing_snippets.each do |theme_file|
|
27
27
|
add_offense("This snippet is not used", theme_file: theme_file) do |corrector|
|
28
|
-
corrector.
|
28
|
+
corrector.remove_file(@theme, theme_file.relative_path.to_s)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -14,11 +14,20 @@ module ThemeCheck
|
|
14
14
|
@theme_file.rewriter.insert_before(node, content)
|
15
15
|
end
|
16
16
|
|
17
|
+
def remove(node)
|
18
|
+
@theme_file.rewriter.remove(node)
|
19
|
+
end
|
20
|
+
|
17
21
|
def replace(node, content)
|
18
22
|
@theme_file.rewriter.replace(node, content)
|
19
23
|
node.markup = content
|
20
24
|
end
|
21
25
|
|
26
|
+
def replace_block_body(node, content)
|
27
|
+
content = "\n #{JSON.pretty_generate(content, array_nl: "\n ", object_nl: "\n ")}\n" if content.is_a?(Hash)
|
28
|
+
@theme_file.rewriter.replace_body(node, content)
|
29
|
+
end
|
30
|
+
|
22
31
|
def wrap(node, insert_before, insert_after)
|
23
32
|
@theme_file.rewriter.wrap(node, insert_before, insert_after)
|
24
33
|
end
|
@@ -28,11 +37,11 @@ module ThemeCheck
|
|
28
37
|
end
|
29
38
|
|
30
39
|
def create_default_locale_json(theme)
|
40
|
+
create(theme, "locales/#{theme.default_locale}.default.json", {})
|
31
41
|
theme.default_locale_json = JsonFile.new("locales/#{theme.default_locale}.default.json", theme.storage)
|
32
|
-
theme.default_locale_json.update_contents({})
|
33
42
|
end
|
34
43
|
|
35
|
-
def
|
44
|
+
def remove_file(theme, relative_path)
|
36
45
|
theme.storage.remove(relative_path)
|
37
46
|
end
|
38
47
|
|
@@ -42,12 +51,40 @@ module ThemeCheck
|
|
42
51
|
|
43
52
|
def add_default_translation_key(file, key, value)
|
44
53
|
hash = file.content
|
54
|
+
add_key(hash, key, value)
|
55
|
+
file.update_contents(hash)
|
56
|
+
end
|
57
|
+
|
58
|
+
def remove_key(hash, key)
|
59
|
+
key.reduce(hash) do |pointer, token|
|
60
|
+
return pointer.delete(token) if token == key.last
|
61
|
+
pointer[token]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_key(hash, key, value)
|
45
66
|
key.reduce(hash) do |pointer, token|
|
46
67
|
return pointer[token] = value if token == key.last
|
47
68
|
pointer[token] = {} unless pointer.key?(token)
|
48
69
|
pointer[token]
|
49
70
|
end
|
50
|
-
|
71
|
+
end
|
72
|
+
|
73
|
+
def schema_corrector(schema, key, value)
|
74
|
+
return unless schema.is_a?(Hash)
|
75
|
+
key.reduce(schema) do |pointer, token|
|
76
|
+
case pointer
|
77
|
+
when Array
|
78
|
+
pointer.each do |item|
|
79
|
+
schema_corrector(item, key.drop(1), value)
|
80
|
+
end
|
81
|
+
|
82
|
+
when Hash
|
83
|
+
return pointer[token] = value if token == key.last
|
84
|
+
pointer[token] = {} unless pointer.key?(token) || pointer.key?("id")
|
85
|
+
pointer[token].nil? && pointer["id"] == token ? pointer : pointer[token]
|
86
|
+
end
|
87
|
+
end
|
51
88
|
end
|
52
89
|
end
|
53
90
|
end
|
@@ -38,14 +38,14 @@ module ThemeCheck
|
|
38
38
|
def read_message
|
39
39
|
message_body = @messenger.read_message
|
40
40
|
message_json = JSON.parse(message_body)
|
41
|
-
@messenger.log(JSON.pretty_generate(message_json)) if
|
41
|
+
@messenger.log(JSON.pretty_generate(message_json)) if ThemeCheck.debug?
|
42
42
|
message_json
|
43
43
|
end
|
44
44
|
|
45
45
|
def send_message(message_hash)
|
46
46
|
message_hash[:jsonrpc] = '2.0'
|
47
47
|
message_body = JSON.dump(message_hash)
|
48
|
-
@messenger.log(JSON.pretty_generate(message_hash)) if
|
48
|
+
@messenger.log(JSON.pretty_generate(message_hash)) if ThemeCheck.debug?
|
49
49
|
@messenger.send_message(message_body)
|
50
50
|
end
|
51
51
|
|
@@ -68,11 +68,25 @@ module ThemeCheck
|
|
68
68
|
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#responseMessage
|
69
69
|
def send_response(id, result = nil, error = nil)
|
70
70
|
message = { id: id }
|
71
|
-
|
72
|
-
|
71
|
+
if error
|
72
|
+
message[:error] = error
|
73
|
+
else
|
74
|
+
message[:result] = result
|
75
|
+
end
|
73
76
|
send_message(message)
|
74
77
|
end
|
75
78
|
|
79
|
+
# https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#responseError
|
80
|
+
def send_internal_error(id, e)
|
81
|
+
send_response(id, nil, {
|
82
|
+
code: ErrorCodes::INTERNAL_ERROR,
|
83
|
+
message: <<~EOS,
|
84
|
+
#{e.class}: #{e.message}
|
85
|
+
#{e.backtrace.join("\n ")}
|
86
|
+
EOS
|
87
|
+
})
|
88
|
+
end
|
89
|
+
|
76
90
|
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#notificationMessage
|
77
91
|
def send_notification(method, params)
|
78
92
|
message = { method: method }
|
@@ -47,10 +47,13 @@ module ThemeCheck
|
|
47
47
|
})
|
48
48
|
end
|
49
49
|
|
50
|
+
def on_shutdown(id, _params)
|
51
|
+
@bridge.send_response(id, nil)
|
52
|
+
end
|
53
|
+
|
50
54
|
def on_exit(_id, _params)
|
51
55
|
close!
|
52
56
|
end
|
53
|
-
alias_method :on_shutdown, :on_exit
|
54
57
|
|
55
58
|
def on_text_document_did_change(_id, params)
|
56
59
|
relative_path = relative_path_from_text_document_uri(params)
|
@@ -37,7 +37,7 @@ module ThemeCheck
|
|
37
37
|
@handlers = []
|
38
38
|
|
39
39
|
# The error queue holds blocks the main thread. When filled, we exit the program.
|
40
|
-
@error = SizedQueue.new(
|
40
|
+
@error = SizedQueue.new(number_of_threads)
|
41
41
|
|
42
42
|
@should_raise_errors = should_raise_errors
|
43
43
|
end
|
@@ -94,8 +94,7 @@ module ThemeCheck
|
|
94
94
|
|
95
95
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
96
96
|
raise e if should_raise_errors
|
97
|
-
@bridge.log(e)
|
98
|
-
@bridge.log(e.backtrace)
|
97
|
+
@bridge.log("#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}")
|
99
98
|
2
|
100
99
|
end
|
101
100
|
|
@@ -110,6 +109,15 @@ module ThemeCheck
|
|
110
109
|
if @handler.respond_to?(method_name)
|
111
110
|
@handler.send(method_name, id, params)
|
112
111
|
end
|
112
|
+
|
113
|
+
rescue DoneStreaming => e
|
114
|
+
raise e
|
115
|
+
rescue StandardError => e
|
116
|
+
is_request = id
|
117
|
+
raise e unless is_request
|
118
|
+
# Errors obtained in request handlers should be sent
|
119
|
+
# back as internal errors instead of closing the program.
|
120
|
+
@bridge.send_internal_error(id, e)
|
113
121
|
end
|
114
122
|
|
115
123
|
def handle_response(message)
|
@@ -135,7 +143,16 @@ module ThemeCheck
|
|
135
143
|
|
136
144
|
# Hijack the status_code if an error occurred while cleaning up.
|
137
145
|
# 👀 unit tests.
|
138
|
-
|
146
|
+
until @error.empty?
|
147
|
+
code = status_code_from_error(@error.pop)
|
148
|
+
# Promote the status_code to ERROR if one of the threads
|
149
|
+
# resulted in an error, otherwise leave the status_code as
|
150
|
+
# is. That's because one thread could end successfully in a
|
151
|
+
# DoneStreaming error while the other failed with an
|
152
|
+
# internal error. If we had an internal error, we should
|
153
|
+
# return with a status_code that fits.
|
154
|
+
status_code = code if code > status_code
|
155
|
+
end
|
139
156
|
status_code
|
140
157
|
ensure
|
141
158
|
@messenger.close_output
|
@@ -74,6 +74,34 @@ module ThemeCheck
|
|
74
74
|
position.end_index
|
75
75
|
end
|
76
76
|
|
77
|
+
def start_token_index
|
78
|
+
return position.start_index if inside_liquid_tag?
|
79
|
+
position.start_index - (start_token.length + 1)
|
80
|
+
end
|
81
|
+
|
82
|
+
def end_token_index
|
83
|
+
return position.end_index if inside_liquid_tag?
|
84
|
+
position.end_index + end_token.length
|
85
|
+
end
|
86
|
+
|
87
|
+
def render_start_tag
|
88
|
+
"#{start_token} #{@value.raw}#{end_token}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def render_end_tag
|
92
|
+
"#{start_token} #{@value.block_delimiter} #{end_token}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def block_body_start_index
|
96
|
+
return unless block_tag?
|
97
|
+
block_regex.begin(:body)
|
98
|
+
end
|
99
|
+
|
100
|
+
def block_body_end_index
|
101
|
+
return unless block_tag?
|
102
|
+
block_regex.end(:body)
|
103
|
+
end
|
104
|
+
|
77
105
|
# Literals are hard-coded values in the liquid file.
|
78
106
|
def literal?
|
79
107
|
@value.is_a?(String) || @value.is_a?(Integer)
|
@@ -184,6 +212,11 @@ module ThemeCheck
|
|
184
212
|
|
185
213
|
private
|
186
214
|
|
215
|
+
def block_regex
|
216
|
+
return unless block_tag?
|
217
|
+
/(?<start_token>#{render_start_tag})(?<body>.*)(?<end_token>#{render_end_tag})/m.match(source)
|
218
|
+
end
|
219
|
+
|
187
220
|
def position
|
188
221
|
@position ||= Position.new(
|
189
222
|
markup,
|
@@ -14,24 +14,43 @@ module ThemeCheck
|
|
14
14
|
visit_object(@default, @other, [])
|
15
15
|
end
|
16
16
|
|
17
|
-
def add_as_offenses(check, key_prefix: [], node: nil, theme_file: nil)
|
17
|
+
def add_as_offenses(check, key_prefix: [], node: nil, theme_file: nil, schema: {})
|
18
18
|
if extra_keys.any?
|
19
|
-
|
20
|
-
key_prefix: key_prefix, node: node, theme_file: theme_file)
|
19
|
+
remove_extra_keys_offense(check, "Extra translation keys", extra_keys,
|
20
|
+
key_prefix: key_prefix, node: node, theme_file: theme_file, schema: schema)
|
21
21
|
end
|
22
22
|
|
23
23
|
if missing_keys.any?
|
24
|
-
|
25
|
-
key_prefix: key_prefix, node: node, theme_file: theme_file)
|
24
|
+
add_missing_keys_offense(check, "Missing translation keys", missing_keys,
|
25
|
+
key_prefix: key_prefix, node: node, theme_file: theme_file, schema: schema)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
-
def
|
32
|
-
message = "#{cause}: #{format_keys(key_prefix,
|
31
|
+
def remove_extra_keys_offense(check, cause, extra_keys, key_prefix:, node: nil, theme_file: nil, schema: {})
|
32
|
+
message = "#{cause}: #{format_keys(key_prefix, extra_keys)}"
|
33
33
|
if node
|
34
|
-
check.add_offense(message, node: node)
|
34
|
+
check.add_offense(message, node: node) do |corrector|
|
35
|
+
extra_keys.each do |k|
|
36
|
+
corrector.remove_key(schema, key_prefix + k)
|
37
|
+
end
|
38
|
+
corrector.replace_block_body(node, schema)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
check.add_offense(message, theme_file: theme_file)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_missing_keys_offense(check, cause, missing_keys, key_prefix:, node: nil, theme_file: nil, schema: {})
|
46
|
+
message = "#{cause}: #{format_keys(key_prefix, missing_keys)}"
|
47
|
+
if node
|
48
|
+
check.add_offense(message, node: node) do |corrector|
|
49
|
+
missing_keys.each do |k|
|
50
|
+
corrector.add_key(schema, key_prefix + k, "TODO")
|
51
|
+
end
|
52
|
+
corrector.replace_block_body(node, schema)
|
53
|
+
end
|
35
54
|
else
|
36
55
|
check.add_offense(message, theme_file: theme_file)
|
37
56
|
end
|
data/lib/theme_check/position.rb
CHANGED
@@ -64,6 +64,10 @@ module ThemeCheck
|
|
64
64
|
strict_position.end_column
|
65
65
|
end
|
66
66
|
|
67
|
+
def content_line_count
|
68
|
+
@content_line_count ||= contents.count("\n")
|
69
|
+
end
|
70
|
+
|
67
71
|
private
|
68
72
|
|
69
73
|
def compute_start_offset
|
@@ -78,10 +82,6 @@ module ThemeCheck
|
|
78
82
|
@contents
|
79
83
|
end
|
80
84
|
|
81
|
-
def content_line_count
|
82
|
-
@content_line_count ||= contents.count("\n")
|
83
|
-
end
|
84
|
-
|
85
85
|
def line_number
|
86
86
|
return 0 if @line_number_1_indexed.nil?
|
87
87
|
bounded(0, @line_number_1_indexed - 1, content_line_count)
|
data/lib/theme_check/tags.rb
CHANGED
@@ -25,6 +25,12 @@ module ThemeCheck
|
|
25
25
|
)
|
26
26
|
end
|
27
27
|
|
28
|
+
def remove(node)
|
29
|
+
@rewriter.remove(
|
30
|
+
range(node.start_token_index, node.end_token_index)
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
28
34
|
def replace(node, content)
|
29
35
|
@rewriter.replace(
|
30
36
|
range(node.start_index, node.end_index),
|
@@ -32,6 +38,13 @@ module ThemeCheck
|
|
32
38
|
)
|
33
39
|
end
|
34
40
|
|
41
|
+
def replace_body(node, content)
|
42
|
+
@rewriter.replace(
|
43
|
+
range(node.block_body_start_index, node.block_body_end_index),
|
44
|
+
content
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
35
48
|
def wrap(node, insert_before, insert_after)
|
36
49
|
@rewriter.wrap(
|
37
50
|
range(node.start_index, node.end_index),
|
data/lib/theme_check/version.rb
CHANGED
data/lib/theme_check.rb
CHANGED
@@ -51,6 +51,10 @@ Encoding.default_external = Encoding::UTF_8
|
|
51
51
|
Encoding.default_internal = Encoding::UTF_8
|
52
52
|
|
53
53
|
module ThemeCheck
|
54
|
+
def self.debug?
|
55
|
+
ENV["THEME_CHECK_DEBUG"] == "true"
|
56
|
+
end
|
57
|
+
|
54
58
|
def self.with_liquid_c_disabled
|
55
59
|
if defined?(Liquid::C)
|
56
60
|
was_enabled = Liquid::C.enabled
|
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.8.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-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: liquid
|