platformos-check 0.4.8 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/README.md +28 -19
  4. data/config/default.yml +13 -1
  5. data/docs/checks/form_action.md +6 -0
  6. data/docs/checks/form_authenticity_token.md +22 -3
  7. data/docs/checks/include_in_render.md +62 -0
  8. data/docs/checks/translation_files_match.md +70 -0
  9. data/docs/checks/translation_key_exists.md +44 -0
  10. data/docs/platformos-check.jpg +0 -0
  11. data/lib/platformos_check/app.rb +13 -0
  12. data/lib/platformos_check/app_file.rb +10 -3
  13. data/lib/platformos_check/checks/convert_include_to_render.rb +41 -2
  14. data/lib/platformos_check/checks/form_action.rb +3 -1
  15. data/lib/platformos_check/checks/form_authenticity_token.rb +20 -0
  16. data/lib/platformos_check/checks/img_lazy_loading.rb +6 -2
  17. data/lib/platformos_check/checks/include_in_render.rb +45 -0
  18. data/lib/platformos_check/checks/invalid_args.rb +4 -1
  19. data/lib/platformos_check/checks/translation_files_match.rb +83 -0
  20. data/lib/platformos_check/checks/translation_key_exists.rb +48 -0
  21. data/lib/platformos_check/checks/undefined_object.rb +55 -26
  22. data/lib/platformos_check/checks/unreachable_code.rb +9 -9
  23. data/lib/platformos_check/checks/unused_assign.rb +33 -24
  24. data/lib/platformos_check/cli.rb +1 -1
  25. data/lib/platformos_check/ext/hash.rb +19 -0
  26. data/lib/platformos_check/graphql_file.rb +4 -0
  27. data/lib/platformos_check/language_server/constants.rb +18 -2
  28. data/lib/platformos_check/language_server/document_link_provider.rb +67 -10
  29. data/lib/platformos_check/language_server/document_link_providers/localize_document_link_provider.rb +38 -0
  30. data/lib/platformos_check/language_server/document_link_providers/theme_render_document_link_provider.rb +2 -1
  31. data/lib/platformos_check/language_server/document_link_providers/translation_document_link_provider.rb +36 -0
  32. data/lib/platformos_check/tags/graphql.rb +3 -0
  33. data/lib/platformos_check/translation_file.rb +40 -0
  34. data/lib/platformos_check/version.rb +1 -1
  35. data/lib/platformos_check/yaml_file.rb +7 -2
  36. data/lib/platformos_check.rb +1 -0
  37. metadata +13 -4
  38. data/docs/preview.png +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 579d15b95d0e00e65eb562778f0870bc28698bfe2f6c97ca66e7ca81a18b855c
4
- data.tar.gz: 2f6afe88f067cccc169d62a9744399b5b11294537dd8c7653ca9d5ed9165f1f3
3
+ metadata.gz: 269921738309c4cc1a1d7afef16318af6a75f050fad261530d008f53c464ce62
4
+ data.tar.gz: 0a3c1b2704f40a8244a4608ff6d9f26b0cb7757f7e93182e875edb55344c6fd9
5
5
  SHA512:
