theme-check 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8bec2f54c12487d444bebd3bb0abad48ec133c4e9504be29857a58c87d82f589
4
- data.tar.gz: 2cacd6af05aa3c2af8d40167a04532ed998d24049df7b277f70baf50f0a4e401
3
+ metadata.gz: e154c11ed7f84b968edac05c97afb2611e816933d790347cdbdca63071d46e88
4
+ data.tar.gz: dd8fc72c420412ab3adfad64f3d11197f562904bd0171289debe8e440ca34c86
5
5
  SHA512:
6
- metadata.gz: 95a61ee91b1a575dead56345172c5472cdb1c314b94aef37814f311ab54d39263a70d51192ea5d276188d06e8ddc32715f9693f7089157e3376bd7c885b1d30a
7
- data.tar.gz: 6fe39a2b8944ceb34e48b5a4a84cbb1f544d870b9c38f36dff33ff2e226f76feabb612d9f9e98ce31c2c68209014b46d76adcd0a4dd37224aee3c2ee266e50d0
6
+ metadata.gz: 0315a3eb75f5cda96fe2be02d7533e07aa364fc7b3e08bdb2682edf50f30d13bc2c03099d015c73db2e1c6e7d06c90707068d596db044176ddcdaea4bfe3a65c
7
+ data.tar.gz: a7050df945829d05a0440464d0ac309d3cc55d9fdd9909259b95f2405beae746e799aad8beeb564508b0a543568dcd718edb9638c1307bb345051784818ea165
data/CHANGELOG.md CHANGED
@@ -1,4 +1,17 @@
1
1
 
