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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +28 -19
- data/config/default.yml +13 -1
- data/docs/checks/form_action.md +6 -0
- data/docs/checks/form_authenticity_token.md +22 -3
- data/docs/checks/include_in_render.md +62 -0
- data/docs/checks/translation_files_match.md +70 -0
- data/docs/checks/translation_key_exists.md +44 -0
- data/docs/platformos-check.jpg +0 -0
- data/lib/platformos_check/app.rb +13 -0
- data/lib/platformos_check/app_file.rb +10 -3
- data/lib/platformos_check/checks/convert_include_to_render.rb +41 -2
- data/lib/platformos_check/checks/form_action.rb +3 -1
- data/lib/platformos_check/checks/form_authenticity_token.rb +20 -0
- data/lib/platformos_check/checks/img_lazy_loading.rb +6 -2
- data/lib/platformos_check/checks/include_in_render.rb +45 -0
- data/lib/platformos_check/checks/invalid_args.rb +4 -1
- data/lib/platformos_check/checks/translation_files_match.rb +83 -0
- data/lib/platformos_check/checks/translation_key_exists.rb +48 -0
- data/lib/platformos_check/checks/undefined_object.rb +55 -26
- data/lib/platformos_check/checks/unreachable_code.rb +9 -9
- data/lib/platformos_check/checks/unused_assign.rb +33 -24
- data/lib/platformos_check/cli.rb +1 -1
- data/lib/platformos_check/ext/hash.rb +19 -0
- data/lib/platformos_check/graphql_file.rb +4 -0
- data/lib/platformos_check/language_server/constants.rb +18 -2
- data/lib/platformos_check/language_server/document_link_provider.rb +67 -10
- data/lib/platformos_check/language_server/document_link_providers/localize_document_link_provider.rb +38 -0
- data/lib/platformos_check/language_server/document_link_providers/theme_render_document_link_provider.rb +2 -1
- data/lib/platformos_check/language_server/document_link_providers/translation_document_link_provider.rb +36 -0
- data/lib/platformos_check/tags/graphql.rb +3 -0
- data/lib/platformos_check/translation_file.rb +40 -0
- data/lib/platformos_check/version.rb +1 -1
- data/lib/platformos_check/yaml_file.rb +7 -2
- data/lib/platformos_check.rb +1 -0
- metadata +13 -4
- data/docs/preview.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 269921738309c4cc1a1d7afef16318af6a75f050fad261530d008f53c464ce62
|
4
|
+
data.tar.gz: 0a3c1b2704f40a8244a4608ff6d9f26b0cb7757f7e93182e875edb55344c6fd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
✅
|
30
|
-
✅
|
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
|
+
|
data/docs/checks/form_action.md
CHANGED
@@ -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
|
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
|
data/lib/platformos_check/app.rb
CHANGED
@@ -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
|
-
|
38
|
-
return n if n.start_with?(prefix)
|
37
|
+
return n if n.start_with?(module_prefix)
|
39
38
|
|
40
|
-
"#{
|
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
|
-
|
13
|
-
|
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
|