theme-check 0.7.2 → 0.8.3

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/theme-check.yml +1 -0
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +33 -0
  5. data/RELEASING.md +5 -3
  6. data/config/default.yml +1 -1
  7. data/data/shopify_liquid/tags.yml +3 -0
  8. data/data/shopify_translation_keys.yml +1 -0
  9. data/dev.yml +1 -1
  10. data/docs/checks/nested_snippet.md +1 -1
  11. data/docs/checks/space_inside_braces.md +28 -0
  12. data/exe/theme-check +1 -1
  13. data/lib/theme_check.rb +5 -0
  14. data/lib/theme_check/analyzer.rb +19 -9
  15. data/lib/theme_check/bug.rb +20 -0
  16. data/lib/theme_check/check.rb +5 -1
  17. data/lib/theme_check/checks.rb +39 -8
  18. data/lib/theme_check/checks/missing_enable_comment.rb +4 -4
  19. data/lib/theme_check/checks/nested_snippet.rb +1 -1
  20. data/lib/theme_check/checks/space_inside_braces.rb +8 -2
  21. data/lib/theme_check/cli.rb +99 -64
  22. data/lib/theme_check/config.rb +6 -2
  23. data/lib/theme_check/disabled_check.rb +39 -0
  24. data/lib/theme_check/disabled_checks.rb +20 -32
  25. data/lib/theme_check/exceptions.rb +32 -0
  26. data/lib/theme_check/json_file.rb +5 -1
  27. data/lib/theme_check/language_server.rb +1 -1
  28. data/lib/theme_check/language_server/completion_engine.rb +1 -1
  29. data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +10 -8
  30. data/lib/theme_check/language_server/constants.rb +5 -1
  31. data/lib/theme_check/language_server/document_link_engine.rb +2 -2
  32. data/lib/theme_check/language_server/handler.rb +32 -24
  33. data/lib/theme_check/language_server/variable_lookup_finder.rb +295 -0
  34. data/lib/theme_check/node.rb +12 -0
  35. data/lib/theme_check/offense.rb +14 -48
  36. data/lib/theme_check/parsing_helpers.rb +1 -1
  37. data/lib/theme_check/position.rb +77 -0
  38. data/lib/theme_check/position_helper.rb +37 -0
  39. data/lib/theme_check/remote_asset_file.rb +3 -0
  40. data/lib/theme_check/shopify_liquid/tag.rb +13 -0
  41. data/lib/theme_check/version.rb +1 -1
  42. data/lib/theme_check/visitor.rb +9 -10
  43. data/theme-check.gemspec +2 -0
  44. metadata +10 -5
  45. data/lib/theme_check/language_server/position_helper.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b516a7041c1025cd22bcbb4cab685b45893b38fa41ab55b539efad60cf67e100
4
- data.tar.gz: 86d5d5054247c0c86b4a31b066a579fc60fbcf4f0d32940354c4fc9793667498
3
+ metadata.gz: fc820b814467926919858c11517a275e70dd07aea017285f315dc3309e4b49a3
4
+ data.tar.gz: 949c2934821bb7270aa466c3430d8fb640e8af938fb239aa1a2a346c82580a50
5
5
  SHA512:
6
- metadata.gz: b76463ad9ecab829705519f163745fdd7cb6dea084558983c914dd3ddf923385050da1c535ad73f48a4442dd8a67bc797fd072e293aa85befb15a141870196db
7
- data.tar.gz: 67571132dcf7fd556c81d4eb7f7e15c8db6c7ccee70384bb6654915090d5c8c213dbbee9b9b36acd74f0cac02390630defe7c1de1956f41f61c9d30294cdd4a0
6
+ metadata.gz: 699907617f0401cd5737c7f774b7063fae97f17465a8ac06ad1e404992b969923e4de6ff877c5f85fb951a8af1433ac017ab651465132b69d6143ff77baa5495
7
+ data.tar.gz: 93d69bd9b50561cc0f10940f4b5e7c5b19fcef43d105d0896b4ae484a3df13301cfc51f6470dff4b83b1e3410a3736f54d5097dca9a80763fa7c4790f1761018
@@ -15,6 +15,7 @@ jobs:
15
15
  version:
