theme-check 0.8.0 → 0.9.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/.github/workflows/theme-check.yml +3 -0
- data/CHANGELOG.md +44 -0
- data/CONTRIBUTING.md +2 -1
- data/README.md +4 -1
- data/RELEASING.md +5 -3
- data/config/default.yml +42 -1
- data/data/shopify_liquid/tags.yml +3 -0
- data/data/shopify_translation_keys.yml +1 -0
- data/docs/checks/asset_url_filters.md +56 -0
- data/docs/checks/content_for_header_modification.md +42 -0
- data/docs/checks/nested_snippet.md +1 -1
- data/docs/checks/parser_blocking_script_tag.md +53 -0
- data/docs/checks/space_inside_braces.md +28 -0
- data/exe/theme-check-language-server +1 -2
- data/lib/theme_check.rb +13 -1
- data/lib/theme_check/analyzer.rb +79 -13
- data/lib/theme_check/bug.rb +20 -0
- data/lib/theme_check/check.rb +36 -7
- data/lib/theme_check/checks.rb +47 -8
- data/lib/theme_check/checks/asset_url_filters.rb +46 -0
- data/lib/theme_check/checks/content_for_header_modification.rb +41 -0
- data/lib/theme_check/checks/img_width_and_height.rb +18 -49
- data/lib/theme_check/checks/missing_enable_comment.rb +4 -4
- data/lib/theme_check/checks/missing_template.rb +1 -0
- data/lib/theme_check/checks/nested_snippet.rb +1 -1
- data/lib/theme_check/checks/parser_blocking_javascript.rb +6 -38
- data/lib/theme_check/checks/parser_blocking_script_tag.rb +20 -0
- data/lib/theme_check/checks/remote_asset.rb +21 -79
- data/lib/theme_check/checks/space_inside_braces.rb +8 -2
- data/lib/theme_check/checks/template_length.rb +3 -0
- data/lib/theme_check/checks/valid_html_translation.rb +1 -0
- data/lib/theme_check/config.rb +2 -0
- data/lib/theme_check/disabled_check.rb +41 -0
- data/lib/theme_check/disabled_checks.rb +33 -29
- data/lib/theme_check/exceptions.rb +32 -0
- data/lib/theme_check/html_check.rb +7 -0
- data/lib/theme_check/html_node.rb +56 -0
- data/lib/theme_check/html_visitor.rb +38 -0
- data/lib/theme_check/json_file.rb +13 -1
- data/lib/theme_check/language_server.rb +2 -1
- data/lib/theme_check/language_server/completion_engine.rb +1 -1
- data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +1 -0
- data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +10 -8
- data/lib/theme_check/language_server/constants.rb +5 -1
- data/lib/theme_check/language_server/diagnostics_tracker.rb +64 -0
- data/lib/theme_check/language_server/document_link_engine.rb +2 -2
- data/lib/theme_check/language_server/handler.rb +63 -50
- data/lib/theme_check/language_server/server.rb +1 -1
- data/lib/theme_check/language_server/variable_lookup_finder.rb +295 -0
- data/lib/theme_check/liquid_check.rb +1 -4
- data/lib/theme_check/node.rb +12 -0
- data/lib/theme_check/offense.rb +30 -46
- data/lib/theme_check/position.rb +77 -0
- data/lib/theme_check/position_helper.rb +37 -0
- data/lib/theme_check/remote_asset_file.rb +3 -0
- data/lib/theme_check/shopify_liquid/tag.rb +13 -0
- data/lib/theme_check/template.rb +8 -0
- data/lib/theme_check/theme.rb +7 -2
- data/lib/theme_check/version.rb +1 -1
- data/lib/theme_check/visitor.rb +4 -14
- metadata +19 -4
- data/lib/theme_check/language_server/position_helper.rb +0 -27
| @@ -0,0 +1,77 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ThemeCheck
         | 
| 4 | 
            +
              class Position
         | 
| 5 | 
            +
                include PositionHelper
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(needle, contents, line_number_1_indexed)
         | 
| 8 | 
            +
                  @needle = needle
         | 
| 9 | 
            +
                  @contents = contents
         | 
