theme-check 1.1.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/theme-check.yml +5 -9
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +50 -0
  5. data/CONTRIBUTING.md +1 -1
  6. data/RELEASING.md +34 -2
  7. data/bin/theme-check +29 -0
  8. data/bin/theme-check-language-server +29 -0
  9. data/config/default.yml +15 -1
  10. data/config/theme_app_extension.yml +15 -0
  11. data/data/shopify_liquid/objects.yml +1 -0
  12. data/docs/checks/app_block_valid_tags.md +40 -0
  13. data/docs/checks/asset_size_app_block_css.md +1 -1
  14. data/docs/checks/deprecate_lazysizes.md +0 -3
  15. data/docs/checks/deprecated_global_app_block_type.md +65 -0
  16. data/docs/checks/missing_template.md +25 -0
  17. data/docs/checks/pagination_size.md +44 -0
  18. data/docs/checks/template_length.md +1 -1
  19. data/docs/checks/undefined_object.md +5 -0
  20. data/lib/theme_check/analyzer.rb +1 -0
  21. data/lib/theme_check/check.rb +3 -3
  22. data/lib/theme_check/checks/app_block_valid_tags.rb +36 -0
  23. data/lib/theme_check/checks/asset_size_css.rb +3 -3
  24. data/lib/theme_check/checks/asset_size_javascript.rb +2 -2
  25. data/lib/theme_check/checks/convert_include_to_render.rb +3 -1
  26. data/lib/theme_check/checks/default_locale.rb +3 -1
  27. data/lib/theme_check/checks/deprecate_bgsizes.rb +1 -1
  28. data/lib/theme_check/checks/deprecate_lazysizes.rb +7 -4
  29. data/lib/theme_check/checks/deprecated_global_app_block_type.rb +57 -0
  30. data/lib/theme_check/checks/img_lazy_loading.rb +1 -1
  31. data/lib/theme_check/checks/img_width_and_height.rb +3 -3
  32. data/lib/theme_check/checks/missing_template.rb +21 -5
  33. data/lib/theme_check/checks/pagination_size.rb +64 -0
  34. data/lib/theme_check/checks/parser_blocking_javascript.rb +1 -1
  35. data/lib/theme_check/checks/remote_asset.rb +3 -3
  36. data/lib/theme_check/checks/space_inside_braces.rb +27 -7
  37. data/lib/theme_check/checks/template_length.rb +1 -1
  38. data/lib/theme_check/checks/undefined_object.rb +1 -1
  39. data/lib/theme_check/checks/valid_html_translation.rb +1 -1
  40. data/lib/theme_check/checks.rb +11 -1
  41. data/lib/theme_check/cli.rb +18 -2
  42. data/lib/theme_check/corrector.rb +9 -0
  43. data/lib/theme_check/file_system_storage.rb +12 -0
  44. data/lib/theme_check/html_check.rb +0 -1
  45. data/lib/theme_check/html_node.rb +37 -16
  46. data/lib/theme_check/html_visitor.rb +17 -3
  47. data/lib/theme_check/json_check.rb +2 -2
  48. data/lib/theme_check/json_file.rb +11 -0
  49. data/lib/theme_check/json_printer.rb +27 -0
  50. data/lib/theme_check/language_server/constants.rb +18 -11
  51. data/lib/theme_check/language_server/document_link_engine.rb +3 -67
  52. data/lib/theme_check/language_server/document_link_provider.rb +71 -0
  53. data/lib/theme_check/language_server/document_link_providers/asset_document_link_provider.rb +11 -0
  54. data/lib/theme_check/language_server/document_link_providers/include_document_link_provider.rb +11 -0
  55. data/lib/theme_check/language_server/document_link_providers/render_document_link_provider.rb +11 -0
  56. data/lib/theme_check/language_server/document_link_providers/section_document_link_provider.rb +11 -0
  57. data/lib/theme_check/language_server/handler.rb +17 -9
  58. data/lib/theme_check/language_server/server.rb +9 -0
  59. data/lib/theme_check/language_server/uri_helper.rb +37 -0
  60. data/lib/theme_check/language_server.rb +6 -0
  61. data/lib/theme_check/node.rb +6 -4
  62. data/lib/theme_check/offense.rb +56 -3
  63. data/lib/theme_check/parsing_helpers.rb +4 -3
  64. data/lib/theme_check/position.rb +98 -14
  65. data/lib/theme_check/regex_helpers.rb +5 -2
  66. data/lib/theme_check/theme.rb +3 -0
  67. data/lib/theme_check/version.rb +1 -1
  68. data/lib/theme_check.rb +1 -0
  69. data/theme-check.gemspec +1 -1
  70. metadata +20 -6
  71. data/bin/liquid-server +0 -4
