theme-check 0.10.0 → 0.10.1
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.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +6 -0
 - data/CONTRIBUTING.md +20 -91
 - data/Rakefile +31 -0
 - data/docs/api/check.md +15 -0
 - data/docs/api/html_check.md +46 -0
 - data/docs/api/json_check.md +19 -0
 - data/docs/api/liquid_check.md +99 -0
 - data/docs/checks/{CHECK_DOCS_TEMPLATE.md → TEMPLATE.md.erb} +5 -5
 - data/lib/theme_check/check.rb +1 -1
 - data/lib/theme_check/checks/TEMPLATE.rb.erb +11 -0
 - data/lib/theme_check/json_file.rb +5 -0
 - data/lib/theme_check/language_server/diagnostics_tracker.rb +2 -0
 - data/lib/theme_check/offense.rb +5 -5
 - data/lib/theme_check/template.rb +1 -0
 - data/lib/theme_check/version.rb +1 -1
 - metadata +8 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 56b6a91e5ac4b1e2045b1e4fb2748e5ecb9600206f9ba07df401c1410bf494fc
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: b6fb1b3957ae5aecd7b2efbaa76a2e3c07390ec442f94d416ea5b20ca2cbf966
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e2ca68b31968949dc52240c8ee5ca607e10e063b500cda0a7b06306589849f2bc0098f1b0742f962a91a0ca282aa504acb9f7c0de6b785afff0b577b84fa6eba
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c7186299a1168c5ad1e3cd6544ee8c8248b96a492e1dc82481c26a69e75fb1f04172ceb58da61e310a393fd36c9b990464542e7528810c7bea556b5b8ce9b61d
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/CONTRIBUTING.md
    CHANGED
    
    | 
         @@ -36,103 +36,32 @@ bundle exec theme-check /path/to/your/theme 
     | 
|
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            ## Creating a new "Check"
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
            Run `bundle exec rake "new_check[MyNewCheckName]"` to generate all the files required to create a new check.
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
            module ThemeCheck
         
     | 
| 
       43 
     | 
    
         
            -
              # Does one thing, and does it well!
         
     | 
| 
       44 
     | 
    
         
            -
              # NOTE: inherit from `JsonCheck` to implement a JSON-based check, and from `HtmlCheck`
         
     | 
| 
       45 
     | 
    
         
            -
              # to implement an HTML-based one. See other checks in `lib/theme_check/checks` for examples.
         
     | 
| 
       46 
     | 
    
         
            -
              class MyCheckName < LiquidCheck
         
     | 
| 
       47 
     | 
    
         
            -
                severity :suggestion # :error or :style
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                def on_document(node)
         
     | 
| 
       50 
     | 
    
         
            -
                  # Called with the root node of all templates
         
     | 
| 
       51 
     | 
    
         
            -
                  node.value    # is the original Liquid object for this node. See Liquid source code for details.
         
     | 
| 
       52 
     | 
    
         
            -
                  node.template # is the template being analyzed, See lib/theme_check/template.rb.
         
     | 
| 
       53 
     | 
    
         
            -
                  node.parent   # is the parent node.
         
     | 
| 
       54 
     | 
    
         
            -
                  node.children # are the children nodes.
         
     | 
| 
       55 
     | 
    
         
            -
                  # See lib/theme_check/node.rb for more helper methods
         
     | 
| 
       56 
     | 
    
         
            -
                  theme # Gives you access to all the templates in the theme. See lib/theme_check/theme.rb.
         
     | 
| 
       57 
     | 
    
         
            -
                end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                def on_node(node)
         
     | 
| 
       60 
     | 
    
         
            -
                  # Called for every node
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                def on_tag(node)
         
     | 
| 
       64 
     | 
    
         
            -
                  # Called for each tag (if, include, for, assign, etc.)
         
     | 
| 
       65 
     | 
    
         
            -
                end
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                def after_tag(node)
         
     | 
| 
       68 
     | 
    
         
            -
                  # Called after the tag children have been visited
         
     | 
| 
       69 
     | 
    
         
            -
                  
         
     | 
| 
       70 
     | 
    
         
            -
                  # If you find an issue, add an offense:
         
     | 
| 
       71 
     | 
    
         
            -
                  add_offense("Describe the problem...", node: node)
         
     | 
| 
       72 
     | 
    
         
            -
                  # Or, if the offense is related to the whole template:
         
     | 
