theme-check 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/theme-check.yml +11 -3
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +29 -0
  5. data/Gemfile +5 -5
  6. data/LICENSE.md +2 -0
  7. data/README.md +1 -0
  8. data/RELEASING.md +10 -3
  9. data/Rakefile +6 -0
  10. data/config/default.yml +3 -0
  11. data/dev.yml +1 -1
  12. data/docs/checks/remote_asset.md +82 -0
  13. data/exe/theme-check +1 -1
  14. data/lib/theme_check.rb +1 -0
  15. data/lib/theme_check/check.rb +1 -1
  16. data/lib/theme_check/checks/asset_size_css.rb +1 -1
  17. data/lib/theme_check/checks/asset_size_javascript.rb +1 -1
  18. data/lib/theme_check/checks/img_width_and_height.rb +2 -2
  19. data/lib/theme_check/checks/matching_translations.rb +1 -1
  20. data/lib/theme_check/checks/parser_blocking_javascript.rb +1 -1
  21. data/lib/theme_check/checks/remote_asset.rb +99 -0
  22. data/lib/theme_check/checks/translation_key_exists.rb +1 -4
  23. data/lib/theme_check/checks/undefined_object.rb +1 -1
  24. data/lib/theme_check/checks/valid_html_translation.rb +1 -1
  25. data/lib/theme_check/cli.rb +101 -57
  26. data/lib/theme_check/config.rb +6 -2
  27. data/lib/theme_check/disabled_checks.rb +2 -2
  28. data/lib/theme_check/in_memory_storage.rb +13 -16
  29. data/lib/theme_check/language_server/completion_engine.rb +2 -2
  30. data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +1 -1
  31. data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +1 -1
  32. data/lib/theme_check/language_server/completion_providers/render_snippet_completion_provider.rb +1 -1
  33. data/lib/theme_check/language_server/completion_providers/tag_completion_provider.rb +2 -2
  34. data/lib/theme_check/language_server/constants.rb +2 -2
  35. data/lib/theme_check/language_server/document_link_engine.rb +4 -3
  36. data/lib/theme_check/language_server/handler.rb +29 -21
  37. data/lib/theme_check/language_server/server.rb +1 -2
  38. data/lib/theme_check/node.rb +1 -2
  39. data/lib/theme_check/offense.rb +3 -1
  40. data/lib/theme_check/packager.rb +1 -1
  41. data/lib/theme_check/parsing_helpers.rb +1 -1
  42. data/lib/theme_check/releaser.rb +39 -0
  43. data/lib/theme_check/shopify_liquid/deprecated_filter.rb +6 -8
  44. data/lib/theme_check/shopify_liquid/filter.rb +3 -5
  45. data/lib/theme_check/shopify_liquid/object.rb +2 -6
  46. data/lib/theme_check/shopify_liquid/tag.rb +1 -3
  47. data/lib/theme_check/storage.rb +3 -3
  48. data/lib/theme_check/string_helpers.rb +47 -0
  49. data/lib/theme_check/tags.rb +1 -2
  50. data/lib/theme_check/theme.rb +1 -1
  51. data/lib/theme_check/version.rb +1 -1
  52. data/packaging/homebrew/theme_check.base.rb +1 -1
  53. data/theme-check.gemspec +3 -2
  54. metadata +9 -19
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'json'
3
3
  require 'stringio'
4
- require 'active_support/core_ext/string/inflections'
5
4
 
6
5
  module ThemeCheck
7
6
  module LanguageServer
@@ -99,7 +98,7 @@ module ThemeCheck
99
98
  end
100
99
 
101
100
  def to_snake_case(method_name)
102
- method_name.gsub(/[^\w]/, '_').underscore
101
+ StringHelpers.underscore(method_name.gsub(/[^\w]/, '_'))
103
102
  end
104
103
 
105
104
  def initial_line
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'active_support/core_ext/string/inflections'
3
2
 
4
3
  module ThemeCheck
5
4
  # A node from the Liquid AST, the result of parsing a template.
@@ -101,7 +100,7 @@ module ThemeCheck
101
100
  # The `:under_score_name` of this type of node. Used to dispatch to the `on_<type_name>`