16
16
  - 3.0.0
17
17
  - 2.7.1
18
+ - 2.6.6
18
19
 
19
20
  name: Ruby ${{ matrix.version }}
20
21
 
data/.rubocop.yml CHANGED
@@ -7,7 +7,7 @@ require:
7
7
  - rubocop-rake
8
8
 
9
9
  AllCops:
10
- TargetRubyVersion: 2.7
10
+ TargetRubyVersion: 2.6
11
11
  Exclude:
12
12
  - 'vendor/bundle/**/*'
13
13
  - 'packaging/builds/**/*'
data/CHANGELOG.md CHANGED
@@ -1,4 +1,37 @@
1
1
 
2
+ v0.8.3 / 2021-05-17
3
+ ==================
4
+
5
+ * Making sure VERSION is set before referencing it
6
+
7
+ v0.8.2 / 2021-05-14
8
+ ===================
9
+
10
+ * Bump NestedSnippet max_nesting_level to 3
11
+ * Add a message to help debug errors, and timeout checks after 5 sec
12
+ * Object Completions Everywhere!
13
+ * Include operators to space inside braces check
14
+
15
+ 0.8.1 / 2021-04-22
16
+ ==================
17
+
18
+ * Add consistent spacing around the pipe character (`|`) in variable expressions to the `SpaceInsideBrace` check ([#73](https://github.com/shopify/theme-check/issues/73))
19
+ * Add ReCaptcha system translation ([#265](https://github.com/shopify/theme-check/issues/265))
20
+ * Fix document links in `{% liquid %}` tags ([#263](https://github.com/shopify/theme-check/issues/263))
21
+ * Fix theme-check-disable for checks based on regular expressions ([#242](https://github.com/shopify/theme-check/issues/242))
22
+ * Fix VS Code crash on new window ([#264](https://github.com/shopify/theme-check/issues/264))
23
+ * Rescue errors thrown by remote_asset_file
24
+
25
+ 0.8.0 / 2021-04-13
26
+ ==================
27
+
28
+ * Set minimal Ruby version to 2.6
29
+
30
+ 0.7.3 / 2021-04-13
31
+ ==================
32
+
33
+ * Refactor CLI option parsing
34
+
2
35
  0.7.2 / 2021-04-12
3
36
  ==================
4
37
 
data/RELEASING.md CHANGED
@@ -9,11 +9,13 @@
9
9
  rake prerelease[$VERSION]
10
10
  ```
11
11
 
12
- 3. Commit your changes and make a PR.
12
+ 3. Run [`git changelog`](https://github.com/tj/git-extras) to update `CHANGELOG.md`.
13
13
 
14
- 4. Merge your PR to master.
14
+ 4. Commit your changes and make a PR.
15
15
 
16
- 5. On [Shipit](https://shipit.shopify.io/shopify/theme-check/rubygems), deploy your commit.
16
+ 5. Merge your PR to master.
17
+
18
+ 6. On [Shipit](https://shipit.shopify.io/shopify/theme-check/rubygems), deploy your commit.
17
19
 
18
20
  ## Homebrew Release Process
19
21
 
data/config/default.yml CHANGED
@@ -17,7 +17,7 @@ MissingTemplate:
17
17
 
18
18
  NestedSnippet:
19
19
  enabled: true
20
- max_nesting_level: 2
20
+ max_nesting_level: 3
21
21
 
22
22
  RequiredLayoutThemeObject:
23
23
  enabled: true
@@ -8,6 +8,8 @@
8
8
  - cycle
9
9
  - decrement
10
10
  - echo
11
+ - else
12
+ - elsif
11
13
  - for
12
14
  - form
13
15
  - if
@@ -25,3 +27,4 @@
25
27
  - stylesheet
26
28
  - tablerow
27
29
  - unless
30
+ - when
@@ -848,3 +848,4 @@
848
848
  - shopify.store_availability.pick_up_time.two_to_four_hours
849
849
  - shopify.store_availability.pick_up_time.immediately
850
850
  - shopify.store_availability.pick_up_time.next_day
851
+ - shopify.online_store.spam_detection.disclaimer_html
data/dev.yml CHANGED
@@ -3,7 +3,7 @@ name: theme-check
3
3
  type: ruby
4
4
 
5
5
  up:
6
- - ruby: 2.7.1
6
+ - ruby: 2.6.6
7
7
  - bundler
8
8
 
9
9
  commands:
@@ -45,7 +45,7 @@ The default configuration for this check is the following:
45
45
  ```yaml
46
46
  NestedSnippet:
47
47
  enabled: true
48
- max_nesting_level: 2
48
+ max_nesting_level: 3
49
49
  ```
50
50
 
51
51
  ### `max_nesting_level`
@@ -17,6 +17,14 @@ This check is aimed at eliminating ugly Liquid:
17
17
  <!-- After commas and semicolons -->
18
18
  {% form 'type', object, key:value %}
19
19
  {% endform %}
20
+
21
+ <!-- Arround filter pipelines -->
22
+ {{ url | asset_url | img_tag }}
23
+ {% assign my_upcase_string = "Hello world"| upcase %}
24
+
25
+ <!-- Arround symbol operators -->
26
+ {%- if target == product and product.price_varies -%}
27
+ {%- if product.featured_media.width >=165 -%}
20
28
  ```
21
29
 
22
30
  :+1: Examples of **correct** code for this check:
@@ -33,6 +41,10 @@ This check is aimed at eliminating ugly Liquid:
33
41
  media_size: section.settings.product_recommendations_image_ratio,
34
42
  center_align_text: section.settings.center_align_text
35
43
  %}
44
+ {{ url | asset_url | img_tag }}
45
+ {% assign my_upcase_string = "Hello world" | upcase %}
46
+ {%- if target == product and product.price_varies -%}
47
+ {%- if product.featured_media.width >= 165 -%}
36
48
  ```
37
49
 
38
50
  ## Check Options
@@ -44,6 +56,22 @@ SpaceInsideBraces:
44
56
  enabled: true
45
57
  ```
46
58
 
59
+ ## Auto-correction
60
+
61
+ This check can automatically trim or add spaces around `{{ ... }}`.
62
+
63
+ ```liquid
64
+ {{ x}}
65
+ {{x}}
66
+ {{ x }}
67
+ ```
68
+
69
+ Can all be auto-corrected with the `--auto-correct` option to:
70
+
71
+ ```liquid
72
+ {{ x }}
73
+ ```
74
+
47
75
  ## When Not To Use It
48
76
 
49
77
  If you don't care about the look of your code.
data/exe/theme-check CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require "theme_check"
5
5
 
6
- ThemeCheck::Cli.new.run!(ARGV)
6
+ ThemeCheck::Cli.parse_and_run(ARGV)
data/lib/theme_check.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  require "liquid"
3
3
 
4
+ require_relative "theme_check/bug"
5
+ require_relative "theme_check/exceptions"
4
6
  require_relative "theme_check/analyzer"
5
7
  require_relative "theme_check/check"
6
8
  require_relative "theme_check/checks_tracking"
7
9
  require_relative "theme_check/cli"
10
+ require_relative "theme_check/disabled_check"
8
11
  require_relative "theme_check/disabled_checks"
9
12
  require_relative "theme_check/liquid_check"
10
13
  require_relative "theme_check/locale_diff"
@@ -14,6 +17,8 @@ require_relative "theme_check/regex_helpers"
14
17
  require_relative "theme_check/json_check"
15
18
  require_relative "theme_check/json_file"
16
19
  require_relative "theme_check/json_helpers"
20
+ require_relative "theme_check/position_helper"
21
+ require_relative "theme_check/position"
17
22
  require_relative "theme_check/language_server"
18
23
  require_relative "theme_check/checks"
19
24
  require_relative "theme_check/config"
@@ -1,11 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
3
  class Analyzer
4
- attr_reader :offenses
5
-
6
4
  def initialize(theme, checks = Check.all.map(&:new), auto_correct = false)
7
5
  @theme = theme
8
- @offenses = []
9
6
  @auto_correct = auto_correct
10
7
 
11
8
  @liquid_checks = Checks.new
@@ -13,7 +10,6 @@ module ThemeCheck
13
10
 
14
11
  checks.each do |check|
15
12
  check.theme = @theme
16
- check.offenses = @offenses
17
13
 
18
14
  case check
19
15
  when LiquidCheck
@@ -26,26 +22,40 @@ module ThemeCheck
26
22
  @visitor = Visitor.new(@liquid_checks)
27
23
  end
28
24
 
25
+ def offenses
26
+ @liquid_checks.flat_map(&:offenses) + @json_checks.flat_map(&:offenses)
27
+ end
28
+
29
+ def offenses_clear!
30
+ @liquid_checks.each do |check|
31
+ check.offenses.clear
32
+ end
33
+
34
+ @json_checks.each do |check|
35
+ check.offenses.clear
36
+ end
37
+ end
38
+
29
39
  def analyze_theme
30
- @offenses.clear
40
+ offenses_clear!
31
41
  @theme.liquid.each { |template| @visitor.visit_template(template) }
32
42
  @theme.json.each { |json_file| @json_checks.call(:on_file, json_file) }
33
43
  @liquid_checks.call(:on_end)
34
44
  @json_checks.call(:on_end)
35
- @offenses
45
+ offenses
36
46
  end
37
47
 
38
48
  def uncorrectable_offenses
39
49
  unless @auto_correct
40
- return @offenses
50
+ return offenses
41
51
  end
42
52
 
43
- @offenses.select { |offense| !offense.correctable? }
53
+ offenses.select { |offense| !offense.correctable? }
44
54
  end
45
55
 
46
56
  def correct_offenses
47
57
  if @auto_correct
48
- @offenses.each(&:correct)
58
+ offenses.each(&:correct)
49
59
  @theme.liquid.each(&:write)
50
60
  end
51
61
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ require 'theme_check/version'
3
+
4
+ module ThemeCheck
5
+ BUG_POSTAMBLE = <<~EOS
6
+ Theme Check Version: #{VERSION}
7
+ Ruby Version: #{RUBY_VERSION}
8
+ Platform: #{RUBY_PLATFORM}
9
+ Muffin mode: activated
10
+
11
+ ------------------------
12
+ Whoops! It looks like you found a bug in Theme Check.
13
+ Please report it at https://github.com/Shopify/theme-check/issues, and include the message above.
14
+ Or cross your fingers real hard, and try again.
15
+ EOS
16
+
17
+ def self.bug(message)
18
+ abort(message + BUG_POSTAMBLE)
19
+ end
20
+ end
@@ -6,8 +6,8 @@ module ThemeCheck
6
6
  include JsonHelpers
7
7
 
8
8
  attr_accessor :theme
9
- attr_accessor :offenses
10
9
  attr_accessor :options
10
+ attr_writer :offenses
11
11
 
12
12
  SEVERITIES = [
13
13
  :error,
@@ -69,6 +69,10 @@ module ThemeCheck
69
69
  end
70
70
  end
71
71
 
72
+ def offenses
73
+ @offenses ||= []
74
+ end
75
+
72
76
  def severity
73
77
  self.class.severity
74
78
  end
@@ -1,22 +1,53 @@
1
1
  # frozen_string_literal: true
2
+ require "pp"
3
+ require "timeout"
4
+
2
5
  module ThemeCheck
3
6
  class Checks < Array
7
+ CHECK_METHOD_TIMEOUT = 5 # sec
8
+
4
9
  def call(method, *args)
5
10
  each do |check|
6
- if check.respond_to?(method) && !check.ignored?
7
- check.send(method, *args)
8
- end
11
+ call_check_method(check, method, *args)
9
12
  end
10
13
  end
11
14
 
12
- def always_enabled
13
- self.class.new(reject(&:can_disable?))
15
+ def disableable
16
+ self.class.new(select(&:can_disable?))
14
17
  end
15
18
 
16
- def except_for(disabled_checks)
17
- still_enabled = reject { |check| disabled_checks.all.include?(check.code_name) }
19
+ private
20
+
21
+ def call_check_method(check, method, *args)
22
+ return unless check.respond_to?(method) && !check.ignored?
23
+
24
+ Timeout.timeout(CHECK_METHOD_TIMEOUT) do
25
+ check.send(method, *args)
26
+ end
27
+ rescue Liquid::Error
28
+ # Pass-through Liquid errors
29
+ raise
30
+ rescue => e
31
+ node = args.first
32
+ template = node.respond_to?(:template) ? node.template.relative_path : "?"
33
+ markup = node.respond_to?(:markup) ? node.markup : ""
34
+ node_class = node.respond_to?(:value) ? node.value.class : "?"
35
+
36
+ ThemeCheck.bug(<<~EOS)
37
+ Exception while running `#{check.code_name}##{method}`:
38
+ ```
39
+ #{e.class}: #{e.message}
40
+ #{e.backtrace.join("\n ")}
41
+ ```
18
42
 
19
- self.class.new((always_enabled + still_enabled).uniq)
43
+ Template: `#{template}`
44
+ Node: `#{node_class}`
45
+ Markup:
46
+ ```
47
+ #{markup}
48
+ ```
49
+ Check options: `#{check.options.pretty_inspect}`
50
+ EOS
20
51
  end
21
52
  end
22
53
  end
@@ -17,13 +17,13 @@ module ThemeCheck
17
17
  end
18
18
 
19
19
  def after_document(node)
20
- return if @disabled_checks.full_document_disabled?
21
- return unless @disabled_checks.any?
20
+ checks_missing_end_index = @disabled_checks.checks_missing_end_index
21
+ return if checks_missing_end_index.empty?
22
22
 
23
- message = if @disabled_checks.all_disabled?
23
+ message = if checks_missing_end_index.any? { |name| name == :all }
24
24
  "All checks were"
25
25
  else
26
- @disabled_checks.all.join(', ') + " " + (@disabled_checks.all.size == 1 ? "was" : "were")
26
+ checks_missing_end_index.join(', ') + " " + (checks_missing_end_index.size == 1 ? "was" : "were")
27
27
  end
28
28
 
29
29
  add_offense("#{message} disabled but not re-enabled with theme-check-enable", node: node)
@@ -20,7 +20,7 @@ module ThemeCheck
20
20
  end
21
21
  end
22
22
 
23
- def initialize(max_nesting_level: 2)
23
+ def initialize(max_nesting_level: 3)
24
24
  @max_nesting_level = max_nesting_level
25
25
  @templates = {}
26
26
  end
@@ -15,12 +15,18 @@ module ThemeCheck
15
15
  return if :assign == node.type_name
16
16
 
17
17
  outside_of_strings(node.markup) do |chunk|
18
- chunk.scan(/([,:]) +/) do |_match|
18
+ chunk.scan(/([,:|]|==|<>|<=|>=|<|>|!=) +/) do |_match|
19
19
  add_offense("Too many spaces after '#{Regexp.last_match(1)}'", node: node, markup: Regexp.last_match(0))
20
20
  end
21
- chunk.scan(/([,:])\S/) do |_match|
21
+ chunk.scan(/([,:|]|==|<>|<=|>=|<\b|>\b|!=)(\S|\z)/) do |_match|
22
22
  add_offense("Space missing after '#{Regexp.last_match(1)}'", node: node, markup: Regexp.last_match(0))
23
23
  end
24
+ chunk.scan(/ (\||==|<>|<=|>=|<|>|!=)+/) do |_match|
25
+ add_offense("Too many spaces before '#{Regexp.last_match(1)}'", node: node, markup: Regexp.last_match(0))
26
+ end
27
+ chunk.scan(/(\A|\S)(?<match>\||==|<>|<=|>=|<|\b>|!=)/) do |_match|
28
+ add_offense("Space missing before '#{Regexp.last_match(1)}'", node: node, markup: Regexp.last_match(0))
29
+ end
24
30
  end
25
31
  end
26
32
 
@@ -1,85 +1,104 @@
1
1
  # frozen_string_literal: true
2
+ require "optparse"
3
+
2
4
  module ThemeCheck
3
5
  class Cli
4
6
  class Abort < StandardError; end
5
7
 
6
- USAGE = <<~END
7
- Usage: theme-check [options] /path/to/your/theme
8
-
9
- Basic Options:
10
- -C, --config <path> Use the config provided, overriding .theme-check.yml if present
11
- -c, --category <category> Only run this category of checks
12
- -x, --exclude-category <category> Exclude this category of checks
13
- -a, --auto-correct Automatically fix offenses
14
-
15
- Miscellaneous:
16
- --init Generate a .theme-check.yml file
17
- --print-config Output active config to STDOUT
18
- -h, --help Show this. Hi!
19
- -l, --list List enabled checks
20
- -v, --version Print Theme Check version
21
-
22
- Description:
23
- Theme Check helps you follow Shopify Themes & Liquid best practices by analyzing the
24
- Liquid & JSON inside your theme.
25
-
26
- You can configure checks in the .theme-check.yml file of your theme root directory.
27
- END
8
+ attr_accessor :path
28
9
 
29
- def run(argv)
10
+ def initialize
30
11
  @path = "."
12
+ @command = :check
13
+ @only_categories = []
14
+ @exclude_categories = []
15
+ @auto_correct = false
16
+ @config_path = nil
17
+ end
31
18
 
32
- command = :check
33
- only_categories = []
34
- exclude_categories = []
35
- auto_correct = false
36
- config_path = nil
37
-
38
- args = argv.dup
39
- while (arg = args.shift)
40
- case arg
41
- when "--help", "-h"
42
- raise Abort, USAGE
43
- when "--version", "-v"
44
- command = :version
45
- when "--config", "-C"
46
- config_path = Pathname.new(args.shift)
47
- when "--category", "-c"
48
- only_categories << args.shift.to_sym
49
- when "--exclude-category", "-x"
50
- exclude_categories << args.shift.to_sym
51
- when "--list", "-l"
52
- command = :list
53
- when "--auto-correct", "-a"
54
- auto_correct = true
55
- when "--init"
56
- command = :init
57
- when "--print"
58
- command = :print
59
- else
60
- @path = arg
61
- end
62
- end
19
+ def option_parser(parser = OptionParser.new, help: true)
20
+ return @option_parser if defined?(@option_parser)
21
+ @option_parser = parser
22
+ @option_parser.banner = "Usage: theme-check [options] [/path/to/your/theme]"
23
+
24
+ @option_parser.separator("")
25
+ @option_parser.separator("Basic Options:")
26
+ @option_parser.on(
27
+ "-C", "--config PATH",
28
+ "Use the config provided, overriding .theme-check.yml if present"
29
+ ) { |path| @config_path = path }
30
+ @option_parser.on(
31
+ "-c", "--category CATEGORY",
32
+ "Only run this category of checks"
33
+ ) { |category| @only_categories << category.to_sym }
34
+ @option_parser.on(
35
+ "-x", "--exclude-category CATEGORY",
36
+ "Exclude this category of checks"
37
+ ) { |category| @exclude_categories << category.to_sym }
38
+ @option_parser.on(
39
+ "-a", "--auto-correct",
40
+ "Automatically fix offenses"
41
+ ) { @auto_correct = true }
42
+
43
+ @option_parser.separator("")
44
+ @option_parser.separator("Miscellaneous:")
45
+ @option_parser.on(
46
+ "--init",
47
+ "Generate a .theme-check.yml file"
48
+ ) { @command = :init }
49
+ @option_parser.on(
50
+ "--print",
51
+ "Output active config to STDOUT"
52
+ ) { @command = :print }
53
+ @option_parser.on(
54
+ "-h", "--help",
55
+ "Show this. Hi!"
56
+ ) { @command = :help } if help
57
+ @option_parser.on(
58
+ "-l", "--list",
59
+ "List enabled checks"
60
+ ) { @command = :list }
61
+ @option_parser.on(
62
+ "-v", "--version",
63
+ "Print Theme Check version"
64
+ ) { @command = :version }
65
+
66
+ @option_parser.separator("")
67
+ @option_parser.separator(<<~EOS)
68
+ Description:
69
+ Theme Check helps you follow Shopify Themes & Liquid best practices by analyzing the
70
+ Liquid & JSON inside your theme.
71
+
72
+ You can configure checks in the .theme-check.yml file of your theme root directory.
73
+ EOS
74
+
75
+ @option_parser
76
+ end
77
+
78
+ def parse(argv)
79
+ @path = option_parser.parse(argv).first || "."
80
+ end
63
81
 
64
- unless [:version, :init].include?(command)
65
- @config = if config_path
82
+ def run!
83
+ unless [:version, :init, :help].include?(@command)
84
+ @config = if @config_path
66
85
  ThemeCheck::Config.new(
67
86
  root: @path,
68
- configuration: ThemeCheck::Config.load_file(config_path)
87
+ configuration: ThemeCheck::Config.load_file(@config_path)
69
88
  )
70
89
  else
71
90
  ThemeCheck::Config.from_path(@path)
72
91
  end
73
- @config.only_categories = only_categories
74
- @config.exclude_categories = exclude_categories
75
- @config.auto_correct = auto_correct
92
+ @config.only_categories = @only_categories
93
+ @config.exclude_categories = @exclude_categories
94
+ @config.auto_correct = @auto_correct
76
95
  end
77
96
 
78
- send(command)
97
+ send(@command)
79
98
  end
80
99
 
81
- def run!(argv)
82
- run(argv)
100
+ def run
101
+ run!
83
102
  rescue Abort => e
84
103
  if e.message.empty?
85
104
  exit(1)
@@ -88,6 +107,18 @@ module ThemeCheck
88
107
  end
89
108
  end
90
109
 
110
+ def self.parse_and_run!(argv)
111
+ cli = new
112
+ cli.parse(argv)
113
+ cli.run!
114
+ end
115
+
116
+ def self.parse_and_run(argv)
117
+ cli = new
118
+ cli.parse(argv)
119
+ cli.run
120
+ end
121
+
91
122
  def list
92
123
  puts @config.enabled_checks
93
124
  end
@@ -111,12 +142,16 @@ module ThemeCheck
111
142
  puts YAML.dump(@config.to_h)
112
143
  end
113
144
 
145
+ def help
146
+ puts option_parser.to_s
147
+ end
148
+
114
149
  def check
115
150
  puts "Checking #{@config.root} ..."
116
151
  storage = ThemeCheck::FileSystemStorage.new(@config.root, ignored_patterns: @config.ignored_patterns)
117
152
  theme = ThemeCheck::Theme.new(storage)
118
153
  if theme.all.empty?
119
- raise Abort, "No templates found.\n#{USAGE}"
154
+ raise Abort, "No templates found."
120
155
  end
121
156
  analyzer = ThemeCheck::Analyzer.new(theme, @config.enabled_checks, @config.auto_correct)
122
157
  analyzer.analyze_theme