| 10 | 
            +
                  @line_number_1_indexed = line_number_1_indexed
         | 
| 11 | 
            +
                  @start_row_column = nil
         | 
| 12 | 
            +
                  @end_row_column = nil
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def start_line_index
         | 
| 16 | 
            +
                  from_row_column_to_index(contents, line_number, 0)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # 0-indexed, inclusive
         | 
| 20 | 
            +
                def start_index
         | 
| 21 | 
            +
                  contents.index(needle, start_line_index) || start_line_index
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                # 0-indexed, exclusive
         | 
| 25 | 
            +
                def end_index
         | 
| 26 | 
            +
                  start_index + needle.size
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def start_row
         | 
| 30 | 
            +
                  start_row_column[0]
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def start_column
         | 
| 34 | 
            +
                  start_row_column[1]
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def end_row
         | 
| 38 | 
            +
                  end_row_column[0]
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def end_column
         | 
| 42 | 
            +
                  end_row_column[1]
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                private
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def contents
         | 
| 48 | 
            +
                  return '' unless @contents.is_a?(String) && !@contents.empty?
         | 
| 49 | 
            +
                  @contents
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def line_number
         | 
| 53 | 
            +
                  return 0 if @line_number_1_indexed.nil?
         | 
| 54 | 
            +
                  bounded(0, @line_number_1_indexed - 1, contents.lines.size - 1)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def needle
         | 
| 58 | 
            +
                  if @needle.nil? && !contents.empty? && !@line_number_1_indexed.nil?
         | 
| 59 | 
            +
                    contents.lines(chomp: true)[line_number] || ''
         | 
| 60 | 
            +
                  elsif contents.empty? || @needle.nil?
         | 
| 61 | 
            +
                    ''
         | 
| 62 | 
            +
                  else
         | 
| 63 | 
            +
                    @needle
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def start_row_column
         | 
| 68 | 
            +
                  return @start_row_column unless @start_row_column.nil?
         | 
| 69 | 
            +
                  @start_row_column = from_index_to_row_column(contents, start_index)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def end_row_column
         | 
| 73 | 
            +
                  return @end_row_column unless @end_row_column.nil?
         | 
| 74 | 
            +
                  @end_row_column = from_index_to_row_column(contents, end_index)
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
            # Note: Everything is 0-indexed here.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module ThemeCheck
         | 
| 5 | 
            +
              module PositionHelper
         | 
| 6 | 
            +
                def from_row_column_to_index(content, row, col)
         | 
| 7 | 
            +
                  return 0 unless content.is_a?(String) && !content.empty?
         | 
| 8 | 
            +
                  return 0 unless row.is_a?(Integer) && col.is_a?(Integer)
         | 
| 9 | 
            +
                  i = 0
         | 
| 10 | 
            +
                  result = 0
         | 
| 11 | 
            +
                  safe_row = bounded(0, row, content.lines.size - 1)
         | 
| 12 | 
            +
                  lines = content.lines
         | 
| 13 | 
            +
                  line_size = lines[i].size
         | 
| 14 | 
            +
                  while i < safe_row
         | 
| 15 | 
            +
                    result += line_size
         | 
| 16 | 
            +
                    i += 1
         | 
| 17 | 
            +
                    line_size = lines[i].size
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                  result += bounded(0, col, line_size - 1)
         | 
| 20 | 
            +
                  result
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def from_index_to_row_column(content, index)
         | 
| 24 | 
            +
                  return [0, 0] unless content.is_a?(String) && !content.empty?
         | 
| 25 | 
            +
                  return [0, 0] unless index.is_a?(Integer)
         | 
| 26 | 
            +
                  safe_index = bounded(0, index, content.size - 1)
         | 
| 27 | 
            +
                  lines = content[0..safe_index].lines
         | 
| 28 | 
            +
                  row = lines.size - 1
         | 
| 29 | 
            +
                  col = lines.last.size - 1
         | 
| 30 | 
            +
                  [row, col]
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def bounded(a, x, b)
         | 