6
- metadata.gz: 2fa86abf31229208eaff48e7f95b212977682bd560234d99d2fa9b3162a33ca7139b8faad2960152951295b056ef41b834e9faa756b0627f02a14034f6d4e468
7
- data.tar.gz: 18fa38e2613faf4e31dfdf0a432e4fbe3a8ced0b18f8f194698bf73606affd770cf2589dadb852c26c19f5ec31146535e95e863d7c31ab9c8977feb67fa99a07
6
+ metadata.gz: 6de2d63705409c6b3d818f48799c5c65809c26304b64d675248c21a170562098af119d954c4d5ea77f0a09559c571e64ea10a8f3417fd406c7644999048e8916
7
+ data.tar.gz: bc35549e8dc86f7f924937a9abc7306dfb6629c05311e38b092219432b9984a855b5d1bbeda8e23503cbe903fbebeff2fb4e4538a012ec4a0dd2697a8bc6f183
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ v0.4.10 / 2024-02-19
2
+ ==================
3
+
4
+ * Add documentLink for translations (both for `| t` and `| l` filters)
5
+ * Add TranslationKeyExists, TranslationFilesMatch offenses to warn about issues with missing translation or inconsistency between multiple language translation files
6
+
7
+ v0.4.9 / 2024-01-10
8
+ ==================
9
+
10
+ * Skip FormAuthenticityToken check for GET forms
11
+ * Skip FormAuthenticityToken for action which is not relative path
12
+ * Fix FormAction to not report offenses on valid scenarios
13
+ * UnusedAssign will not automatically remove assign if it might change the business logic (which is a scenario when filters modifying objects are used)
14
+ * UnusedAssign will automatically rename result of background tag if variable not used
15
+ * Fix reporting UndefinedObject's missing argument offenses when the same partial is used multiple times (previously offenses where displayed only for the last render)
16
+ * Add autocorrector for UndefinedObject's missing argument error (explicitly provide null)
17
+ * Add autocorrector for ImgLazyLoading
18
+ * ConvertIncludeToRender will not report offense as autocorrect
19
+ * Improve inline GraphQL syntax check to raise error if result variable not provided
20
+ * Add autocorrector for UndefinedObject (Unused Argument offense) (FIXME: for N unused arguments in the same line it needs to be invoked N times)
21
+ * Add autocorrector for InvalidArgs - remove duplicates arguments
22
+ * Do not report ConvertIncludeToRender offenses for valid use cases (using `break` and using variable as a template name)
23
+ * Add IncludeInRender check
24
+ * Improve autocorrector for UndefinedObject's missing argument error - if variable is defined, it will be passed instead of hardcoding null
25
+ * Re-enable autocorrector for ConvertIncludeToRender
26
+ * Make UndefinedObject more clever - it will report undefined object if variable is used before declaration
27
+
1
28
  v0.4.8 / 2023-12-20
2
29
  ==================
3
30
 
data/README.md CHANGED
@@ -8,29 +8,29 @@ PlatformOS Check is a tool that helps you follow platformOS recommendations & be
8
8
 
9
9
  PlatformOS Check currently checks for the following:
10
10
 
11
- ✅ Liquid syntax errors
12
- ✅ JSON syntax errors
13
- ✅ Missing partials and graphqls
14
- ✅ Unused `{% assign ... %}`
15
- ✅ Unused partials
16
- ✅ Template length
17
- ✅ Deprecated tags
18
- ✅ Unknown tags
19
- ✅ Unknown filters
20
- ✅ Missing or extra spaces inside `{% ... %}` and `{{ ... }}`
21
- ✅ Using several `{% ... %}` instead of `{% liquid ... %}`
22
- ✅ Undefined objects
23
- ✅ Deprecated filters
24
- ✅ Missing `platformos-check-enable` comment
25
- ✅ Invalid arguments provided to `{% graphql %}` tags
11
+ ✅ Liquid syntax errors
12
+ ✅ JSON syntax errors
13
+ ✅ Missing partials and graphqls
14
+ ✅ Unused variables (via `{% assign var = ... %}`, {% function var = ... %} etc.)
15
+ ✅ Unused partials
16
+ ✅ Template length
17
+ ✅ Deprecated tags
18
+ ✅ Unknown tags
19
+ ✅ Unknown filters
20
+ ✅ Missing or extra spaces inside `{% ... %}` and `{{ ... }}`
21
+ ✅ Using several `{% ... %}` instead of `{% liquid ... %}`
22
+ ✅ Undefined objects
23
+ ✅ Deprecated filters
24
+ ✅ Missing `platformos-check-enable` comment
25
+ ✅ Invalid arguments provided to `{% graphql %}` tags
26
+ ✅ Missing `authenticity_token` in `<form>`
27
+ ✅ Unreachable code
26
28
 
27
29
  As well as checks that prevent easy to spot performance problems:
28
30
 