| 
       73 
     | 
    
         
            -
                  add_offense("Describe the problem...", template: node.template)
         
     | 
| 
       74 
     | 
    
         
            -
                end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                def on_assign(node)
         
     | 
| 
       77 
     | 
    
         
            -
                  # Called only for {% assign ... %} tags
         
     | 
| 
       78 
     | 
    
         
            -
                end
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
                def on_string(node)
         
     | 
| 
       81 
     | 
    
         
            -
                  # Called for every `String` (including inside if conditions).
         
     | 
| 
       82 
     | 
    
         
            -
                  if node.parent.block?
         
     | 
| 
       83 
     | 
    
         
            -
                    # If parent is a block, `node.value` is a String written directly to the output when
         
     | 
| 
       84 
     | 
    
         
            -
                    # the template is rendered.
         
     | 
| 
       85 
     | 
    
         
            -
                  end
         
     | 
| 
       86 
     | 
    
         
            -
                end
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                def on_error(exception)
         
     | 
| 
       89 
     | 
    
         
            -
                  # Called each time a Liquid exception is raised while parsing the template
         
     | 
| 
       90 
     | 
    
         
            -
                end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                def on_end
         
     | 
| 
       93 
     | 
    
         
            -
                  # A special callback after we're done visiting all the templates
         
     | 
| 
       94 
     | 
    
         
            -
                end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                # Each type of node has a corresponding `on_node_class_name` & `after_node_class_name`
         
     | 
| 
       97 
     | 
    
         
            -
                # A few common examples:
         
     | 
| 
       98 
     | 
    
         
            -
                # on_block_body(node)
         
     | 
| 
       99 
     | 
    
         
            -
                # on_capture(node)
         
     | 
| 
       100 
     | 
    
         
            -
                # on_case(node)
         
     | 
| 
       101 
     | 
    
         
            -
                # on_comment(node)
         
     | 
| 
       102 
     | 
    
         
            -
                # on_condition(node)
         
     | 
| 
       103 
     | 
    
         
            -
                # on_document(node)
         
     | 
| 
       104 
     | 
    
         
            -
                # on_else_condition(node)
         
     | 
| 
       105 
     | 
    
         
            -
                # on_for(node)
         
     | 
| 
       106 
     | 
    
         
            -
                # on_form(node)
         
     | 
| 
       107 
     | 
    
         
            -
                # on_if(node)
         
     | 
| 
       108 
     | 
    
         
            -
                # on_include(node)
         
     | 
| 
       109 
     | 
    
         
            -
                # on_integer(node)
         
     | 
| 
       110 
     | 
    
         
            -
                # on_layout(node)
         
     | 
| 
       111 
     | 
    
         
            -
                # on_method_literal(node)
         
     | 
| 
       112 
     | 
    
         
            -
                # on_paginate(node)
         
     | 
| 
       113 
     | 
    
         
            -
                # on_range(node)
         
     | 
| 
       114 
     | 
    
         
            -
                # on_render(node)
         
     | 
| 
       115 
     | 
    
         
            -
                # on_schema(node)
         
     | 
| 
       116 
     | 
    
         
            -
                # on_section(node)
         
     | 
| 
       117 
     | 
    
         
            -
                # on_style(node)
         
     | 
| 
       118 
     | 
    
         
            -
                # on_unless(node)
         
     | 
| 
       119 
     | 
    
         
            -
                # on_variable(node)
         
     | 
| 
       120 
     | 
    
         
            -
                # on_variable_lookup(node)
         
     | 
| 
       121 
     | 
    
         
            -
              end
         
     | 
| 
       122 
     | 
    
         
            -
            end
         
     | 
| 
       123 
     | 
    
         
            -
            ```
         
     | 
| 
      
 41 
     | 
    
         
            +
            Check the [Check API](/docs/api/check.md) for how to implement a check. Also take a look at other checks in [lib/theme_check/checks](/lib/theme_check/checks).
         
     | 
| 
       124 
42 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
      
 43 
     | 
    
         
            +
            We done implementing your check, add it to `config/default.yml` to enable it:
         
     | 
| 
       126 
44 
     | 
    
         | 
| 
       127 
45 
     | 
    
         
             
            ```yaml
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
            MyNewCheckName:
         
     | 
| 
       129 
47 
     | 
    
         
             
              enabled: true
         
     | 
