theme-check 0.1.2 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +1 -0
  4. data/CHANGELOG.md +27 -0
  5. data/CONTRIBUTING.md +2 -0
  6. data/README.md +62 -1
  7. data/RELEASING.md +41 -0
  8. data/Rakefile +38 -4
  9. data/config/default.yml +20 -1
  10. data/data/shopify_liquid/deprecated_filters.yml +10 -0
  11. data/data/shopify_liquid/plus_objects.yml +15 -0
  12. data/dev.yml +2 -0
  13. data/lib/theme_check.rb +6 -0
  14. data/lib/theme_check/analyzer.rb +15 -5
  15. data/lib/theme_check/check.rb +11 -0
  16. data/lib/theme_check/checks.rb +10 -0
  17. data/lib/theme_check/checks/deprecated_filter.rb +22 -0
  18. data/lib/theme_check/checks/missing_enable_comment.rb +31 -0
  19. data/lib/theme_check/checks/parser_blocking_javascript.rb +55 -0
  20. data/lib/theme_check/checks/space_inside_braces.rb +19 -7
  21. data/lib/theme_check/checks/template_length.rb +11 -3
  22. data/lib/theme_check/checks/undefined_object.rb +119 -36
  23. data/lib/theme_check/checks/valid_html_translation.rb +2 -2
  24. data/lib/theme_check/cli.rb +18 -4
  25. data/lib/theme_check/config.rb +97 -44
  26. data/lib/theme_check/corrector.rb +31 -0
  27. data/lib/theme_check/disabled_checks.rb +77 -0
  28. data/lib/theme_check/file_system_storage.rb +51 -0
  29. data/lib/theme_check/in_memory_storage.rb +37 -0
  30. data/lib/theme_check/json_file.rb +12 -10
  31. data/lib/theme_check/language_server/handler.rb +38 -13
  32. data/lib/theme_check/language_server/server.rb +2 -2
  33. data/lib/theme_check/liquid_check.rb +2 -2
  34. data/lib/theme_check/node.rb +13 -0
  35. data/lib/theme_check/offense.rb +25 -9
  36. data/lib/theme_check/packager.rb +51 -0
  37. data/lib/theme_check/printer.rb +13 -4
  38. data/lib/theme_check/shopify_liquid.rb +1 -0
  39. data/lib/theme_check/shopify_liquid/deprecated_filter.rb +28 -0
  40. data/lib/theme_check/shopify_liquid/object.rb +6 -0
  41. data/lib/theme_check/storage.rb +25 -0
  42. data/lib/theme_check/template.rb +32 -10
  43. data/lib/theme_check/theme.rb +14 -9
  44. data/lib/theme_check/version.rb +1 -1
  45. data/lib/theme_check/visitor.rb +14 -3
  46. data/packaging/homebrew/theme_check.base.rb +98 -0
  47. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e51f58be8347c6d602ef2f5f6385117f1c8ad5d07a66c111c8c8bf623008f3b1
4
- data.tar.gz: 88eb1fbc392ff70251255f5aa681e6e7bf37fbc1c0a65bc1651e291c13baf5d9
3
+ metadata.gz: 31af33605da4e88e134907242224b4266afc76fede068c70a1ba6b8d84eb98cd
4
+ data.tar.gz: 80c7427113fd20c02c02d87d8f598d49182d460a8691e06dbaa954872c4f83c2
5
5
  SHA512:
6
- metadata.gz: 0c7865cb5cb44da5811b78429d34c3309264ba21f55954a83b97784e15375798794461c0d19edfe620e8cbed45b6b8a80d63755b258505acb4c2b61bbae77e4a
7
- data.tar.gz: 625963de20e85bc5b27989fba14a9a8243aafffc21aba5f4ea54b8e937fba05f73df99549a6b6b575dd29b7df48319c054aa2089e98c31e1e8212b1521c73c04
6
+ metadata.gz: 486f6280ef9521a7d35a8c4dce9e146b652514cb16def7b70845e2b93993710f2b61bd22dd448954ab1e44adc62b10c84b8e93ac3895dd92c4c1c42911341c83
7
+ data.tar.gz: '0171786d1c8bea48ba90a755cda22aea62da383b740b2cccc402dba210cc6d361a86704fe43617be2e489747bbb67a6614e4ab975d5fe2128e2f89da724a8ca3'
data/.gitignore CHANGED
@@ -11,3 +11,4 @@
11
11
  Gemfile.lock