| 34 | 
            +
                  [a, [x, b].min].max
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -8,6 +8,19 @@ module ThemeCheck | |
| 8 8 |  | 
| 9 9 | 
             
                  def labels
         | 
| 10 10 | 
             
                    @tags ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/tags.yml"))
         | 
| 11 | 
            +
                      .to_set
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def tag_regex(tag)
         | 
| 15 | 
            +
                    return unless labels.include?(tag)
         | 
| 16 | 
            +
                    @tag_regexes ||= {}
         | 
| 17 | 
            +
                    @tag_regexes[tag] ||= /\A#{Liquid::TagStart}-?\s*#{tag}/m
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def liquid_tag_regex(tag)
         | 
| 21 | 
            +
                    return unless labels.include?(tag)
         | 
| 22 | 
            +
                    @tag_liquid_regexes ||= {}
         | 
| 23 | 
            +
                    @tag_liquid_regexes[tag] ||= /^\s*#{tag}/m
         | 
| 11 24 | 
             
                  end
         | 
| 12 25 | 
             
                end
         | 
| 13 26 | 
             
              end
         | 
    
        data/lib/theme_check/template.rb
    CHANGED
    
    
    
        data/lib/theme_check/theme.rb
    CHANGED
    
    | @@ -52,8 +52,13 @@ module ThemeCheck | |
| 52 52 | 
             
                  @all ||= json + liquid + assets
         | 
| 53 53 | 
             
                end
         | 
