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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b606fffc2525680e6d47cf1d45b3fbdd514c79cf426dfd28baaec20e1cc083f
4
- data.tar.gz: f0b9e3b0da8f41ae48e11d91ff1ccd780e0ed6cc5b8ba80694c3cd70a33e04a0
3
+ metadata.gz: 56b6a91e5ac4b1e2045b1e4fb2748e5ecb9600206f9ba07df401c1410bf494fc
4
+ data.tar.gz: b6fb1b3957ae5aecd7b2efbaa76a2e3c07390ec442f94d416ea5b20ca2cbf966
5
5
  SHA512:
6
- metadata.gz: 23ce6e8b332e57cf523db93cf14ca9c948e569703633d5b82f106e95e66dd613ab30fa448226cf4f624b24da2675179220e7fc9fe206bfa9521f722c74356ba2
7
- data.tar.gz: 22e2469eba1fc8aca4e881cfc5d0ad5ea7c16a057cdba6327310906099497b72d18dbef2d4f69d328528d6801f0abb91fac78a692f68387f7378d2c8fd3986dd
6
+ metadata.gz: e2ca68b31968949dc52240c8ee5ca607e10e063b500cda0a7b06306589849f2bc0098f1b0742f962a91a0ca282aa504acb9f7c0de6b785afff0b577b84fa6eba
7
+ data.tar.gz: c7186299a1168c5ad1e3cd6544ee8c8248b96a492e1dc82481c26a69e75fb1f04172ceb58da61e310a393fd36c9b990464542e7528810c7bea556b5b8ce9b61d
data/CHANGELOG.md CHANGED
@@ -1,4 +1,10 @@
1
1
 
2
+ v0.10.1 / 2021-06-11
3
+ ==================
4
+
5
+ * Fix LSP diagnostics not being merged properly when analyzing a single file.
6
+ Causing VSCode problems not being cleared after fixing.
7
+
2
8
  v0.10.0 / 2021-06-08
3
9
  ==================
4
10
 
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
- Under `lib/theme_check/checks`, create new Ruby file with a unique name describing what you want to check for.
39
+ Run `bundle exec rake "new_check[MyNewCheckName]"` to generate all the files required to create a new check.
40
40
 
41
- ```ruby
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
- Add the new check to `config/default.yml` to enable it. If the check is configurable, the `initialize` argument name and default values should also be duplicated inside `config/default.yml`.
43
+ We done implementing your check, add it to `config/default.yml` to enable it:
126
44
 
127
45
  ```yaml
128
- MyCheckName:
46
+ MyNewCheckName:
129
47
  enabled: true
48
+ ignore: []
130
49
  ```
131
50
 
132
- Add a corresponding test file under `test/checks`.
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
- When done, run the tests with `dev test`.
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
- [doctemplate]: /docs/checks/CHECK_DOCS_TEMPLATE.md
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 (`CheckClassName`)
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
- CheckClassName:
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 X.X.X.
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]: /lib/theme_check/checks/check_class_name.rb
47
- [docsource]: /docs/checks/check_class_name.md
46
+ [codesource]: /<%= code_source %>
47
+ [docsource]: /<%= doc_source %>
@@ -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
@@ -46,6 +46,11 @@ module ThemeCheck
46
46
  false
47
47
  end
48
48
 
49
+ def ==(other)
50
+ other.is_a?(JsonFile) && relative_path == other.relative_path
51
+ end
52
+ alias_method :eql?, :==
53
+
49
54
  private
50
55
 
51
56
  def load!
@@ -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
@@ -124,13 +124,13 @@ module ThemeCheck
124
124
 
125
125
  def ==(other)
126
126
  other.is_a?(Offense) &&
127
- check == other.check &&
127
+ code_name == other.code_name &&
128
128
  message == other.message &&
129
- template == other.template &&
130
- node == other.node &&
131
- markup == other.markup &&
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
@@ -91,6 +91,7 @@ module ThemeCheck
91
91
  def ==(other)
92
92
  other.is_a?(Template) && relative_path == other.relative_path
93
93
  end
94
+ alias_method :eql?, :==
94
95
 
95
96
  def self.parse(source)
96
97
  Liquid::Template.parse(
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- VERSION = "0.10.0"
3
+ VERSION = "0.10.1"
4
4
  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.10.0
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-08 00:00:00.000000000 Z
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/checks/CHECK_DOCS_TEMPLATE.md
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