29
- Use of [parser-blocking](/docs/checks/parser_blocking_javascript.md) JavaScript
30
- [Use of non-platformOS domains for assets](/docs/checks/remote_asset.md)
31
+ [GraphQL in for loop](/docs/checks/graphql_in_for_loop.md)
32
+ ✅ Use of [parser-blocking](/docs/checks/parser_blocking_javascript.md) JavaScript
31
33
  ✅ [Missing width and height attributes on `img` tags](/docs/checks/img_width_and_height.md)
32
- ✅ [Too much JavaScript](/docs/checks/asset_size_javascript.md)
33
- ✅ [Too much CSS](/docs/checks/asset_size_css.md)
34
34
 
35
35
  For detailed descriptions and configuration options, [take a look at the complete list.](/docs/checks/)
36
36
 
@@ -52,12 +52,21 @@ With more to come! Suggestions welcome ([create an issue](https://github.com/Pla
52
52
  ### Install ruby and platform-check gem
53
53
 
54
54
  1. Download the latest version of Ruby - https://www.ruby-lang.org/en/documentation/installation/
55
+
56
+ Verify that you've installed at least version 3.2:
57
+
58
+ `ruby -v`
59
+
60
+ ⚠️ **Note:** You might need to restart the terminal after installing.
61
+ ⚠️ **Note:*** Please make sure you install ruby for your user, not the root
62
+
55
63
  2. Install platformos-check gem
56
64
 
57
65
  `gem install platformos-check`
58
66
 
59
67
  You can verify the installation was successful by invoking `platformos-check --version`. If you chose this method, use `platformos-check-language-server` as a path to your language server instead of `/Users/<username/platformos-check-language-server`
60
68
 
69
+ ⚠️ **Note:*** Please make sure you install the gem for your user, not the root - i.e. without `sudo`
61
70
 
62
71
  ### Using Docker
63
72
 
data/config/default.yml CHANGED
@@ -15,6 +15,10 @@ ConvertIncludeToRender:
15
15
  enabled: true
16
16
  ignore: []
17
17
 
18
+ IncludeInRender:
19
+ enabled: true
20
+ ignore: []
21
+
18
22
  LiquidTag:
19
23
  enabled: true
20
24
  ignore: []
@@ -69,7 +73,6 @@ ValidYaml:
69
73
  UndefinedObject:
70
74
  enabled: true
71
75
  ignore: []
72
- config_type: :default
73
76
 
74
77
  DeprecatedFilter:
75
78
  enabled: true
@@ -107,7 +110,16 @@ HtmlParsingError:
107
110
  enabled: true
108
111
  ignore: []
109
112
 
113
+ TranslationKeyExists:
114
+ enabled: true
115
+ ignore: []
116
+
117
+ TranslationFilesMatch:
118
+ enabled: true
119
+ ignore: []
120
+
110
121
  ParseJsonFormat:
111
122
  enabled: false
112
123
  start_level: 0
113
124
  indent: ' '
125
+
@@ -30,6 +30,12 @@ This check is aimed at ensuring you have not forgotten to start the path with /.
30
30
  </form>
31
31
  ```
32
32
 
33
+ ```liquid
34
+ <form action="https://example.com/external">
35
+ ...
36
+ </form>
37
+ ```
38
+
33
39
  ## Check Options
34
40
 
35
41
  The default configuration for this check is the following:
@@ -3,7 +3,7 @@
3
3
  In platformOS all POST/PATCH/PUT/DELETE requests are protected from [CSRF Attacks][csrf-attack] through [authenticity_token][page-csrf]
4
4
  Form action defines the endpoint to which browser will make a request after submitting it.
5
5
 
6
- As a general rule you should include hidden input `<input type="hidden" name="authenticity_token" value="{{ context.authenticity_token }}">` in every form. Missing it will result in session invalidation and any logged in user will be automatically logged out.
6
+ As a general rule you should include hidden input `<input type="hidden" name="authenticity_token" value="{{ context.authenticity_token }}">` in every form. Missing it will result in session invalidation and the logged in user will be automatically logged out.
7
7
 
8
8
  ## Check Details
9
9
 
@@ -12,18 +12,37 @@ This check is aimed at ensuring you have not forgotten to include authenticity_t
12
12
  :-1: Examples of **incorrect** code for this check:
13
13
 
14
14
  ```liquid
15
- <form action="dummy/create">
15
+ <form action="/dummy/create" method="post">
16
16
  </form>
17
17
  ```
18
18
 
19
19
  :+1: Examples of **correct** code for this check:
20
20
 
21
+ With token:
21
22
  ```liquid
22
- <form action="/dummy/create">
23
+ <form action="/dummy/create" method="post">
23
24
  <input type="hidden" name="authenticity_token" value="{{ context.authenticity_token }}">
24
25
  </form>
25
26
  ```
26
27
 
28
+ For GET request:
29
+ ```liquid
30
+ <form action="/dummy/create">
31
+ </form>
32
+ ```
33
+
34
+ For external request:
35
+ ```liquid
36
+ <form action="https://example.com/dummy/create" method="post">
37
+ </form>
38
+ ```
39
+
40
+ For parameterized request:
41
+ ```liquid
42
+ <form action="{{ context.constants.MY_REQUEST_URL }}" method="post">
43
+ </form>
44
+ ```
45
+
27
46
  ## Check Options
28
47
 
29
48
  The default configuration for this check is the following:
@@ -0,0 +1,62 @@
1
+ # Reports usage of `include` tag inside `render` (`IncludeInRender`)
2
+
3
+ Runtime error is used when `include` tag is used inside `render` tag.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at eliminating the use of `include` tags `render` tag.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {% liquid
13
+ # app/views/pages/index.liquid
14
+ render 'foo'
15
+ %}
16
+ ```liquid
17
+ {% liquid
18
+ # app/views/partials/foo.liquid
19
+ include 'bar'
20
+ %}
21
+ ```
22
+
23
+ :+1: Examples of **correct** code for this check:
24
+
25
+ ```liquid
26
+ {% liquid
27
+ # app/views/pages/index.liquid
28
+ render 'foo'
29
+ %}
30
+ ```liquid
31
+ {% liquid
32
+ # app/views/partials/foo.liquid
33
+ render 'bar'
34
+ %}
35
+ ```
36
+
37
+ ## Check Options
38
+
39
+ The default configuration for this check is the following:
40
+
41
+ ```yaml
42
+ IncludeInRender:
43
+ enabled: true
44
+ ```
45
+
46
+ ## When Not To Use It
47
+
48
+ It is discouraged to disable this rule.
49
+
50
+ ## Version
51
+
52
+ This check has been introduced in PlatformOS Check 0.4.9.
53
+
54
+ ## Resources
55
+
56
+ - [Deprecated Tags Reference][deprecated]
57
+ - [Rule Source][codesource]
58
+ - [Documentation Source][docsource]
59
+
60
+ [deprecated]: https://documentation.platformos.com/api-reference/liquid/include
61
+ [codesource]: /lib/platformos_check/checks/convert_include_to_render.rb
62
+ [docsource]: /docs/checks/convert_include_to_render.md
@@ -0,0 +1,70 @@
1
+ # Translation Files Match (`TranslationFilesMatch`)
2
+
3
+ Checks if translation files for different language have the same keys.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at avoiding inconsistences between translation files to avoid errors hard to spot and make maintenance easier.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```yaml
12
+ # app/translations/en/item.yml
13
+ en:
14
+ app:
15
+ item:
16
+ title: "Item"
17
+ description: "Description"
18
+
19
+ # app/translations/de/item.yml
20
+ en:
21
+ app:
22
+ item:
23
+ description: "Beschreibung"
24
+ ```
25
+
26
+ Missing "title" in de/item.yml
27
+
28
+ :+1: Examples of **correct** code for this check:
29
+
30
+ ```yaml
31
+ # app/translations/en/item.yml
32
+ en:
33
+ app:
34
+ item:
35
+ title: "Item"
36
+ description: "Description"
37
+
38
+ # app/translations/de/item.yml
39
+ en:
40
+ app:
41
+ item:
42
+ title: "Artikel"
43
+ description: "Beschreibung"
44
+ ```
45
+
46
+ ## Check Options
47
+
48
+ The default configuration for this check is the following:
49
+
50
+ ```yaml
51
+ TranslationFilesMatch:
52
+ enabled: true
53
+ ```
54
+
55
+ ## When Not To Use It
56
+
57
+ There should be no cases where disabling this rule is needed. For keys that are set via UI, and hence should not be part of the codebase,
58
+ use proper configuration option in [app/config.yml](https://documentation.platformos.com/developer-guide/platformos-workflow/codebase/config)
59
+
60
+ ## Version
61
+
62
+ This check has been introduced in PlatformOS Check 0.4.10.
63
+
64
+ ## Resources
65
+
66
+ - [Rule Source][codesource]
67
+ - [Documentation Source][docsource]
68
+
69
+ [codesource]: /lib/platformos_check/checks/translation_files_match.rb
70
+ [docsource]: /docs/checks/translation_files_match.md
@@ -0,0 +1,44 @@
1
+ # Translation Key Exists (`TranslationKeyExists`)
2
+
3
+ Checks if translation key is defined in the default language
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at avoiding missing translation error.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {{ 'undefined.key' | t }}
13
+ ```
14
+
15
+ :+1: Examples of **correct** code for this check:
16
+
17
+ ```liquid
18
+ {{ 'defined.key' | t }}
19
+
20
+ ## Check Options
21
+
22
+ The default configuration for this check is the following:
23
+
24
+ ```yaml
25
+ TranslationKeyExists:
26
+ enabled: true
27
+ ```
28
+
29
+ ## When Not To Use It
30
+
31
+ There should be no cases where disabling this rule is needed. For keys that are set via UI, and hence should not be part of the codebase,
32
+ use proper configuration option in [app/config.yml](https://documentation.platformos.com/developer-guide/platformos-workflow/codebase/config)
33
+
34
+ ## Version
35
+
36
+ This check has been introduced in PlatformOS Check 0.4.10.
37
+
38
+ ## Resources
39
+
40
+ - [Rule Source][codesource]
41
+ - [Documentation Source][docsource]
42
+
43
+ [codesource]: /lib/platformos_check/checks/translation_key_exists.rb
44
+ [docsource]: /docs/checks/translation_key_exists.md
Binary file
@@ -39,6 +39,8 @@ module PlatformosCheck
39
39
  CONFIG_REGEX => ConfigFile
40
40
  }
41
41
 
42
+ DEFAULT_LANGUAGE = 'en'
43
+
42
44
  attr_reader :storage, :grouped_files
43
45
 
44
46
  def initialize(storage)
@@ -139,5 +141,16 @@ module PlatformosCheck
139
141
  all.find { |t| t.relative_path.to_s == name_or_relative_path }
140
142
  end
141
143
  end
144
+
145
+ def default_language
146
+ DEFAULT_LANGUAGE
147
+ end
148
+
149
+ def translations_hash
150
+ @translations_hash ||= translations.each_with_object({}) do |translation_file, hash|
151
+ hash.deep_merge!(translation_file.content)
152
+ hash
153
+ end
154
+ end
142
155
  end
143
156
  end
@@ -34,16 +34,19 @@ module PlatformosCheck
34
34
  n = remove_extension(relative_path.sub(dir_prefix, '')).to_s
35
35
  return n if module_name.nil?
36
36
 
37
- prefix = "modules#{File::SEPARATOR}#{module_name}#{File::SEPARATOR}"
38
- return n if n.start_with?(prefix)
37
+ return n if n.start_with?(module_prefix)
39
38
 
40
- "#{prefix}#{n}"
39
+ "#{module_prefix}#{n}"
41
40
  end
42
41
 
43
42
  def dir_prefix
44
43
  nil
45
44
  end
46
45
 
46
+ def module_prefix
47
+ @module_prefix ||= "modules#{File::SEPARATOR}#{module_name}#{File::SEPARATOR}"
48
+ end
49
+
47
50
  def module_name
48
51
  @module_name ||= begin
49
52
  dir_names = @relative_path.split(File::SEPARATOR).reject(&:empty?)
@@ -85,6 +88,10 @@ module PlatformosCheck
85
88
  false
86
89
  end
87
90
 
91
+ def translation?
92
+ false
93
+ end
94
+
88
95
  def ==(other)
89
96
  other.is_a?(self.class) && relative_path == other.relative_path
90
97
  end
@@ -3,15 +3,54 @@
3
3
  module PlatformosCheck
4
4
  # Recommends replacing `include` for `render`
5
5
  class ConvertIncludeToRender < LiquidCheck
6
+ RENDER_INCOMPATIBLE_TAGS = %w[break include].freeze
7
+
6
8
  severity :suggestion
7
9
  category :liquid
8
10
  doc docs_url(__FILE__)
9
11
 
12
+ def initialize
13
+ @processed_files = {}
14
+ end
15
+
10
16
  def on_include(node)
17
+ return if allowed_usecase?(node)
18
+
11
19
  add_offense("`include` is deprecated - convert it to `render`", node:) do |corrector|
12
- # We need to fix #445 and pass the variables from the context or don't replace at all.
13
- # corrector.replace(node, "render \'#{node.value.template_name_expr}\' ")
20
+ match = node.markup.match(/(?<include>include\s*)/)
21
+ corrector.replace(node, node.markup.sub(match[:include], 'render '), node.start_index...node.end_index)
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def allowed_usecase?(node)
28
+ return true if name_is_variable?(node)
29
+ return true if include_node_contains_render_incompatible_tag?(root_node_from_include(node.value.template_name_expr))
30
+
31
+ false
32
+ end
33
+
34
+ def name_is_variable?(node)
35
+ !node.value.template_name_expr.is_a?(String)
36
+ end
37
+
38
+ def include_node_contains_render_incompatible_tag?(node)
39
+ return false if node.nil?
40
+
41
+ node.nodelist.any? do |n|
42
+ if RENDER_INCOMPATIBLE_TAGS.include?(n.respond_to?(:tag_name) && n.tag_name)
43
+ true
44
+ elsif n.respond_to?(:nodelist) && n.nodelist
45
+ include_node_contains_render_incompatible_tag?(n)
46
+ else
47
+ false
48
+ end
14
49
  end
15
50
  end
51
+
52
+ def root_node_from_include(path)
53
+ @platformos_app.grouped_files[PlatformosCheck::PartialFile][path]&.parse&.root
54
+ end
16
55
  end
17
56
  end
@@ -6,11 +6,13 @@ module PlatformosCheck
6
6
  categories :html
7
7
  doc docs_url(__FILE__)
8
8
 
9
+ VALID_ACTION_START = ['/', '{%', '{{', '#', 'http'].freeze
10
+
9
11
  def on_form(node)
10
12
  action = node.attributes["action"]&.strip
11
13
  return if action.nil?
12
14
  return if action.empty?
13
- return if action.start_with?('/', '{{')
15
+ return if action.start_with?(*VALID_ACTION_START)
14
16
 
15
17
  add_offense("Use action=\"/#{action}\" (start with /) to ensure the form can be submitted multiple times in case of validation errors", node:)
16
18
  end
@@ -9,6 +9,9 @@ module PlatformosCheck
9
9
  AUTHENTICITY_TOKEN_VALUE = /\A\s*{{\s*context\.authenticity_token\s*}}\s*\z/
10
10
 
11
11
  def on_form(node)
12
+ return if method_is_get(node.attributes['method'])
13
+ return unless action_is_relative_url(node.attributes['action'])
14
+
12
15
  authenticity_toke_inputs = node.children.select { |c| c.name == 'input' && c.attributes['name'] == 'authenticity_token' && c.attributes['value']&.match?(AUTHENTICITY_TOKEN_VALUE) }
13
16
  return if authenticity_toke_inputs.size == 1
14
17
  return add_offense('Duplicated authenticity_token inputs', node:) if authenticity_toke_inputs.size > 1
@@ -17,5 +20,22 @@ module PlatformosCheck
17
20
  corrector.insert_after(node, "\n<input type=\"hidden\" name=\"authenticity_token\" value=\"{{ context.authenticity_token }}\">")
18
21
  end
19
22
  end
23
+
24
+ protected
25
+
26
+ def method_is_get(method)
27
+ return true if method.nil?
28
+
29
+ method = method.downcase.strip
30
+ return true if method == ''
31
+
32
+ method == 'get'
33
+ end
34
+
35
+ def action_is_relative_url(action)
36
+ return true if action.nil?
37
+
38
+ action.lstrip[0] == '/'
39
+ end
20
40
  end
21
41
  end
@@ -6,13 +6,17 @@ module PlatformosCheck
6
6
  categories :html, :performance
7
7
  doc docs_url(__FILE__)
8
8
 
9
- ACCEPTED_LOADING_VALUES = %w[lazy eager]
9
+ ACCEPTED_LOADING_VALUES = Set.new(%w[lazy eager]).freeze
10
+ LOADING_DEFAULT_ATTRIBUTE = ' loading="eager"'
10
11
 
11
12
  def on_img(node)
12
13
  loading = node.attributes["loading"]&.downcase
13
14
  return if ACCEPTED_LOADING_VALUES.include?(loading)
14
15
 
15
- add_offense("Use loading=\"eager\" for images visible in the viewport on load and loading=\"lazy\" for others", node:)
16
+ add_offense("Use loading=\"eager\" for images visible in the viewport on load and loading=\"lazy\" for others", node:) do |corrector|
17
+ start_pos = node.start_index + node.markup.index('>')
18
+ corrector.insert_after(node, LOADING_DEFAULT_ATTRIBUTE, start_pos...start_pos)
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlatformosCheck
4
+ # Recommends replacing `include` for `render`
5
+ class IncludeInRender < LiquidCheck
6
+ severity :error
7
+ category :liquid
8
+ doc docs_url(__FILE__)
9
+
10
+ def initialize
11
+ @processed_files = {}
12
+ end
13
+
14
+ def on_render(node)
15
+ path = node.value.template_name_expr
16
+ return unless include_tag_in_render?(root_node_for_render(path))
17
+
18
+ add_offense("`render` context does not allow to use `include`, either remove all includes from `#{app_file_for_path(path).relative_path}` or change `render` to `include`", node:)
19
+ end
20
+
21
+ protected
22
+
23
+ def include_tag_in_render?(node)
24
+ return false if node.nil?
25
+
26
+ node.nodelist.any? do |n|
27
+ if n.respond_to?(:tag_name) && n.tag_name == 'include'
28
+ true
29
+ elsif n.respond_to?(:nodelist) && n.nodelist
30
+ include_tag_in_render?(n)
31
+ else
32
+ false
33
+ end
34
+ end
35
+ end
36
+
37
+ def root_node_for_render(path)
38
+ app_file_for_path(path)&.parse&.root
39
+ end
40
+
41
+ def app_file_for_path(path)
42
+ @platformos_app.grouped_files[PlatformosCheck::PartialFile][path]
43
+ end
44
+ end
45
+ end
@@ -42,7 +42,10 @@ module PlatformosCheck
42
42
 
43
43
  def add_duplicated_key_offense(node)
44
44
  node.value.duplicated_attrs.each do |duplicated_arg|
45
- add_offense("Duplicated argument `#{duplicated_arg}`", node:)
45
+ add_offense("Duplicated argument `#{duplicated_arg}`", node:) do |corrector|
46
+ match = node.markup.match(/(?<attribute>,?\s*#{duplicated_arg}\s*:\s*#{Liquid::QuotedFragment})\s*/)
47
+ corrector.replace(node, node.markup.sub(match[:attribute], ''), node.start_index...node.end_index)
48
+ end
46
49
  end
47
50
  end
48
51
  end