| 54 54 |  | 
| 55 | 
            -
                def []( | 
| 56 | 
            -
                   | 
| 55 | 
            +
                def [](name_or_relative_path)
         | 
| 56 | 
            +
                  case name_or_relative_path
         | 
| 57 | 
            +
                  when Pathname
         | 
| 58 | 
            +
                    all.find { |t| t.relative_path == name_or_relative_path }
         | 
| 59 | 
            +
                  else
         | 
| 60 | 
            +
                    all.find { |t| t.name == name_or_relative_path }
         | 
| 61 | 
            +
                  end
         | 
| 57 62 | 
             
                end
         | 
| 58 63 |  | 
| 59 64 | 
             
                def templates
         | 
    
        data/lib/theme_check/version.rb
    CHANGED
    
    
    
        data/lib/theme_check/visitor.rb
    CHANGED
    
    | @@ -1,12 +1,14 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 | 
             
            module ThemeCheck
         | 
| 3 3 | 
             
              class Visitor
         | 
| 4 | 
            -
                 | 
| 4 | 
            +
                attr_reader :checks
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize(checks, disabled_checks)
         | 
| 5 7 | 
             
                  @checks = checks
         | 
| 8 | 
            +
                  @disabled_checks = disabled_checks
         | 
| 6 9 | 
             
                end
         | 
| 7 10 |  | 
| 8 11 | 
             
                def visit_template(template)
         | 
| 9 | 
            -
                  @disabled_checks = DisabledChecks.new
         | 
| 10 12 | 
             
                  visit(Node.new(template.root, nil, template))
         | 
| 11 13 | 
             
                rescue Liquid::Error => exception
         | 
| 12 14 | 
             
                  exception.template_name = template.name
         | 
| @@ -29,20 +31,8 @@ module ThemeCheck | |
| 29 31 | 
             
                  @disabled_checks.update(node) if node.comment?
         | 
| 30 32 | 
             
                end
         | 
| 31 33 |  | 
| 32 | 
            -
                def visit_children(node)
         | 
| 33 | 
            -
                  node.children.each { |child| visit(child) }
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
             | 
| 36 34 | 
             
                def call_checks(method, *args)
         | 
| 37 35 | 
             
                  checks.call(method, *args)
         | 
| 38 36 | 
             
                end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                def checks
         | 
| 41 | 
            -
                  return @checks unless @disabled_checks.any?
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                  return @checks.always_enabled if @disabled_checks.all_disabled?
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                  @checks.except_for(@disabled_checks)
         | 
| 46 | 
            -
                end
         | 
| 47 37 | 
             
              end
         | 
| 48 38 | 
             
            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. | 
| 4 | 
            +
              version: 0.9.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-04 | 
| 11 | 
            +
            date: 2021-06-04 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: liquid
         | 
| @@ -72,6 +72,8 @@ files: | |
| 72 72 | 
             
            - docs/checks/CHECK_DOCS_TEMPLATE.md
         | 
| 73 73 | 
             
            - docs/checks/asset_size_css.md
         | 
| 74 74 | 
             
            - docs/checks/asset_size_javascript.md
         | 
| 75 | 
            +
            - docs/checks/asset_url_filters.md
         | 
| 76 | 
            +
            - docs/checks/content_for_header_modification.md
         | 
| 75 77 | 
             
            - docs/checks/convert_include_to_render.md
         | 
| 76 78 | 
             
            - docs/checks/default_locale.md
         | 
| 77 79 | 
             
            - docs/checks/deprecated_filter.md
         | 
| @@ -84,6 +86,7 @@ files: | |
| 84 86 | 
             
            - docs/checks/missing_template.md
         | 
| 85 87 | 
             
            - docs/checks/nested_snippet.md
         | 
| 86 88 | 
             
            - docs/checks/parser_blocking_javascript.md
         | 
| 89 | 
            +
            - docs/checks/parser_blocking_script_tag.md
         | 
| 87 90 | 
             
            - docs/checks/remote_asset.md
         | 
| 88 91 | 
             
            - docs/checks/required_directories.md
         | 
| 89 92 | 
             
            - docs/checks/required_layout_theme_object.md
         | 
| @@ -104,10 +107,13 @@ files: | |
| 104 107 | 
             
            - lib/theme_check.rb
         | 
| 105 108 | 
             
            - lib/theme_check/analyzer.rb
         | 
| 106 109 | 
             
            - lib/theme_check/asset_file.rb
         | 
| 110 | 
            +
            - lib/theme_check/bug.rb
         | 
| 107 111 | 
             
            - lib/theme_check/check.rb
         | 
| 108 112 | 
             
            - lib/theme_check/checks.rb
         | 
| 109 113 | 
             
            - lib/theme_check/checks/asset_size_css.rb
         | 
| 110 114 | 
             
            - lib/theme_check/checks/asset_size_javascript.rb
         | 
| 115 | 
            +
            - lib/theme_check/checks/asset_url_filters.rb
         | 
| 116 | 
            +
            - lib/theme_check/checks/content_for_header_modification.rb
         | 
| 111 117 | 
             
            - lib/theme_check/checks/convert_include_to_render.rb
         | 
| 112 118 | 
             
            - lib/theme_check/checks/default_locale.rb
         | 
| 113 119 | 
             
            - lib/theme_check/checks/deprecated_filter.rb
         | 
| @@ -120,6 +126,7 @@ files: | |
| 120 126 | 
             
            - lib/theme_check/checks/missing_template.rb
         | 
| 121 127 | 
             
            - lib/theme_check/checks/nested_snippet.rb
         | 
| 122 128 | 
             
            - lib/theme_check/checks/parser_blocking_javascript.rb
         | 
| 129 | 
            +
            - lib/theme_check/checks/parser_blocking_script_tag.rb
         | 
| 123 130 | 
             
            - lib/theme_check/checks/remote_asset.rb
         | 
| 124 131 | 
             
            - lib/theme_check/checks/required_directories.rb
         | 
| 125 132 | 
             
            - lib/theme_check/checks/required_layout_theme_object.rb
         | 
| @@ -138,8 +145,13 @@ files: | |
| 138 145 | 
             
            - lib/theme_check/cli.rb
         | 
| 139 146 | 
             
            - lib/theme_check/config.rb
         | 
| 140 147 | 
             
            - lib/theme_check/corrector.rb
         | 
| 148 | 
            +
            - lib/theme_check/disabled_check.rb
         | 
| 141 149 | 
             
            - lib/theme_check/disabled_checks.rb
         | 
| 150 | 
            +
            - lib/theme_check/exceptions.rb
         | 
| 142 151 | 
             
            - lib/theme_check/file_system_storage.rb
         | 
| 152 | 
            +
            - lib/theme_check/html_check.rb
         | 
| 153 | 
            +
            - lib/theme_check/html_node.rb
         | 
| 154 | 
            +
            - lib/theme_check/html_visitor.rb
         | 
| 143 155 | 
             
            - lib/theme_check/in_memory_storage.rb
         | 
| 144 156 | 
             
            - lib/theme_check/json_check.rb
         | 
| 145 157 | 
             
            - lib/theme_check/json_file.rb
         | 
| @@ -153,18 +165,21 @@ files: | |
| 153 165 | 
             
            - lib/theme_check/language_server/completion_providers/render_snippet_completion_provider.rb
         | 
| 154 166 | 
             
            - lib/theme_check/language_server/completion_providers/tag_completion_provider.rb
         | 
| 155 167 | 
             
            - lib/theme_check/language_server/constants.rb
         | 
| 168 | 
            +
            - lib/theme_check/language_server/diagnostics_tracker.rb
         | 
| 156 169 | 
             
            - lib/theme_check/language_server/document_link_engine.rb
         | 
| 157 170 | 
             
            - lib/theme_check/language_server/handler.rb
         | 
| 158 | 
            -
            - lib/theme_check/language_server/position_helper.rb
         | 
| 159 171 | 
             
            - lib/theme_check/language_server/protocol.rb
         | 
| 160 172 | 
             
            - lib/theme_check/language_server/server.rb
         | 
| 161 173 | 
             
            - lib/theme_check/language_server/tokens.rb
         | 
| 174 | 
            +
            - lib/theme_check/language_server/variable_lookup_finder.rb
         | 
| 162 175 | 
             
            - lib/theme_check/liquid_check.rb
         | 
| 163 176 | 
             
            - lib/theme_check/locale_diff.rb
         | 
| 164 177 | 
             
            - lib/theme_check/node.rb
         | 
| 165 178 | 
             
            - lib/theme_check/offense.rb
         | 
| 166 179 | 
             
            - lib/theme_check/packager.rb
         | 
| 167 180 | 
             
            - lib/theme_check/parsing_helpers.rb
         | 
| 181 | 
            +
            - lib/theme_check/position.rb
         | 
| 182 | 
            +
            - lib/theme_check/position_helper.rb
         | 
| 168 183 | 
             
            - lib/theme_check/printer.rb
         | 
| 169 184 | 
             
            - lib/theme_check/regex_helpers.rb
         | 
| 170 185 | 
             
            - lib/theme_check/releaser.rb
         | 
| @@ -203,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 203 218 | 
             
                - !ruby/object:Gem::Version
         | 
| 204 219 | 
             
                  version: '0'
         | 
| 205 220 | 
             
            requirements: []
         | 
| 206 | 
            -
            rubygems_version: 3. | 
| 221 | 
            +
            rubygems_version: 3.2.17
         | 
| 207 222 | 
             
            signing_key: 
         | 
| 208 223 | 
             
            specification_version: 4
         | 
| 209 224 | 
             
            summary: A Shopify Theme Linter
         | 
| @@ -1,27 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
            # Note: Everything is 0-indexed here.
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            module ThemeCheck
         | 
| 5 | 
            -
              module LanguageServer
         | 
| 6 | 
            -
                module PositionHelper
         | 
| 7 | 
            -
                  def from_line_column_to_index(content, row, col)
         | 
| 8 | 
            -
                    i = 0
         | 
| 9 | 
            -
                    result = 0
         | 
| 10 | 
            -
                    lines = content.lines
         | 
| 11 | 
            -
                    while i < row
         | 
| 12 | 
            -
                      result += lines[i].size
         | 
| 13 | 
            -
                      i += 1
         | 
| 14 | 
            -
                    end
         | 
| 15 | 
            -
                    result += col
         | 
| 16 | 
            -
                    result
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  def from_index_to_line_column(content, index)
         | 
| 20 | 
            -
                    lines = content[0..index].lines
         | 
| 21 | 
            -
                    row = lines.size - 1
         | 
| 22 | 
            -
                    col = lines.last.size - 1
         | 
| 23 | 
            -
                    [row, col]
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
              end
         | 
| 27 | 
            -
            end
         |