2
+ v1.4.0 / 2021-08-30
3
+ ==================
4
+
5
+ * Add new object drop: `predictive_search`
6
+ * Bump `TemplateLength` `max_length` default
7
+ * Fix `RemoteAsset` incorrectly firing on structured data elements [#393](https://github.com/Shopify/theme-check/issues/393)
8
+ * Fix document links not working on open
9
+ * Fix `asset_url` document links
10
+ * Use better heuristics for `DeprecateLazysizes`
11
+ * Add support for `section` document links
12
+ * Add support for `include` document links
13
+ * Automatically creates the default translation file (`locales/en.default.json`) if it doesn't already exist.
14
+
2
15
  v1.3.0 / 2021-08-26
3
16
  ==================
4
17
 
data/config/default.yml CHANGED
@@ -45,7 +45,7 @@ SyntaxError:
45
45
  TemplateLength:
46
46
  enabled: true
47
47
  ignore: []
48
- max_length: 500
48
+ max_length: 600
49
49
  # Exclude content of {% schema %} in line count
50
50
  exclude_schema: true
51
51
  # Exclude content of {% stylesheet %} in line count
@@ -54,6 +54,7 @@
54
54
  - part
55
55
  - policy
56
56
  - powered_by_link
57
+ - predictive_search
57
58
  - product
58
59
  - product_option
59
60
  - product_variant
@@ -10,9 +10,6 @@ This check is aimed at discouraging the use of the lazysizes JavaScript library
10
10
 
11
11
  ```liquid
12
12
 
13
- <!-- Reports use of "lazyload" class -->
14
- <img src="a.jpg" class="lazyload">
15
-
16
13
  <!-- Reports use of "data-srcset" and "data-sizes" attribute. Reports data-sizes="auto" -->
17
14
  <img
18
15
  alt="House by the lake"
@@ -21,7 +21,7 @@ The default configuration for this check is the following:
21
21
  ```yaml
22
22
  TemplateLength:
23
23
  enabled: true
24
- max_length: 500
24
+ max_length: 600
25
25
  exclude_schema: true
26
26
  exclude_stylesheet: true
27
27
  exclude_javascript: true
@@ -87,6 +87,7 @@ module ThemeCheck
87
87
  if @auto_correct
88
88
  offenses.each(&:correct)
89
89
  @theme.liquid.each(&:write)
90
+ @theme.json.each(&:write)
90
91
  end
91
92
  end
92
93
 
@@ -7,7 +7,9 @@ module ThemeCheck
7
7
 
8
8
  def on_end
9
9
  return if @theme.default_locale_json
10
- add_offense("Default translation file not found (for example locales/en.default.json)")
10
+ add_offense("Default translation file not found (for example locales/en.default.json)") do |corrector|
11
+ corrector.create_default_locale_json(@theme)
12
+ end
11
13
  end
12
14
  end
13
15
  end
@@ -7,10 +7,13 @@ module ThemeCheck
7
7
 
8
8
  def on_img(node)
9
9
  class_list = node.attributes["class"]&.split(" ")
10
+ has_loading_lazy = node.attributes["loading"] == "lazy"
11
+ has_native_source = node.attributes["src"] || node.attributes["srcset"]
12
+ return if has_native_source && has_loading_lazy
13
+ has_lazysize_source = node.attributes["data-srcset"] || node.attributes["data-src"]
14
+ has_lazysize_class = class_list&.include?("lazyload")
15
+ return unless has_lazysize_class && has_lazysize_source
10
16
  add_offense("Use the native loading=\"lazy\" attribute instead of lazysizes", node: node) if class_list&.include?("lazyload")
11
- add_offense("Use the native srcset attribute instead of data-srcset", node: node) if node.attributes["data-srcset"]
12
- add_offense("Use the native sizes attribute instead of data-sizes", node: node) if node.attributes["data-sizes"]
13
- add_offense("Do not set the data-sizes attribute to auto", node: node) if node.attributes["data-sizes"] == "auto"
14
17
  end
15
18
  end
16
19
  end
@@ -23,9 +23,9 @@ module ThemeCheck
23
23
  return if resource_url =~ RELATIVE_PATH
24
24
  return if url_hosted_by_shopify?(resource_url)
25
25
 
26
- # Ignore non-stylesheet rel tags
26
+ # Ignore non-stylesheet link tags
27
27
  rel = node.attributes["rel"]
28
- return if rel && rel != "stylesheet"
28
+ return if node.name == "link" && rel != "stylesheet"
29
29
 
30
30
  add_offense(
31
31
  "Asset should be served by the Shopify CDN for better performance.",
@@ -5,7 +5,7 @@ module ThemeCheck
5
5
  category :liquid
6
6
  doc docs_url(__FILE__)
7
7
 
8
- def initialize(max_length: 500, exclude_schema: true, exclude_stylesheet: true, exclude_javascript: true)
8
+ def initialize(max_length: 600, exclude_schema: true, exclude_stylesheet: true, exclude_javascript: true)
9
9
  @max_length = max_length
10
10
  @exclude_schema = exclude_schema
11
11
  @exclude_stylesheet = exclude_stylesheet
@@ -31,5 +31,10 @@ module ThemeCheck
31
31
  def create(theme, relative_path, content)
32
32
  theme.storage.write(relative_path, content)
33
33
  end
34
+
35
+ def create_default_locale_json(theme)
36
+ theme.default_locale_json = JsonFile.new("locales/#{theme.default_locale}.default.json", theme.storage)
37
+ theme.default_locale_json.update_contents('{}')
38
+ end
34
39
  end
35
40
  end
@@ -20,6 +20,17 @@ module ThemeCheck
20
20
  @parser_error
21
21
  end
22
22
 
23
+ def update_contents(new_content = '{}')
24
+ @content = new_content
25
+ end
26
+
27
+ def write
28
+ if source != @content
29
+ @storage.write(@relative_path, content)
30
+ @source = content
31
+ end
32
+ end
33
+
23
34
  def json?
24
35
  true
25
36
  end
@@ -2,21 +2,28 @@
2
2
 
3
3
  module ThemeCheck
4
4
  module LanguageServer
5
- PARTIAL_RENDER = %r{
6
- \{\%-?\s*render\s+'(?<partial>[^']*)'|
7
- \{\%-?\s*render\s+"(?<partial>[^"]*)"|
5
+ def self.partial_tag(tag)
6
+ %r{
7
+ \{\%-?\s*#{tag}\s+'(?<partial>[^']*)'|
8
+ \{\%-?\s*#{tag}\s+"(?<partial>[^"]*)"|
9
+
10
+ # in liquid tags the whole line is white space until the tag
11
+ ^\s*#{tag}\s+'(?<partial>[^']*)'|
12
+ ^\s*#{tag}\s+"(?<partial>[^"]*)"
13
+ }mix
14
+ end
15
+
16
+ PARTIAL_RENDER = partial_tag('render')
17
+ PARTIAL_INCLUDE = partial_tag('include')
18
+ PARTIAL_SECTION = partial_tag('section')
8
19
 
9
- # in liquid tags the whole line is white space until render
10
- ^\s*render\s+'(?<partial>[^']*)'|
11
- ^\s*render\s+"(?<partial>[^"]*)"
12
- }mix
13
20
  ASSET_INCLUDE = %r{
14
- \{\%-?\s*'(?<partial>[^']*)'\s*\|\s*asset_url|
15
- \{\%-?\s*"(?<partial>[^"]*)"\s*\|\s*asset_url|
21
+ \{\{-?\s*'(?<partial>[^']*)'\s*\|\s*asset_url|
22
+ \{\{-?\s*"(?<partial>[^"]*)"\s*\|\s*asset_url|
16
23
 