102
101
  # and `after_<type_name>` check methods.
103
102
  def type_name
104
- @type_name ||= @value.class.name.demodulize.underscore.to_sym
103
+ @type_name ||= StringHelpers.underscore(StringHelpers.demodulize(@value.class.name)).to_sym
105
104
  end
106
105
 
107
106
  # Is this node inside a `{% liquid ... %}` block?
@@ -32,6 +32,8 @@ module ThemeCheck
32
32
  node&.markup
33
33
  end
34
34
 
35
+ raise ArgumentError, "Offense markup cannot be an empty string" if @markup.is_a?(String) && @markup.empty?
36
+
35
37
  @line_number = if line_number
36
38
  line_number
37
39
  elsif @node
@@ -83,7 +85,7 @@ module ThemeCheck
83
85
  end
84
86
 
85
87
  def check_name
86
- check.class.name.demodulize
88
+ StringHelpers.demodulize(check.class.name)
87
89
  end
88
90
 
89
91
  def doc
@@ -24,7 +24,7 @@ module ThemeCheck
24
24
  puts "Grabbing sha256 checksum from Rubygems.org"
25
25
  require 'digest/sha2'
26
26
  require 'open-uri'
27
- gem_checksum = open("https://rubygems.org/downloads/theme-check-#{ThemeCheck::VERSION}.gem") do |io|
27
+ gem_checksum = URI.open("https://rubygems.org/downloads/theme-check-#{ThemeCheck::VERSION}.gem") do |io|
28
28
  Digest::SHA256.new.hexdigest(io.read)
29
29
  end
30
30
 
@@ -6,7 +6,7 @@ module ThemeCheck
6
6
  scanner = StringScanner.new(markup)
7
7
 