| 
      
 48 
     | 
    
         
            +
              ignore: []
         
     | 
| 
       130 
49 
     | 
    
         
             
            ```
         
     | 
| 
       131 
50 
     | 
    
         | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
            Add a documentation file in `docs/checks/#{name_of_check}.md` based off of the [check documentation template][doctemplate].
         
     | 
| 
      
 51 
     | 
    
         
            +
            If the check is configurable, the `initialize` argument names and default values should also be duplicated inside `config/default.yml`. eg.:
         
     | 
| 
       135 
52 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 54 
     | 
    
         
            +
            class MyCheckName < LiquidCheck
         
     | 
| 
      
 55 
     | 
    
         
            +
              def initialize(muffin_mode: true)
         
     | 
| 
      
 56 
     | 
    
         
            +
                @muffin_mode = muffin_mode
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
              # ...
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
      
 60 
     | 
    
         
            +
            ```
         
     | 
| 
       137 
61 
     | 
    
         | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
      
 62 
     | 
    
         
            +
            ```yaml
         
     | 
| 
      
 63 
     | 
    
         
            +
            MyNewCheckName:
         
     | 
| 
      
 64 
     | 
    
         
            +
              enabled: true
         
     | 
| 
      
 65 
     | 
    
         
            +
              ignore: []
         
     | 
| 
      
 66 
     | 
    
         
            +
              muffin_mode: true
         
     | 