17
24
  # in liquid tags the whole line is white space until the asset partial
18
- ^\s*'(?<partial>[^']*)'\s*\|\s*asset_url|
19
- ^\s*"(?<partial>[^"]*)"\s*\|\s*asset_url
25
+ ^\s*(?:echo|assign[^=]*\=)\s*'(?<partial>[^']*)'\s*\|\s*asset_url|
26
+ ^\s*(?:echo|assign[^=]*\=)\s*"(?<partial>[^"]*)"\s*\|\s*asset_url
20
27
  }mix
21
28
  end
22
29
  end
@@ -3,81 +3,17 @@
3
3
  module ThemeCheck
4
4
  module LanguageServer
5
5
  class DocumentLinkEngine
6
- include PositionHelper
7
- include RegexHelpers
8
-
9
6
  def initialize(storage)
10
7
  @storage = storage
8
+ @providers = DocumentLinkProvider.all.map { |x| x.new(storage) }
11
9
  end
12
10
 
13
11
  def document_links(relative_path)
14
12
  buffer = @storage.read(relative_path)
15
13
  return [] unless buffer
16
- snippet_matches = matches(buffer, PARTIAL_RENDER).map do |match|
17
- start_line, start_character = from_index_to_row_column(
18
- buffer,
19
- match.begin(:partial),
20
- )
21
-
22
- end_line, end_character = from_index_to_row_column(
23
- buffer,
24
- match.end(:partial)
25
- )
26
-
27
- {
28
- target: snippet_link(match[:partial]),
29
- range: {
30
- start: {
31
- line: start_line,
32
- character: start_character,
33
- },
34
- end: {
35
- line: end_line,
36
- character: end_character,
37
- },
38
- },
39
- }
14
+ @providers.flat_map do |p|
15
+ p.document_links(buffer)
40
16
  end
41
- asset_matches = matches(buffer, ASSET_INCLUDE).map do |match|
42
- start_line, start_character = from_index_to_row_column(
43
- buffer,
44
- match.begin(:partial),
45
- )
46
-
47
- end_line, end_character = from_index_to_row_column(
48
- buffer,
49
- match.end(:partial)
50
- )
51
-
52
- {
53
- target: asset_link(match[:partial]),
54
- range: {
55
- start: {
56
- line: start_line,
57
- character: start_character,
58
- },
59
- end: {
60
- line: end_line,
61
- character: end_character,
62
- },
63
- },
64
- }
65
- end
66
- snippet_matches + asset_matches
67
- end
68
-
69
- def snippet_link(partial)
70
- file_link('snippets', partial, '.liquid')
71
- end
72
-
73
- def asset_link(partial)
74
- file_link('assets', partial, '')
75
- end
76
-
77
- private
78
-
79
- def file_link(directory, partial, extension)
80
- "file://#{@storage.path(directory + '/' + partial + extension)}"
81
17
  end
82
18
  end