12
12
 
13
13
  .rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml
14
+ packaging/builds
data/.rubocop.yml CHANGED
@@ -7,6 +7,7 @@ AllCops:
7
7
  TargetRubyVersion: 2.7
8
8
  Exclude:
9
9
  - 'vendor/bundle/**/*'
10
+ - 'packaging/builds/**/*'
10
11
 
11
12
  Metrics/MethodLength:
12
13
  Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+
2
+ v0.3.2 / 2021-02-17
3
+ ==================
4
+
5
+ * Ignore snippets in UndefinedObject check
6
+
7
+ v0.3.1 / 2021-02-16
8
+ ===================
9
+
10
+ * Fixup version flag
11
+
12
+ v0.3.0 / 2021-02-16
13
+ ===================
14
+
15
+ * Add ParserBlockingJavaScript Check ([#78](https://github.com/Shopify/theme-check/issues/78), [#146](https://github.com/Shopify/theme-check/issues/146))
16
+ * Internal refactor to enable running theme-check in servers ([#145](https://github.com/Shopify/theme-check/issues/145), [#148](https://github.com/Shopify/theme-check/issues/148))
17
+ * Add -v, --version flag ([#126](https://github.com/Shopify/theme-check/issues/126))
18
+ * Exclude content of {% schema %} in line count for TemplateLength ([#140](https://github.com/Shopify/theme-check/issues/140))
19
+ * Fix Language Server removed files bug ([#136](https://github.com/Shopify/theme-check/issues/136))
20
+ * Add ignore config ([#147](https://github.com/Shopify/theme-check/issues/147))
21
+ * Add ability to disable checks with comments ([#79](https://github.com/Shopify/theme-check/issues/79))
22
+ * Adding checks for shopify plus objects in checkout ([#121](https://github.com/Shopify/theme-check/issues/121))
23
+
24
+ v0.2.2 / 2021-01-22
25
+ ===================
26
+
27
+ * [Language Server] Send empty dianogstics to flush errors
data/CONTRIBUTING.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  We love receiving pull requests!
4
4
 
5
+ For your contribution to be accepted you will need to sign the [Shopify Contributor License Agreement (CLA)](https://cla.shopify.com/).
6
+
5
7
  ## Standards
6
8
 
7
9
  * Checks should do one thing, and do it well.
data/README.md CHANGED
@@ -30,13 +30,32 @@ Theme Check currently checks for the following:
30
30
  ✅ Unmatching translation keys in locale files
31
31
  ✅ Using unknown translation keys in `{{ 'missing_key' | t }}`
32
32
  ✅ Using several `{% ... %}` instead of `{% liquid ... %}`
33
- ✅ Undefined [objects](https://shopify.dev/docs/themes/liquid/reference/objects)
33
+ ✅ Undefined [objects](https://shopify.dev/docs/themes/liquid/reference/objects)
34
+ ✅ Deprecated filters
35
+ ✅ Missing `theme-check-enable` comment
34
36
 
35
37
  And many more to come! Suggestions welcome ([create an issue](https://github.com/Shopify/theme-check/issues)).
36
38
 
39
+ ## Requirements
40
+
41
+ - Ruby 2.7+
42
+
37
43
  ## Installation
38
44
 
45
+ Theme Check is available through Homebrew _or_ RubyGems.
46
+
47
+ **Homebrew**
48
+
49
+ You’ll need to run `brew tap` first to add Shopify’s third-party repositories to Homebrew.
50
+
51
+ ```sh
52
+ brew tap shopify/shopify
53
+ brew install theme-check
39
54
  ```
55
+
56
+ **RubyGems**
57
+
58
+ ```sh
40
59
  gem install theme-check
41
60
  ```
42
61
 
@@ -61,11 +80,53 @@ Add a `.theme-check.yml` file at the root of your theme to configure:
61
80
  # be uploaded to Shopify.
62
81
  root: dist
63
82
 
83
+ # It is possible to extend theme-check with custom checks
84
+ require:
85
+ - ./path/to/my_custom_check.rb
86
+
64
87
  # Disable some checks
65
88
  TemplateLength:
66
89
  enabled: false
67
90
  # Or configure options
68
91
  max_length: 300
92
+
93
+ # Enable a custom check
94
+ MyCustomCheck
95
+ enabled: true
69
96
  ```
70
97
 
71
98
  See [config/default.yml](config/default.yml) for available options & defaults.
99
+
100
+ ## Disable checks with comments
101
+
102
+ Use Liquid comments to disable and re-enable all checks for a section of your template:
103
+
104
+ ```liquid
105
+ {% comment %}theme-check-disable{% endcomment %}
106
+ {% assign x = 1 %}
107
+ {% comment %}theme-check-enable{% endcomment %}
108
+ ```
109
+
110
+ Disable a specific check by including it in the comment:
111
+
112
+ ```liquid
113
+ {% comment %}theme-check-disable UnusedAssign{% endcomment %}
114
+ {% assign x = 1 %}
115
+ {% comment %}theme-check-enable UnusedAssign{% endcomment %}
116
+ ```
117
+
118
+ Disable multiple checks by including them as a comma-separated list:
119
+
120
+ ```liquid
121
+ {% comment %}theme-check-disable UnusedAssign,SpaceInsideBraces{% endcomment %}
122
+ {%assign x = 1%}
123
+ {% comment %}theme-check-enable UnusedAssign,SpaceInsideBraces{% endcomment %}
124
+ ```
125
+
126
+ Disable checks for the _entire document_ by placing the comment on the first line:
127
+
128
+ ```liquid
129
+ {% comment %}theme-check-disable SpaceInsideBraces{% endcomment %}
130
+
131
+ {%assign x = 1%}
132
+ ```
data/RELEASING.md ADDED
@@ -0,0 +1,41 @@
1
+ ## Releasing Theme Check
2
+
3
+ 1. Check the Semantic Versioning page for info on how to version the new release: http://semver.org
4
+
5
+ 2. Create a PR to update the version in `lib/theme_check/version.rb`
6
+
7
+ 3. Merge your PR to master
8
+
9
+ 4. On [Shipit](https://shipit.shopify.io/shopify/theme-check/rubygems), deploy your commit.
10
+
11
+ ## Homebrew Release Process
12
+
13
+ 1. Release `theme-check` on RubyGems by following the steps in the previous section.
14
+
15
+ 2. Generate the homebrew formula.
16
+
17
+ ```bash
18
+ rake package
19
+ ```
20
+
21
+ 3. Copy the formula over in the [`homebrew-shopify`](https://github.com/Shopify/homebrew-shopify) repository.
22
+
23
+ ```bash
24
+ VERSION=X.X.X
25
+ cp packaging/builds/$VERSION/theme-check.rb ../homebrew-shopify
26
+ ```
27
+
28
+ 4. Create a branch + a commit on the [`homebrew-shopify`](https://github.com/Shopify/homebrew-shopify) repository.
29
+
30
+ ```bash
31
+ git checkout -b "bump/theme-check-$VERSION"
32
+ git add theme-check.rb
33
+ git commit -m "Bump theme-check version to $VERSION"
34
+ ```
35
+
36
+ 5. Create a pull-request for those changes on the [`homebrew-shopify`](https://github.com/Shopify/homebrew-shopify) repository.
37
+
38
+ ```bash
39
+ # shortcut if you have `hub` installed
40
+ hub compare "master:bump/theme-check-$VERSION"
41
+ ```
data/Rakefile CHANGED
@@ -3,12 +3,46 @@ require "rake/testtask"
3
3
  require "rubocop/rake_task"
4
4
  require "bundler/gem_tasks"
5
5
 
6
- Rake::TestTask.new(:test) do |t|
7
- t.libs << "test"
8
- t.libs << "lib"
9
- t.test_files = FileList["test/**/*_test.rb"]
6
+ namespace :tests do
7
+ task all: [:in_memory, :file_system]
8
+
9
+ Rake::TestTask.new(:suite) do |t|
10
+ t.libs << "test"
11
+ t.libs << "lib"
12
+ t.test_files = FileList["test/**/*_test.rb"]
13
+ end
14
+
15
+ desc("Runs the tests with InMemoryStorage")
16
+ task :in_memory do
17
+ ENV["THEME_STORAGE"] = 'InMemoryStorage'
18
+ puts "Running tests with #{ENV['THEME_STORAGE']}"
19
+ Rake::Task['tests:suite'].execute
20
+ end
21
+
22
+ desc("Runs the tests with FileSystemStorage")
23
+ task :file_system do
24
+ ENV["THEME_STORAGE"] = 'FileSystemStorage'
25
+ puts "Running tests with #{ENV['THEME_STORAGE']}"
26
+ Rake::Task['tests:suite'].execute
27
+ end
10
28
  end
11
29
 
30
+ task(test: 'tests:all')
31
+
12
32
  RuboCop::RakeTask.new
13
33
 
14
34
  task default: [:test, :rubocop]
35
+
36
+ namespace :package do
37
+ require 'theme_check/packager'
38
+
39
+ task all: [:homebrew]
40
+
41
+ desc("Builds a Homebrew package of the CLI")
42
+ task :homebrew do
43
+ ThemeCheck::Packager.new.build_homebrew
44
+ end
45
+ end
46
+
47
+ desc("Builds all distribution packages of the CLI")
48
+ task(package: 'package:all')
data/config/default.yml CHANGED
@@ -1,3 +1,10 @@
1
+ root: .
2
+
3
+ require: []
4
+
5
+ ignore:
6
+ - node_modules/*
7
+
1
8
  ConvertIncludeToRender:
2
9
  enabled: true
3
10
 
@@ -22,6 +29,8 @@ SyntaxError:
22
29
  TemplateLength:
23
30
  enabled: true
24
31
  max_length: 200
32
+ # Exclude content of {% schema %} in line count
33
+ exclude_schema: true
25
34
 
26
35
  UnknownFilter:
27
36
  enabled: true
@@ -57,7 +66,17 @@ MissingRequiredTemplateFiles:
57
66
  enabled: true
58
67
 
59
68
  UndefinedObject:
60
- enabled: false
69
+ enabled: true
70
+ exclude_snippets: true
61
71
 
62
72
  RequiredDirectories:
63
73
  enabled: true
74
+
75
+ DeprecatedFilter:
76
+ enabled: true
77
+
78
+ MissingEnableComment:
79
+ enabled: true
80
+
81
+ ParserBlockingJavaScript:
82
+ enabled: true
@@ -0,0 +1,10 @@
1
+ ---
2
+ Liquid::ColorFilter:
3
+ hex_to_rgba:
4
+ - color_to_rgb
5
+ - color_modify
6
+ Liquid::UrlFilter:
7
+ collection_img_url:
8
+ - img_url
9
+ product_img_url:
10
+ - img_url
@@ -0,0 +1,15 @@
1
+ ---
2
+ - alternative_payment_methods
3
+ - breadcrumb
4
+ - checkout_html_classes
5
+ - checkout_scripts
6
+ - checkout_stylesheets
7
+ - content_for_footer
8
+ - content_for_logo
9
+ - content_for_order_summary
10
+ - direction
11
+ - locale
12
+ - order_summary_toggle
13
+ - page_title
14
+ - skip_to_content_link
15
+ - tracking_code
data/dev.yml CHANGED
@@ -19,5 +19,7 @@ commands:
19
19
  run: bundle exec rake test
20
20
  style:
21
21
  run: bundle exec rake rubocop
22
+ autocorrect:
23
+ run: bundle exec rubocop --auto-correct
22
24
  language-server:
23
25
  run: bundle exec theme-check-language-server
data/lib/theme_check.rb CHANGED
@@ -5,6 +5,7 @@ require_relative "theme_check/analyzer"
5
5
  require_relative "theme_check/check"
6
6
  require_relative "theme_check/checks_tracking"
7
7
  require_relative "theme_check/cli"
8
+ require_relative "theme_check/disabled_checks"
8
9
  require_relative "theme_check/liquid_check"
9
10
  require_relative "theme_check/locale_diff"
10
11
  require_relative "theme_check/json_check"
@@ -17,9 +18,14 @@ require_relative "theme_check/node"
17
18
  require_relative "theme_check/offense"
18
19
  require_relative "theme_check/printer"
19
20
  require_relative "theme_check/shopify_liquid"
21
+ require_relative "theme_check/storage"
22
+ require_relative "theme_check/file_system_storage"
23
+ require_relative "theme_check/in_memory_storage"
20
24
  require_relative "theme_check/tags"
21
25
  require_relative "theme_check/template"
22
26
  require_relative "theme_check/theme"
23
27
  require_relative "theme_check/visitor"
28
+ require_relative "theme_check/corrector"
29
+ require_relative "theme_check/version"
24
30
 
25
31
  Dir[__dir__ + "/theme_check/checks/*.rb"].each { |file| require file }
@@ -3,9 +3,10 @@ module ThemeCheck
3
3
  class Analyzer
4
4
  attr_reader :offenses
5
5
 
6
- def initialize(theme, checks = Check.all.map(&:new))
6
+ def initialize(theme, checks = Check.all.map(&:new), auto_correct = false)
7
7
  @theme = theme
8
8
  @offenses = []
9
+ @auto_correct = auto_correct
9
10
 
10
11
  @liquid_checks = Checks.new
11
12
  @json_checks = Checks.new
@@ -34,10 +35,19 @@ module ThemeCheck
34
35
  @offenses
35
36
  end
36
37
 
37
- def analyze_file(path)
38
- path = Pathname.new(path)
39
- analyze_theme
40
- @offenses.reject! { |offense| offense.template.path != path }
38
+ def uncorrectable_offenses
39
+ unless @auto_correct
40
+ return @offenses
41
+ end
42
+
43
+ @offenses.select { |offense| !offense.correctable? }
44
+ end
45
+
46
+ def correct_offenses
47
+ if @auto_correct
48
+ @offenses.each(&:correct)
49
+ @theme.liquid.each(&:write)
50
+ end
41
51
  end
42
52
  end
43
53
  end
@@ -50,6 +50,13 @@ module ThemeCheck
50
50
  @doc = doc if doc
51
51
  @doc if defined?(@doc)
52
52
  end
53
+
54
+ def can_disable(disableable = nil)
55
+ unless disableable.nil?
56
+ @can_disable = disableable
57
+ end
58
+ defined?(@can_disable) ? @can_disable : true
59
+ end
53
60
  end
54
61
 
55
62
  def severity
@@ -80,6 +87,10 @@ module ThemeCheck
80
87
  defined?(@ignored) && @ignored
81
88
  end
82
89
 
90
+ def can_disable?
91
+ self.class.can_disable
92
+ end
93
+
83
94
  def to_s
84
95
  s = +"#{code_name}:\n"
85
96
  properties = { severity: severity, category: category, doc: doc }.merge(options)
@@ -8,5 +8,15 @@ module ThemeCheck
8
8
  end
9
9
  end
10
10
  end
11
+
12
+ def always_enabled
13
+ self.class.new(reject(&:can_disable?))
14
+ end
15
+
16
+ def except_for(disabled_checks)
17
+ still_enabled = reject { |check| disabled_checks.all.include?(check.code_name) }
18
+
19
+ self.class.new((always_enabled + still_enabled).uniq)
20
+ end
11
21
  end
12
22
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module ThemeCheck
3
+ class DeprecatedFilter < LiquidCheck
4
+ doc "https://shopify.dev/docs/themes/liquid/reference/filters/deprecated-filters"
5
+ category :liquid
6
+ severity :suggestion
7
+
8
+ def on_variable(node)
9
+ used_filters = node.value.filters.map { |name, *_rest| name }
10
+ used_filters.each do |filter|
11
+ alternatives = ShopifyLiquid::DeprecatedFilter.alternatives(filter)
12
+ next unless alternatives
13
+
14
+ alternatives = alternatives.map { |alt| "`#{alt}`" }
15
+ add_offense(
16
+ "Deprecated filter `#{filter}`, consider using an alternative: #{alternatives.join(', ')}",
17
+ node: node,
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end