| 
      
 67 
     | 
    
         
            +
            ```
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -52,3 +52,34 @@ task :prerelease, [:version] do |_t, args| 
     | 
|
| 
       52 
52 
     | 
    
         
             
              require 'theme_check/releaser'
         
     | 
| 
       53 
53 
     | 
    
         
             
              ThemeCheck::Releaser.new.release(args.version)
         
     | 
| 
       54 
54 
     | 
    
         
             
            end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            desc "Create a new check"
         
     | 
| 
      
 57 
     | 
    
         
            +
            task :new_check, [:name] do |_t, args|
         
     | 
| 
      
 58 
     | 
    
         
            +
              require "theme_check/string_helpers"
         
     | 
| 
      
 59 
     | 
    
         
            +
              class_name = args.name
         
     | 
| 
      
 60 
     | 
    
         
            +
              base_name = ThemeCheck::StringHelpers.underscore(class_name)
         
     | 
| 
      
 61 
     | 
    
         
            +
              code_source = "lib/theme_check/checks/#{base_name}.rb"
         
     | 
| 
      
 62 
     | 
    
         
            +
              doc_source = "docs/checks/#{base_name}.md"
         
     | 
| 
      
 63 
     | 
    
         
            +
              test_source = "test/checks/#{base_name}_test.rb"
         
     | 
| 
      
 64 
     | 
    
         
            +
              erb(
         
     | 
| 
      
 65 
     | 
    
         
            +
                "lib/theme_check/checks/TEMPLATE.rb.erb", code_source,
         
     | 
| 
      
 66 
     | 
    
         
            +
                class_name: class_name,
         
     | 
| 
      
 67 
     | 
    
         
            +
              )
         
     | 
| 
      
 68 
     | 
    
         
            +
              erb(
         
     | 
| 
      
 69 
     | 
    
         
            +
                "test/checks/TEMPLATE.rb.erb", test_source,
         
     | 
| 
      
 70 
     | 
    
         
            +
                class_name: class_name,
         
     | 
| 
      
 71 
     | 
    
         
            +
              )
         
     | 
| 
      
 72 
     | 
    
         
            +
              erb(
         
     | 
| 
      
 73 
     | 
    
         
            +
                "docs/checks/TEMPLATE.md.erb", doc_source,
         
     | 
| 
      
 74 
     | 
    
         
            +
                class_name: class_name,
         
     | 
| 
      
 75 
     | 
    
         
            +
                code_source: code_source,
         
     | 
| 
      
 76 
     | 
    
         
            +
                doc_source: doc_source,
         
     | 
| 
      
 77 
     | 
    
         
            +
              )
         
     | 
| 
      
 78 
     | 
    
         
            +
              sh "bundle exec ruby -Itest test/checks/my_new_check_test.rb"
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            def erb(file, to, **args)
         
     | 
| 
      
 82 
     | 
    
         
            +
              require "erb"
         
     | 
| 
      
 83 
     | 
    
         
            +
              File.write(to, ERB.new(File.read(file)).result_with_hash(args))
         
     | 
| 
      
 84 
     | 
    
         
            +
              puts "Generated #{to}"
         
     | 
| 
      
 85 
     | 
    
         
            +
            end
         
     | 
    
        data/docs/api/check.md
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Check API
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Theme Check uses static analysis. It parses theme files into an AST, and then calls the appropriate checks to analyze it.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            An [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) is a tree of node, representing the theme file.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Checks are Ruby classes with callback methods:
         
     | 
| 
      
 8 
     | 
    
         
            +
            - `on_TYPE` that runs before a node of the specific TYPE is visited.
         
     | 
| 
      
 9 
     | 
    
         
            +
            - `after_TYPE` that runs after a node of the specific TYPE is visited.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            There are three types of checks currently supported:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            - [`LiquidCheck`](/docs/api/liquid_check.md)
         
     | 
| 
      
 14 
     | 
    
         
            +
            - [`HtmlCheck`](/docs/api/html_check.md)
         
     | 
| 
      
 15 
     | 
    
         
            +
            - [`JsonCheck`](/docs/api/html_check.md)
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # HTML check API
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            For checking HTML elements in `.liquid` files.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            If you need to check an HTML tag or its attributes, use an `HtmlCheck`.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            The HTML in Liquid files is parsed using the Nokogiri, by consequence you will get [`Nokogiri::XML::Node`][nokogiri].
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 11 
     | 
    
         
            +
            module ThemeCheck
         
     | 
| 
      
 12 
     | 
    
         
            +
              class MyCheckName < HtmlCheck
         
     | 
| 
      
 13 
     | 
    
         
            +
                category :html,
         
     | 
| 
      
 14 
     | 
    
         
            +
                # A check can belong to multiple categories. Valid ones:
         
     | 
| 
      
 15 
     | 
    
         
            +
                categories :translation, :performance
         
     | 
| 
      
 16 
     | 
    
         
            +
                severity :suggestion # :error or :style
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def on_document(node)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # Called with the root node of all templates
         
     | 
| 
      
 20 
     | 
    
         
            +
                  node.value    # is an instance of Nokogiri::XML::Node
         
     | 
| 
      
 21 
     | 
    
         
            +
                  node.template # is the template being analyzed, See lib/theme_check/template.rb.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  node.parent   # is the parent node.
         
     | 
| 
      
 23 
     | 
    
         
            +
                  node.children # are the children nodes.
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # See lib/theme_check/html_node.rb for more helper methods
         
     | 
| 
      
 25 
     | 
    
         
            +
                  theme # Gives you access to all the templates in the theme. See lib/theme_check/theme.rb.
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def on_img(node)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # Called for every <img> element in the file.
         
     | 
| 
      
 30 
     | 
    
         
            +
                  node.attrbutes["class"] # Get the class attribute of the img element.
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def on_a(node)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # Called for every <a> element in the file.
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
      
 38 
     | 
    
         
            +
            ```
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            ## Resources
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            - [Nokogiri::XML::Node API doc][nokogiri]
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            [nokogiri]: https://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # JSON check API
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            For checking the content of `.json` files.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            module ThemeCheck
         
     | 
| 
      
 7 
     | 
    
         
            +
              class MyCheckName < JsonCheck
         
     | 
| 
      
 8 
     | 
    
         
            +
                category :json,
         
     | 
| 
      
 9 
     | 
    
         
            +
                # A check can belong to multiple categories. Valid ones:
         
     | 
| 
      
 10 
     | 
    
         
            +
                categories :translation, :performance
         
     | 
| 
      
 11 
     | 
    
         
            +
                severity :suggestion # :error or :style
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def on_file(file)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  file # an instance of `ThemeCheck::JsonFile`
         
     | 