8
8
  while scanner.scan(/.*?("|')/)
9
- yield scanner.matched[..-2]
9
+ yield scanner.matched[0..-2]
10
10
  # Skip to the end of the string
11
11
  scanner.skip_until(scanner.matched[-1] == "'" ? /[^\\]'/ : /[^\\]"/)
12
12
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+ require 'theme_check/version'
3
+
4
+ module ThemeCheck
5
+ class Releaser
6
+ ROOT = File.expand_path('../../..', __FILE__)
7
+ LIB = File.join(ROOT, 'lib')
8
+
9
+ class VersionError < StandardError; end
10
+
11
+ def release(version)
12
+ raise VersionError, "Missing version argument." if version.nil?
13
+ raise VersionError, "Version should be a string." unless version.is_a?(String)
14
+ raise VersionError, "Version should be a valid semver version." unless version =~ /^\d+\.\d+.\d+$/
15
+ update_docs(version)
16
+ update_version(version)
17
+ end
18
+
19
+ def update_version(version)
20
+ version_file_path = File.join(LIB, 'theme_check/version.rb')
21
+ version_file = File.read(version_file_path)
22
+ updated_version_file = version_file.gsub(ThemeCheck::VERSION, version)
23
+
24
+ return if updated_version_file == version_file
25
+ puts "Updating version to #{version} in #{version_file_path}."
26
+ File.write(version_file_path, updated_version_file)
27
+ end
28
+
29
+ def update_docs(version)
30
+ Dir[ROOT + '/docs/checks/*.md'].each do |filename|
31
+ doc_content = File.read(filename)
32
+ updated_doc_content = doc_content.gsub('THEME_CHECK_VERSION', version)
33
+ next if updated_doc_content == doc_content
34
+ puts "Replacing `THEME_CHECK_VERSION` with #{version} in #{Pathname.new(filename).relative_path_from(ROOT)}"
35
+ File.write(filename, updated_doc_content)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -17,14 +17,12 @@ module ThemeCheck
17
17
  private
18
18
 
19
19
  def all
20
- @all ||= begin
21
- YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/deprecated_filters.yml"))
22
- .values
23
- .each_with_object({}) do |filters, acc|
24
- filters.each do |(filter, alternatives)|
25
- acc[filter] = alternatives
26
- end
27
- end
20
+ @all ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/deprecated_filters.yml"))
21
+ .values
22
+ .each_with_object({}) do |filters, acc|
23
+ filters.each do |(filter, alternatives)|
24
+ acc[filter] = alternatives
25
+ end
28
26
  end
29
27
  end
30
28
  end
@@ -7,11 +7,9 @@ module ThemeCheck
7
7
  extend self
8
8
 
9
9
  def labels
10
- @labels ||= begin
11
- YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/filters.yml"))
12
- .values
13
- .flatten
14
- end
10
+ @labels ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/filters.yml"))
11
+ .values
12
+ .flatten
15
13
  end
16
14
  end
17
15
  end
@@ -7,15 +7,11 @@ module ThemeCheck
7
7
  extend self
8
8
 
9
9
  def labels
10
- @labels ||= begin
11
- YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/objects.yml"))
12
- end
10
+ @labels ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/objects.yml"))
13
11
  end
14
12
 
15
13
  def plus_labels
16
- @plus_labels ||= begin
17
- YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/plus_objects.yml"))
18
- end
14
+ @plus_labels ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/plus_objects.yml"))
19
15
  end
20
16
  end
21
17
  end
@@ -7,9 +7,7 @@ module ThemeCheck
7
7
  extend self
8
8
 
9
9
  def labels
10
- @tags ||= begin
11
- YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/tags.yml"))
12
- end
10
+ @tags ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/tags.yml"))
13
11
  end
14
12
  end
15
13
  end
@@ -2,15 +2,15 @@
2
2
 
3
3
  module ThemeCheck
4
4
  class Storage
5
- def read(relative_path)
5
+ def path(relative_path)
6
6
  raise NotImplementedError
7
7
  end
8
8
 
9
- def write(relative_path, content)
9
+ def read(relative_path)
10
10
  raise NotImplementedError
11
11
  end
12
12
 
13
- def path(relative_path)
13
+ def write(relative_path, content)
14
14
  raise NotImplementedError
15
15
  end
16
16
 
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ module StringHelpers
5
+ extend self
6
+
7
+ # Removes the module part from the expression in the string.
8
+ # Ported from ActiveSupport
9
+ #
10
+ # demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections"
11
+ # demodulize('Inflections') # => "Inflections"
12
+ # demodulize('::Inflections') # => "Inflections"
13
+ # demodulize('') # => ""
14
+ #
15
+ # See also #deconstantize.
16
+ def demodulize(path)
17
+ path = path.to_s
18
+ if (i = path.rindex("::"))
19
+ path[(i + 2)..-1]
20
+ else
21
+ path
22
+ end
23
+ end
24
+
25
+ # Makes an underscored, lowercase form from the expression in the string.
26
+ # Base on ActiveSupport's
27
+ #
28
+ # Changes '::' to '/' to convert namespaces to paths.
29
+ #
30
+ # underscore('ActiveModel') # => "active_model"
31
+ # underscore('ActiveModel::Errors') # => "active_model/errors"
32
+ #
33
+ # As a rule of thumb you can think of +underscore+ as the inverse of
34
+ # #camelize, though there are cases where that does not hold:
35
+ #
36
+ # camelize(underscore('SSLError')) # => "SslError"
37
+ def underscore(camel_cased_word)
38
+ return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
39
+ word = camel_cased_word.to_s.gsub("::", "/")
40
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
41
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
42
+ word.tr!("-", "_")
43
+ word.downcase!
44
+ word
45
+ end
46
+ end
47
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require "active_support/core_ext/string/starts_ends_with"
3
2
 
4
3
  module ThemeCheck
5
4
  module Tags
@@ -19,7 +18,7 @@ module ThemeCheck
19
18
  "Error in tag 'section' - Valid syntax: section '[type]'",
20
19
  ) unless match
21
20
  @section_name = match[:section_name].tr(%('"), '')
22
- @section_name.chomp!(".liquid") if @section_name.ends_with?(".liquid")
21
+ @section_name.chomp!(".liquid") if @section_name.end_with?(".liquid")
23
22
  end
24
23
  end
25
24
 
@@ -13,7 +13,7 @@ module ThemeCheck
13
13
 
14
14
  def assets
15
15
  @assets ||= @storage.files
16
- .select { |path| path.starts_with?("assets/") }
16
+ .select { |path| path.start_with?("assets/") }
17
17
  .map { |path| AssetFile.new(path, @storage) }
18
18
  end
19
19
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- VERSION = "0.6.0"
3
+ VERSION = "0.8.0"
4
4
  end
@@ -13,7 +13,7 @@ class ThemeCheck < Formula
13
13
  class RubyGemsDownloadStrategy < AbstractDownloadStrategy
14
14
  include RubyBin
15
15
 
16
- def fetch
16
+ def fetch(_timeout: nil, **_options)
17
17
  ohai("Fetching theme-check from gem source")
18
18
  cache.cd do
19
19
  ENV['GEM_SPEC_CACHE'] = "#{cache}/gem_spec_cache"
data/theme-check.gemspec CHANGED
@@ -13,6 +13,8 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "https://github.com/Shopify/theme-check"
14
14
  spec.license = "MIT"
15
15
 
16
+ spec.required_ruby_version = ">= 2.6"
17
+
16
18
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
17
19
 
18
20
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
@@ -22,7 +24,6 @@ Gem::Specification.new do |spec|
22
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
25
  spec.require_paths = ["lib"]
24
26
 
25
- spec.add_dependency('liquid', '>= 5')
26
- spec.add_dependency('activesupport')
27
+ spec.add_dependency('liquid', '>= 5.0.1')
27
28
  spec.add_dependency('nokogumbo')
28
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: 0.6.0
4
+ version: 0.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-03-23 00:00:00.000000000 Z
11
+ date: 2021-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -16,28 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5'
19
+ version: 5.0.1
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'
27
- - !ruby/object:Gem::Dependency
28
- name: activesupport
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
26
+ version: 5.0.1
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: nokogumbo
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -98,6 +84,7 @@ files:
98
84
  - docs/checks/missing_template.md
99
85
  - docs/checks/nested_snippet.md
100
86
  - docs/checks/parser_blocking_javascript.md
87
+ - docs/checks/remote_asset.md
101
88
  - docs/checks/required_directories.md
102
89
  - docs/checks/required_layout_theme_object.md
103
90
  - docs/checks/space_inside_braces.md
@@ -133,6 +120,7 @@ files:
133
120
  - lib/theme_check/checks/missing_template.rb
134
121
  - lib/theme_check/checks/nested_snippet.rb
135
122
  - lib/theme_check/checks/parser_blocking_javascript.rb
123
+ - lib/theme_check/checks/remote_asset.rb
136
124
  - lib/theme_check/checks/required_directories.rb
137
125
  - lib/theme_check/checks/required_layout_theme_object.rb
138
126
  - lib/theme_check/checks/space_inside_braces.rb
@@ -179,6 +167,7 @@ files:
179
167
  - lib/theme_check/parsing_helpers.rb
180
168
  - lib/theme_check/printer.rb
181
169
  - lib/theme_check/regex_helpers.rb
170
+ - lib/theme_check/releaser.rb
182
171
  - lib/theme_check/remote_asset_file.rb
183
172
  - lib/theme_check/shopify_liquid.rb
184
173
  - lib/theme_check/shopify_liquid/deprecated_filter.rb
@@ -186,6 +175,7 @@ files:
186
175
  - lib/theme_check/shopify_liquid/object.rb
187
176
  - lib/theme_check/shopify_liquid/tag.rb
188
177
  - lib/theme_check/storage.rb
178
+ - lib/theme_check/string_helpers.rb
189
179
  - lib/theme_check/tags.rb
190
180
  - lib/theme_check/template.rb
191
181
  - lib/theme_check/theme.rb
@@ -206,7 +196,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
206
196
  requirements:
207
197
  - - ">="
208
198
  - !ruby/object:Gem::Version
209
- version: '0'
199
+ version: '2.6'
210
200
  required_rubygems_version: !ruby/object:Gem::Requirement
211
201
  requirements:
212
202
  - - ">="