@@ -5,15 +5,16 @@ module ThemeCheck
5
5
  def outside_of_strings(markup)
6
6
  scanner = StringScanner.new(markup)
7
7
 
8
- while scanner.scan(/.*?("|')/)
9
- yield scanner.matched[0..-2]
8
+ while scanner.scan(/.*?("|')/m)
9
+ chunk_start = scanner.pre_match.size
10
+ yield scanner.matched[0..-2], chunk_start
10
11
  quote = scanner.matched[-1] == "'" ? "'" : "\""
11
12
  # Skip to the end of the string
12
13
  # Check for empty string first, since follow regexp uses lookahead
13
14
  scanner.skip(/#{quote}/) || scanner.skip_until(/[^\\]#{quote}/)
14
15
  end
15
16
 
16
- yield scanner.rest if scanner.rest?
17
+ yield scanner.rest, scanner.charpos if scanner.rest?
17
18
  end
18
19
  end
19
20
  end
@@ -4,42 +4,64 @@ module ThemeCheck
4
4
  class Position
5
5
  include PositionHelper
6
6
 
7
- def initialize(needle, contents, line_number_1_indexed)
8
- @needle = needle
9
- @contents = contents
7
+ def initialize(
8
+ needle_arg,
9
+ contents_arg,
10
+ line_number_1_indexed: nil,
11
+ node_markup: nil,
12
+ node_markup_offset: 0 # the index of markup inside the node_markup
13
+ )
14
+ @needle = needle_arg
15
+ @contents = contents_arg
10
16
  @line_number_1_indexed = line_number_1_indexed
11
- @start_row_column = nil
12
- @end_row_column = nil
17
+ @node_markup_offset = node_markup_offset
18
+ @node_markup = node_markup
19
+ @strict_position = StrictPosition.new(
20
+ needle,
21
+ contents,
22
+ start_index,
23
+ )
13
24
  end
14
25
 
15
- def start_line_index
26
+ def start_line_offset
16
27
  from_row_column_to_index(contents, line_number, 0)
17
28
  end
18
29
 
30
+ def start_offset
31
+ return start_line_offset if @node_markup.nil?
32
+ node_markup_start = contents.index(@node_markup, start_line_offset)
33
+ return start_line_offset if node_markup_start.nil?
34
+ node_markup_start + @node_markup_offset
35
+ end
36
+
19
37
  # 0-indexed, inclusive
20
38
  def start_index
21
- contents.index(needle, start_line_index) || start_line_index
39
+ contents.index(needle, start_offset)
22
40
  end
23
41
 
24
42
  # 0-indexed, exclusive
25
43
  def end_index
26
- start_index + needle.size
44
+ @strict_position.end_index
27
45
  end
28
46
 
47
+ # 0-indexed, inclusive
29
48
  def start_row
30
- start_row_column[0]
49
+ @strict_position.start_row
31
50
  end
32
51
 
52
+ # 0-indexed, inclusive
33
53
  def start_column
34
- start_row_column[1]
54
+ @strict_position.start_column
35
55
  end
36
56
 
57
+ # 0-indexed, exclusive (both taken together are) therefore you
58
+ # might end up on a newline character or the next line
37
59
  def end_row
38
- end_row_column[0]
60
+ @strict_position.end_row
39
61
  end
40
62
 
41
63
  def end_column
42
- end_row_column[1]
64
+ @strict_position.end_column
43
65
  end
44
66
 
45
67
  private
@@ -55,15 +77,77 @@ module ThemeCheck
55
77
  end
56
78
 
57
79
  def needle
58
- if @needle.nil? && !contents.empty? && !@line_number_1_indexed.nil?
59
- contents.lines(chomp: true)[line_number] || ''
80
+ if has_content_and_line_number_but_no_needle?
81
+ entire_line_needle
60
82
  elsif contents.empty? || @needle.nil?
61
83
  ''
84
+ elsif !can_find_needle?
85
+ entire_line_needle
62
86
  else
63
87
  @needle
64
88
  end
65
89
  end
66
90
 
91
+ def has_content_and_line_number_but_no_needle?
92
+ @needle.nil? && !contents.empty? && @line_number_1_indexed.is_a?(Integer)
93
+ end
94
+
95
+ def can_find_needle?
96
+ !!contents.index(@needle)
97
+ end
98
+
99
+ def entire_line_needle
100
+ contents.lines(chomp: true)[line_number] || ''
101
+ end
102
+ end
103
+
104
+ # This method is stricter than Position in the sense that it doesn't
105
+ # accept invalid inputs. Makes for code that is easier to understand.
106
+ class StrictPosition
107
+ include PositionHelper
108
+
109
+ attr_reader :needle, :contents
110
+
111
+ def initialize(needle, contents, start_index)
112
+ raise ArgumentError, 'Bad start_index' unless start_index.is_a?(Integer)
113
+ raise ArgumentError, 'Bad contents' unless contents.is_a?(String)
114
+ raise ArgumentError, 'Bad needle' unless needle.is_a?(String) || !contents.index(needle, start_index)
115
+
116
+ @needle = needle
117
+ @contents = contents
118
+ @start_index = start_index
119
+ @start_row_column = nil
120
+ @end_row_column = nil
121
+ end
122
+
123
+ # 0-indexed, inclusive
124
+ def start_index
125
+ @contents.index(needle, @start_index)
126
+ end
127
+
128
+ # 0-indexed, exclusive
129
+ def end_index
130
+ start_index + needle.size
131
+ end
132
+
133
+ def start_row
134
+ start_row_column[0]
135
+ end
136
+
137
+ def start_column
138
+ start_row_column[1]
139
+ end
140
+
141
+ def end_row
142
+ end_row_column[0]
143
+ end
144
+
145
+ def end_column
146
+ end_row_column[1]
147
+ end
148
+
149
+ private
150
+
67
151
  def start_row_column
68
152
  return @start_row_column unless @start_row_column.nil?
69
153
  @start_row_column = from_index_to_row_column(contents, start_index)
@@ -2,8 +2,11 @@
2
2
 
3
3
  module ThemeCheck
4
4
  module RegexHelpers
5
- VARIABLE = /#{Liquid::VariableStart}.*?#{Liquid::VariableEnd}/om
5
+ LIQUID_TAG = /#{Liquid::TagStart}.*?#{Liquid::TagEnd}/om
6
+ LIQUID_VARIABLE = /#{Liquid::VariableStart}.*?#{Liquid::VariableEnd}/om
7
+ LIQUID_TAG_OR_VARIABLE = /#{LIQUID_TAG}|#{LIQUID_VARIABLE}/om
6
8
  START_OR_END_QUOTE = /(^['"])|(['"]$)/
9
+
7
10
  def matches(s, re)
8
11
  start_at = 0
9
12
  matches = []
@@ -16,7 +19,7 @@ module ThemeCheck
16
19
 
17
20
  def href_to_file_size(href)
18
21
  # asset_url (+ optional stylesheet_tag) variables
19
- if href =~ /^#{VARIABLE}$/o && href =~ /asset_url/ && href =~ Liquid::QuotedString
22
+ if href =~ /^#{LIQUID_VARIABLE}$/o && href =~ /asset_url/ && href =~ Liquid::QuotedString
20
23
  asset_id = Regexp.last_match(0).gsub(START_OR_END_QUOTE, "")
21
24
  asset = @theme.assets.find { |a| a.name.end_with?("/" + asset_id) }
22
25
  return if asset.nil?
@@ -7,6 +7,9 @@ module ThemeCheck
7
7
  LIQUID_REGEX = /\.liquid$/i
8
8
  JSON_REGEX = /\.json$/i
9
9
 
10
+ attr_reader :storage
11
+ attr_writer :default_locale_json
12
+
10
13
  def initialize(storage)
11
14
  @storage = storage
12
15
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- VERSION = "1.1.0"
3
+ VERSION = "1.5.0"
4
4
  end
data/lib/theme_check.rb CHANGED
@@ -27,6 +27,7 @@ require_relative "theme_check/config"
27
27
  require_relative "theme_check/node"
28
28
  require_relative "theme_check/offense"
29
29
  require_relative "theme_check/printer"
30
+ require_relative "theme_check/json_printer"
30
31
  require_relative "theme_check/shopify_liquid"
31
32
  require_relative "theme_check/storage"
32
33
  require_relative "theme_check/string_helpers"
data/theme-check.gemspec CHANGED
@@ -25,5 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.require_paths = ["lib"]
26
26
 
27
27
  spec.add_dependency('liquid', '>= 5.0.1')
28
- spec.add_dependency('nokogumbo')
28
+ spec.add_dependency('nokogiri', '>= 1.12')
29
29
  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.1.0
4
+ version: 1.5.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-07-06 00:00:00.000000000 Z
11
+ date: 2021-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.0.1
27
27
  - !ruby/object:Gem::Dependency
28
- name: nokogumbo
28
+ name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.12'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.12'
41
41
  description:
42
42
  email:
43
43
  - marcandre.cournoyer@shopify.com
@@ -60,7 +60,8 @@ files:
60
60
  - README.md
61
61
  - RELEASING.md
62
62
  - Rakefile
63
- - bin/liquid-server
63
+ - bin/theme-check
64
+ - bin/theme-check-language-server
64
65
  - config/default.yml
65
66
  - config/nothing.yml
66
67
  - config/theme_app_extension.yml
@@ -76,6 +77,7 @@ files:
76
77
  - docs/api/json_check.md
77
78
  - docs/api/liquid_check.md
78
79
  - docs/checks/TEMPLATE.md.erb
80
+ - docs/checks/app_block_valid_tags.md
79
81
  - docs/checks/asset_size_app_block_css.md
80
82
  - docs/checks/asset_size_app_block_javascript.md
81
83
  - docs/checks/asset_size_css.md
@@ -88,6 +90,7 @@ files:
88
90
  - docs/checks/deprecate_bgsizes.md
89
91
  - docs/checks/deprecate_lazysizes.md
90
92
  - docs/checks/deprecated_filter.md
93
+ - docs/checks/deprecated_global_app_block_type.md
91
94
  - docs/checks/html_parsing_error.md
92
95
  - docs/checks/img_lazy_loading.md
93
96
  - docs/checks/img_width_and_height.md
@@ -98,6 +101,7 @@ files:
98
101
  - docs/checks/missing_required_template_files.md
99
102
  - docs/checks/missing_template.md
100
103
  - docs/checks/nested_snippet.md
104
+ - docs/checks/pagination_size.md
101
105
  - docs/checks/parser_blocking_javascript.md
102
106
  - docs/checks/parser_blocking_script_tag.md
103
107
  - docs/checks/remote_asset.md
@@ -124,6 +128,7 @@ files:
124
128
  - lib/theme_check/check.rb
125
129
  - lib/theme_check/checks.rb
126
130
  - lib/theme_check/checks/TEMPLATE.rb.erb
131
+ - lib/theme_check/checks/app_block_valid_tags.rb
127
132
  - lib/theme_check/checks/asset_size_app_block_css.rb
128
133
  - lib/theme_check/checks/asset_size_app_block_javascript.rb
129
134
  - lib/theme_check/checks/asset_size_css.rb
@@ -136,6 +141,7 @@ files:
136
141
  - lib/theme_check/checks/deprecate_bgsizes.rb
137
142
  - lib/theme_check/checks/deprecate_lazysizes.rb
138
143
  - lib/theme_check/checks/deprecated_filter.rb
144
+ - lib/theme_check/checks/deprecated_global_app_block_type.rb
139
145
  - lib/theme_check/checks/html_parsing_error.rb
140
146
  - lib/theme_check/checks/img_lazy_loading.rb
141
147
  - lib/theme_check/checks/img_width_and_height.rb
@@ -146,6 +152,7 @@ files:
146
152
  - lib/theme_check/checks/missing_required_template_files.rb
147
153
  - lib/theme_check/checks/missing_template.rb
148
154
  - lib/theme_check/checks/nested_snippet.rb
155
+ - lib/theme_check/checks/pagination_size.rb
149
156
  - lib/theme_check/checks/parser_blocking_javascript.rb
150
157
  - lib/theme_check/checks/parser_blocking_script_tag.rb
151
158
  - lib/theme_check/checks/remote_asset.rb
@@ -177,6 +184,7 @@ files:
177
184
  - lib/theme_check/json_check.rb
178
185
  - lib/theme_check/json_file.rb
179
186
  - lib/theme_check/json_helpers.rb
187
+ - lib/theme_check/json_printer.rb
180
188
  - lib/theme_check/language_server.rb
181
189
  - lib/theme_check/language_server/completion_engine.rb
182
190
  - lib/theme_check/language_server/completion_helper.rb
@@ -188,10 +196,16 @@ files:
188
196
  - lib/theme_check/language_server/constants.rb
189
197
  - lib/theme_check/language_server/diagnostics_tracker.rb
190
198
  - lib/theme_check/language_server/document_link_engine.rb
199
+ - lib/theme_check/language_server/document_link_provider.rb
200
+ - lib/theme_check/language_server/document_link_providers/asset_document_link_provider.rb
201
+ - lib/theme_check/language_server/document_link_providers/include_document_link_provider.rb
202
+ - lib/theme_check/language_server/document_link_providers/render_document_link_provider.rb
203
+ - lib/theme_check/language_server/document_link_providers/section_document_link_provider.rb
191
204
  - lib/theme_check/language_server/handler.rb
192
205
  - lib/theme_check/language_server/protocol.rb
193
206
  - lib/theme_check/language_server/server.rb
194
207
  - lib/theme_check/language_server/tokens.rb
208
+ - lib/theme_check/language_server/uri_helper.rb
195
209
  - lib/theme_check/language_server/variable_lookup_finder.rb
196
210
  - lib/theme_check/liquid_check.rb
197
211
  - lib/theme_check/locale_diff.rb
data/bin/liquid-server DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env bash
2
- dev="/opt/dev/bin/dev"
3
- cd "$($dev project-path theme-check)"
4
- "$dev" language-server