| 
      
 15 
     | 
    
         
            +
                  file.content # the parsed JSON, as a Ruby object, usually a Hash
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
      
 19 
     | 
    
         
            +
            ```
         
     | 
| 
         @@ -0,0 +1,99 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Liquid check API
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            For checking the Liquid code in `.liquid` files.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            All code inside `{% ... %}` or `{{ ... }}` is Liquid code.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Liquid files are parsed using the Liquid parser, by consequence you will get Liquid nodes (tags, blocks) in your callback methods. Check the Liquid source for details on those nodes: [Liquid source][liquidsource].
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 11 
     | 
    
         
            +
            module ThemeCheck
         
     | 
| 
      
 12 
     | 
    
         
            +
              class MyCheckName < LiquidCheck
         
     | 
| 
      
 13 
     | 
    
         
            +
                category :liquid,
         
     | 
| 
      
 14 
     | 
    
         
            +
                # A check can belong to multiple categories. Valid ones:
         
     | 
| 
      
 15 
     | 
    
         
            +
                categories :translation, :performance
         
     | 
| 
      
 16 
     | 
    
         
            +
                severity :suggestion # :error or :style
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def on_document(node)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # Called with the root node of all templates
         
     | 
| 
      
 20 
     | 
    
         
            +
                  node.value    # is the original Liquid object for this node. See Liquid source code for details.
         
     | 
| 
      
 21 
     | 
    
         
            +
                  node.template # is the template being analyzed, See lib/theme_check/template.rb.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  node.parent   # is the parent node.
         
     | 
| 
      
 23 
     | 
    
         
            +
                  node.children # are the children nodes.
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # See lib/theme_check/node.rb for more helper methods
         
     | 
| 
      
 25 
     | 
    
         
            +
                  theme # Gives you access to all the templates in the theme. See lib/theme_check/theme.rb.
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def on_node(node)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # Called for every node
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def on_tag(node)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # Called for each tag (if, include, for, assign, etc.)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def after_tag(node)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # Called after the tag children have been visited
         
     | 
| 
      
 38 
     | 
    
         
            +
                  
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # If you find an issue, add an offense:
         
     | 
| 
      
 40 
     | 
    
         
            +
                  add_offense("Describe the problem...", node: node)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  # Or, if the offense is related to the whole template:
         
     | 
| 
      
 42 
     | 
    
         
            +
                  add_offense("Describe the problem...", template: node.template)
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def on_assign(node)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # Called only for {% assign ... %} tags
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                def on_string(node)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # Called for every `String` (including inside if conditions).
         
     | 
| 
      
 51 
     | 
    
         
            +
                  if node.parent.block?
         
     | 
| 
      
 52 
     | 
    
         
            +
                    # If parent is a block, `node.value` is a String written directly to the output when
         
     | 
| 
      
 53 
     | 
    
         
            +
                    # the template is rendered.
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                def on_variable(node)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # Called for each {{ ... }}
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def on_error(exception)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  # Called each time a Liquid exception is raised while parsing the template
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                def on_end
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # A special callback after we're done visiting all the files of the theme
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                # Each type of node has a corresponding `on_node_class_name` & `after_node_class_name`
         
     | 
| 
      
 70 
     | 
    
         
            +
                # A few common examples:
         
     | 
| 
      
 71 
     | 
    
         
            +
                # on_capture(node)
         
     | 
| 
      
 72 
     | 
    
         
            +
                # on_case(node)
         
     | 
| 
      
 73 
     | 
    
         
            +
                # on_comment(node)
         
     | 
| 
      
 74 
     | 
    
         
            +
                # on_if(node)
         
     | 
| 
      
 75 
     | 
    
         
            +
                # on_condition(node)
         
     | 
| 
      
 76 
     | 
    
         
            +
                # on_else_condition(node)
         
     | 
| 
      
 77 
     | 
    
         
            +
                # on_for(node)
         
     | 
| 
      
 78 
     | 
    
         
            +
                # on_form(node)
         
     | 
| 
      
 79 
     | 
    
         
            +
                # on_include(node)
         
     | 
| 
      
 80 
     | 
    
         
            +
                # on_integer(node)
         
     | 
| 
      
 81 
     | 
    
         
            +
                # on_layout(node)
         
     | 
| 
      
 82 
     | 
    
         
            +
                # on_method_literal(node)
         
     | 
| 
      
 83 
     | 
    
         
            +
                # on_paginate(node)
         
     | 
| 
      
 84 
     | 
    
         
            +
                # on_range(node)
         
     | 
| 
      
 85 
     | 
    
         
            +
                # on_render(node)
         
     | 
| 
      
 86 
     | 
    
         
            +
                # on_schema(node)
         
     | 
| 
      
 87 
     | 
    
         
            +
                # on_section(node)
         
     | 
| 
      
 88 
     | 
    
         
            +
                # on_style(node)
         
     | 
| 
      
 89 
     | 
    
         
            +
                # on_unless(node)
         
     | 
| 
      
 90 
     | 
    
         
            +
                # on_variable_lookup(node)
         
     | 
| 
      
 91 
     | 
    
         
            +
              end
         
     | 
| 
      
 92 
     | 
    
         
            +
            end
         
     | 
| 
      
 93 
     | 
    
         
            +
            ```
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            ## Resources
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            - [Liquid source][liquidsource]
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            [liquidsource]: https://github.com/Shopify/liquid/tree/master/lib/liquid
         
     | 