83
19
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ module LanguageServer
5
+ class DocumentLinkProvider
6
+ include RegexHelpers
7
+ include PositionHelper
8
+
9
+ class << self
10
+ attr_accessor :partial_regexp, :destination_directory, :destination_postfix
11
+
12
+ def all
13
+ @all ||= []
14
+ end
15
+
16
+ def inherited(subclass)
17
+ all << subclass
18
+ end
19
+ end
20
+
21
+ def initialize(storage = InMemoryStorage.new)
22
+ @storage = storage
23
+ end
24
+
25
+ def partial_regexp
26
+ self.class.partial_regexp
27
+ end
28
+
29
+ def destination_directory
30
+ self.class.destination_directory
31
+ end
32
+
33
+ def destination_postfix
34
+ self.class.destination_postfix
35
+ end
36
+
37
+ def document_links(buffer)
38
+ matches(buffer, partial_regexp).map do |match|
39
+ start_line, start_character = from_index_to_row_column(
40
+ buffer,
41
+ match.begin(:partial),
42
+ )
43
+
44
+ end_line, end_character = from_index_to_row_column(
45
+ buffer,
46
+ match.end(:partial)
47
+ )
48
+
49
+ {
50
+ target: file_link(match[:partial]),
51
+ range: {
52
+ start: {
53
+ line: start_line,
54
+ character: start_character,
55
+ },
56
+ end: {
57
+ line: end_line,
58
+ character: end_character,
59
+ },
60
+ },
61
+ }
62
+ end
63
+ end
64
+
65
+ def file_link(partial)
66
+ "file://#{@storage.path(destination_directory + '/' + partial + destination_postfix)}"
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ module LanguageServer
5
+ class AssetDocumentLinkProvider < DocumentLinkProvider
6
+ @partial_regexp = ASSET_INCLUDE
7
+ @destination_directory = "assets"
8
+ @destination_postfix = ""
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ module LanguageServer
5
+ class IncludeDocumentLinkProvider < DocumentLinkProvider
6
+ @partial_regexp = PARTIAL_INCLUDE
7
+ @destination_directory = "snippets"
8
+ @destination_postfix = ".liquid"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ module LanguageServer
5
+ class RenderDocumentLinkProvider < DocumentLinkProvider
6
+ @partial_regexp = PARTIAL_RENDER
7
+ @destination_directory = "snippets"
8
+ @destination_postfix = ".liquid"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ module LanguageServer
5
+ class SectionDocumentLinkProvider < DocumentLinkProvider
6
+ @partial_regexp = PARTIAL_SECTION
7
+ @destination_directory = "sections"
8
+ @destination_postfix = ".liquid"
9
+ end
10
+ end
11
+ end
@@ -55,10 +55,9 @@ module ThemeCheck
55
55
  end
56
56
 
57
57
  def on_text_document_did_open(_id, params)
58
- return unless @diagnostics_tracker.first_run?
59
58
  relative_path = relative_path_from_text_document_uri(params)
60
59
  @storage.write(relative_path, text_document_text(params))
61
- analyze_and_send_offenses(text_document_uri(params))
60
+ analyze_and_send_offenses(text_document_uri(params)) if @diagnostics_tracker.first_run?
62
61
  end
63
62
 
64
63
  def on_text_document_did_save(_id, params)
@@ -8,6 +8,7 @@ require_relative "language_server/variable_lookup_finder"
8
8
  require_relative "language_server/completion_helper"
9
9
  require_relative "language_server/completion_provider"
10
10
  require_relative "language_server/completion_engine"
11
+ require_relative "language_server/document_link_provider"
11
12
  require_relative "language_server/document_link_engine"
12
13
  require_relative "language_server/diagnostics_tracker"
13
14
 
@@ -15,6 +16,10 @@ Dir[__dir__ + "/language_server/completion_providers/*.rb"].each do |file|
15
16
  require file
16
17
  end
17
18
 
19
+ Dir[__dir__ + "/language_server/document_link_providers/*.rb"].each do |file|
20
+ require file
21
+ end
22
+
18
23
  module ThemeCheck
19
24
  module LanguageServer
20
25
  def self.start
@@ -7,7 +7,8 @@ module ThemeCheck
7
7
  LIQUID_REGEX = /\.liquid$/i
8
8
  JSON_REGEX = /\.json$/i
9
9
 
10
- attr_accessor :storage
10
+ attr_reader :storage
11
+ attr_writer :default_locale_json
11
12
 
12
13
  def initialize(storage)
13
14
  @storage = storage
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- VERSION = "1.3.0"
3
+ VERSION = "1.4.0"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: theme-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-André Cournoyer
@@ -194,6 +194,11 @@ files:
194
194
  - lib/theme_check/language_server/constants.rb
195
195
  - lib/theme_check/language_server/diagnostics_tracker.rb
196
196
  - lib/theme_check/language_server/document_link_engine.rb
197
+ - lib/theme_check/language_server/document_link_provider.rb
198
+ - lib/theme_check/language_server/document_link_providers/asset_document_link_provider.rb
199
+ - lib/theme_check/language_server/document_link_providers/include_document_link_provider.rb
200
+ - lib/theme_check/language_server/document_link_providers/render_document_link_provider.rb
201
+ - lib/theme_check/language_server/document_link_providers/section_document_link_provider.rb
197
202
  - lib/theme_check/language_server/handler.rb
198
203
  - lib/theme_check/language_server/protocol.rb
199
204
  - lib/theme_check/language_server/server.rb