| 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # Check Title ( 
     | 
| 
      
 1 
     | 
    
         
            +
            # Check Title (`<%= class_name %>`)
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            A brief paragraph explaining why the check exists.
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
         @@ -21,7 +21,7 @@ This check is aimed at eliminating ... 
     | 
|
| 
       21 
21 
     | 
    
         
             
            The default configuration for this check is the following:
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
            ```yaml
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
      
 24 
     | 
    
         
            +
            <%= class_name %>:
         
     | 
| 
       25 
25 
     | 
    
         
             
              enabled: true
         
     | 
| 
       26 
26 
     | 
    
         
             
              some_option: 10
         
     | 
| 
       27 
27 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -36,12 +36,12 @@ If you don't want to ..., then it's safe to disable this rule. 
     | 
|
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            ## Version
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
            This check has been introduced in Theme Check  
     | 
| 
      
 39 
     | 
    
         
            +
            This check has been introduced in Theme Check THEME_CHECK_VERSION.
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
            ## Resources
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
            - [Rule Source][codesource]
         
     | 
| 
       44 
44 
     | 
    
         
             
            - [Documentation Source][docsource]
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
            [codesource]:  
     | 
| 
       47 
     | 
    
         
            -
            [docsource]:  
     | 
| 
      
 46 
     | 
    
         
            +
            [codesource]: /<%= code_source %>
         
     | 
| 
      
 47 
     | 
    
         
            +
            [docsource]: /<%= doc_source %>
         
     | 
    
        data/lib/theme_check/check.rb
    CHANGED
    
    | 
         @@ -18,7 +18,6 @@ module ThemeCheck 
     | 
|
| 
       18 
18 
     | 
    
         
             
                CATEGORIES = [
         
     | 
| 
       19 
19 
     | 
    
         
             
                  :liquid,
         
     | 
| 
       20 
20 
     | 
    
         
             
                  :translation,
         
     | 
| 
       21 
     | 
    
         
            -
                  :performance,
         
     | 
| 
       22 
21 
     | 
    
         
             
                  :html,
         
     | 
| 
       23 
22 
     | 
    
         
             
                  :json,
         
     | 
| 
       24 
23 
     | 
    
         
             
                  :performance,
         
     | 
| 
         @@ -124,6 +123,7 @@ module ThemeCheck 
     | 
|
| 
       124 
123 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       125 
124 
     | 
    
         
             
                  other.is_a?(Check) && code_name == other.code_name
         
     | 
| 
       126 
125 
     | 
    
         
             
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
                alias_method :eql?, :==
         
     | 
| 
       127 
127 
     | 
    
         | 
| 
       128 
128 
     | 
    
         
             
                def to_s
         
     | 
| 
       129 
129 
     | 
    
         
             
                  s = +"#{code_name}:\n"
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module ThemeCheck
         
     | 
| 
      
 3 
     | 
    
         
            +
              # TODO: inherit from HtmlCheck or JsonCheck if working on a non-Liquid check
         
     | 
| 
      
 4 
     | 
    
         
            +
              class <%= class_name %> < LiquidCheck
         
     | 
| 
      
 5 
     | 
    
         
            +
                severity :suggestion
         
     | 
| 
      
 6 
     | 
    
         
            +
                category :liquid
         
     | 
| 
      
 7 
     | 
    
         
            +
                doc docs_url(__FILE__)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # TODO: def on_<NODE_TYPE>
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "logger"
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module ThemeCheck
         
     | 
| 
       4 
5 
     | 
    
         
             
              module LanguageServer
         
     | 
| 
         @@ -16,6 +17,7 @@ module ThemeCheck 
     | 
|
| 
       16 
17 
     | 
    
         
             
                  def build_diagnostics(offenses, analyzed_files: nil)
         
     | 
| 
       17 
18 
     | 
    
         
             
                    reported_files = Set.new
         
     | 
| 
       18 
19 
     | 
    
         
             
                    new_single_file_offenses = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                    analyzed_files = analyzed_files.map { |path| Pathname.new(path) } if analyzed_files
         
     | 
| 
       19 
21 
     | 
    
         | 
| 
       20 
22 
     | 
    
         
             
                    offenses.group_by(&:template).each do |template, template_offenses|
         
     | 
| 
       21 
23 
     | 
    
         
             
                      next unless template
         
     | 
    
        data/lib/theme_check/offense.rb
    CHANGED
    
    | 
         @@ -124,13 +124,13 @@ module ThemeCheck 
     | 
|
| 
       124 
124 
     | 
    
         | 
| 
       125 
125 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       126 
126 
     | 
    
         
             
                  other.is_a?(Offense) &&
         
     | 
| 
       127 
     | 
    
         
            -
                     
     | 
| 
      
 127 
     | 
    
         
            +
                    code_name == other.code_name &&
         
     | 
| 
       128 
128 
     | 
    
         
             
                    message == other.message &&
         
     | 
| 
       129 
     | 
    
         
            -
                     
     | 
| 
       130 
     | 
    
         
            -
                     
     | 
| 
       131 
     | 
    
         
            -
                     
     | 
| 
       132 
     | 
    
         
            -
                    line_number == other.line_number
         
     | 
| 
      
 129 
     | 
    
         
            +
                    location == other.location &&
         
     | 
| 
      
 130 
     | 
    
         
            +
                    start_index == other.start_index &&
         
     | 
| 
      
 131 
     | 
    
         
            +
                    end_index == other.end_index
         
     | 
| 
       133 
132 
     | 
    
         
             
                end
         
     | 
| 
      
 133 
     | 
    
         
            +
                alias_method :eql?, :==
         
     | 
| 
       134 
134 
     | 
    
         | 
| 
       135 
135 
     | 
    
         
             
                def to_s
         
     | 
| 
       136 
136 
     | 
    
         
             
                  if template
         
     | 
    
        data/lib/theme_check/template.rb
    CHANGED
    
    
    
        data/lib/theme_check/version.rb
    CHANGED
    
    
    
        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.10. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.10.1
         
     | 
| 
       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-06- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-06-11 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: liquid
         
     | 
| 
         @@ -69,7 +69,11 @@ files: 
     | 
|
| 
       69 
69 
     | 
    
         
             
            - data/shopify_liquid/tags.yml
         
     | 
| 
       70 
70 
     | 
    
         
             
            - data/shopify_translation_keys.yml
         
     | 
| 
       71 
71 
     | 
    
         
             
            - dev.yml
         
     | 
| 
       72 
     | 
    
         
            -
            - docs/ 
     | 
| 
      
 72 
     | 
    
         
            +
            - docs/api/check.md
         
     | 
| 
      
 73 
     | 
    
         
            +
            - docs/api/html_check.md
         
     | 
| 
      
 74 
     | 
    
         
            +
            - docs/api/json_check.md
         
     | 
| 
      
 75 
     | 
    
         
            +
            - docs/api/liquid_check.md
         
     | 
| 
      
 76 
     | 
    
         
            +
            - docs/checks/TEMPLATE.md.erb
         
     | 
| 
       73 
77 
     | 
    
         
             
            - docs/checks/asset_size_css.md
         
     | 
| 
       74 
78 
     | 
    
         
             
            - docs/checks/asset_size_javascript.md
         
     | 
| 
       75 
79 
     | 
    
         
             
            - docs/checks/asset_url_filters.md
         
     | 
| 
         @@ -111,6 +115,7 @@ files: 
     | 
|
| 
       111 
115 
     | 
    
         
             
            - lib/theme_check/bug.rb
         
     | 
| 
       112 
116 
     | 
    
         
             
            - lib/theme_check/check.rb
         
     | 
| 
       113 
117 
     | 
    
         
             
            - lib/theme_check/checks.rb
         
     | 
| 
      
 118 
     | 
    
         
            +
            - lib/theme_check/checks/TEMPLATE.rb.erb
         
     | 
| 
       114 
119 
     | 
    
         
             
            - lib/theme_check/checks/asset_size_css.rb
         
     | 
| 
       115 
120 
     | 
    
         
             
            - lib/theme_check/checks/asset_size_javascript.rb
         
     | 
| 
       116 
121 
     | 
    
         
             
            - lib/theme_check/checks/asset_url_filters.rb
         
     |