-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add new rule django_block_translate_trimmed #137
Open
lb-
wants to merge
1
commit into
thibaudcolas:main
Choose a base branch
from
lb-:feature/block-translate-must-use-trimmed
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+294
−3
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
69 changes: 69 additions & 0 deletions
69
curlylint/rules/django_block_translate_trimmed/django_block_translate_trimmed.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
from curlylint import ast | ||
from curlylint.check_node import CheckNode, build_tree | ||
from curlylint.issue import Issue | ||
|
||
DJANGO_FORMS_RENDERING = "django_block_translate_trimmed" | ||
|
||
RULE = { | ||
"id": "django_block_translate_trimmed", | ||
"type": "internationalisation", | ||
"docs": { | ||
"description": "Enforces the use of Django’s `trimmed` option when using `blocktranslate`/`blocktrans` so that translations do not contain leading or trailing whitespace.", | ||
"url": "https://www.curlylint.org/docs/rules/django_block_translate_trimmed", | ||
"impact": "Serious", | ||
"tags": ["cat:language"], | ||
"resources": [ | ||
"[Django translations](https://docs.djangoproject.com/en/stable/topics/i18n/translation/)", | ||
], | ||
}, | ||
"schema": { | ||
"$schema": "http://json-schema.org/draft/2019-09/schema#", | ||
"oneOf": [ | ||
{ | ||
"const": True, | ||
"title": "Template tags of blocktranslate or blocktrans must use the trimmed option", | ||
"examples": [True], | ||
} | ||
], | ||
}, | ||
} | ||
|
||
BLOCK_NAMES = ["blocktranslate", "blocktrans"] | ||
|
||
|
||
def find_valid(node, file): | ||
|
||
if isinstance(node.value, ast.JinjaElement): | ||
for part in node.value.parts: | ||
|
||
tag = part.tag | ||
|
||
if tag.name in BLOCK_NAMES: | ||
if "trimmed" not in tag.content.split(" "): | ||
return [ | ||
Issue.from_node( | ||
file, | ||
node, | ||
f"`{tag}` must use the `trimmed` option", | ||
DJANGO_FORMS_RENDERING, | ||
) | ||
] | ||
|
||
if not node.children: | ||
return [] | ||
|
||
return sum( | ||
(find_valid(child, file) for child in node.children), | ||
[], | ||
) | ||
|
||
|
||
def django_block_translate_trimmed(file, target): | ||
root = CheckNode(None) | ||
build_tree(root, file.tree) | ||
src = file.source.lower() | ||
|
||
if "blocktrans" in src or "blocktranslate" in src: | ||
return find_valid(root, file) | ||
|
||
return [] |
97 changes: 97 additions & 0 deletions
97
curlylint/rules/django_block_translate_trimmed/django_block_translate_trimmed_test.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
[ | ||
{ | ||
"label": "Using blocktranslate with trimmed", | ||
"template": "{% blocktranslate trimmed %} some value {% endblocktranslate %}", | ||
"example": true, | ||
"config": true, | ||
"output": [] | ||
}, | ||
{ | ||
"label": "Using blocktranslate without trimmed", | ||
"template": "{% blocktranslate %} some value {% endblocktranslate %}", | ||
"example": true, | ||
"config": true, | ||
"output": [ | ||
{ | ||
"file": "test.html", | ||
"column": 1, | ||
"line": 1, | ||
"code": "django_block_translate_trimmed", | ||
"message": "`{% blocktranslate %}` must use the `trimmed` option" | ||
} | ||
] | ||
}, | ||
{ | ||
"label": "Using blocktrans with trimmed", | ||
"template": "{% blocktrans trimmed %} some value {% endblocktrans %}", | ||
"example": true, | ||
"config": true, | ||
"output": [] | ||
}, | ||
{ | ||
"label": "Using blocktrans without trimmed", | ||
"template": "{% blocktrans %} some value {% endblocktrans %}", | ||
"example": true, | ||
"config": true, | ||
"output": [ | ||
{ | ||
"file": "test.html", | ||
"column": 1, | ||
"line": 1, | ||
"code": "django_block_translate_trimmed", | ||
"message": "`{% blocktrans %}` must use the `trimmed` option" | ||
} | ||
] | ||
}, | ||
{ | ||
"label": "Using blocktranslate with trimmed and other options", | ||
"template": "{% blocktranslate trimmed with time_period=revision.created_at|timesince_simple %} some value {% endblocktranslate %}", | ||
"example": true, | ||
"config": true, | ||
"output": [] | ||
}, | ||
{ | ||
"label": "Using blocktranslate without trimmed but with other options", | ||
"template": "{% blocktranslate count counter=list|length %}\n some value\n{% endblocktranslate %}", | ||
"example": true, | ||
"config": true, | ||
"output": [ | ||
{ | ||
"file": "test.html", | ||
"column": 1, | ||
"line": 1, | ||
"code": "django_block_translate_trimmed", | ||
"message": "`{% blocktranslate count counter=list|length %}` must use the `trimmed` option" | ||
} | ||
] | ||
}, | ||
{ | ||
"label": "Using blocktrans with other options", | ||
"template": "{% blocktrans trimmed with book_t=book|title %} some value {% endblocktrans %}", | ||
"example": true, | ||
"config": true, | ||
"output": [] | ||
}, | ||
{ | ||
"label": "Using blocktrans with other options, with trimmed after these options", | ||
"template": "{% blocktrans with book_t=book|title context trimmed %} some value {% endblocktrans %}", | ||
"example": false, | ||
"config": true, | ||
"output": [] | ||
}, | ||
{ | ||
"label": "Using blocktrans without trimmed but with other options", | ||
"template": "{% blocktrans with book_t=book|title %}\nsome value\n{% endblocktrans %}", | ||
"example": true, | ||
"config": true, | ||
"output": [ | ||
{ | ||
"file": "test.html", | ||
"column": 1, | ||
"line": 1, | ||
"code": "django_block_translate_trimmed", | ||
"message": "`{% blocktrans with book_t=book|title %}` must use the `trimmed` option" | ||
} | ||
] | ||
} | ||
] |
10 changes: 10 additions & 0 deletions
10
curlylint/rules/django_block_translate_trimmed/django_block_translate_trimmed_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import unittest | ||
|
||
from curlylint.rules.rule_test_case import RulesTestMeta | ||
|
||
from .django_block_translate_trimmed import django_block_translate_trimmed | ||
|
||
|
||
class TestRule(unittest.TestCase, metaclass=RulesTestMeta): | ||
fixtures = __file__.replace(".py", ".json") | ||
rule = django_block_translate_trimmed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
--- | ||
# This file is auto-generated, please do not update manually. | ||
id: django_block_translate_trimmed | ||
title: django_block_translate_trimmed | ||
custom_edit_url: https://github.com/thibaudcolas/curlylint/edit/main/curlylint/rules/django_block_translate_trimmed/django_block_translate_trimmed.py | ||
--- | ||
|
||
import Tabs from "@theme/Tabs"; | ||
import TabItem from "@theme/TabItem"; | ||
import CodeSnippet from "@theme/CodeSnippet"; | ||
|
||
> Enforces the use of Django’s `trimmed` option when using `blocktranslate`/`blocktrans` so that translations do not contain leading or trailing whitespace. | ||
> | ||
> User impact: **Serious** | ||
|
||
This rule supports the following configuration: | ||
|
||
<Tabs | ||
groupId="config-language" | ||
defaultValue="toml" | ||
values={[ | ||
{ label: "TOML", value: "toml" }, | ||
{ label: "Shell", value: "shell" }, | ||
]} | ||
> | ||
<TabItem value="toml"> | ||
<CodeSnippet | ||
snippet={`# Template tags of blocktranslate or blocktrans must use the trimmed option\ndjango_block_translate_trimmed = true`} | ||
annotations={[]} | ||
lang="toml" | ||
/> | ||
</TabItem> | ||
<TabItem value="shell"> | ||
<CodeSnippet | ||
snippet={`# Template tags of blocktranslate or blocktrans must use the trimmed option\ncurlylint --rule 'django_block_translate_trimmed: true' .`} | ||
annotations={[]} | ||
lang="shell" | ||
/> | ||
</TabItem> | ||
</Tabs> | ||
|
||
## Success | ||
|
||
<Tabs | ||
groupId="config-language" | ||
defaultValue="toml" | ||
values={[ | ||
{ label: "TOML", value: "toml" }, | ||
{ label: "Shell", value: "shell" }, | ||
]} | ||
> | ||
<TabItem value="toml"> | ||
<CodeSnippet | ||
snippet={`<!-- Good: Using blocktranslate with trimmed -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktranslate trimmed %} some value {% endblocktranslate %}\n<!-- Good: Using blocktrans with trimmed -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktrans trimmed %} some value {% endblocktrans %}\n<!-- Good: Using blocktranslate with trimmed and other options -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktranslate trimmed with time_period=revision.created_at|timesince_simple %} some value {% endblocktranslate %}\n<!-- Good: Using blocktrans with other options -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktrans trimmed with book_t=book|title %} some value {% endblocktrans %}`} | ||
annotations={[]} | ||
lang="html" | ||
/> | ||
</TabItem> | ||
<TabItem value="shell"> | ||
<CodeSnippet | ||
snippet={`<!-- Good: Using blocktranslate with trimmed -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktranslate trimmed %} some value {% endblocktranslate %}\n<!-- Good: Using blocktrans with trimmed -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktrans trimmed %} some value {% endblocktrans %}\n<!-- Good: Using blocktranslate with trimmed and other options -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktranslate trimmed with time_period=revision.created_at|timesince_simple %} some value {% endblocktranslate %}\n<!-- Good: Using blocktrans with other options -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktrans trimmed with book_t=book|title %} some value {% endblocktrans %}`} | ||
annotations={[]} | ||
lang="html" | ||
/> | ||
</TabItem> | ||
</Tabs> | ||
|
||
## Fail | ||
|
||
<Tabs | ||
groupId="config-language" | ||
defaultValue="toml" | ||
values={[ | ||
{ label: "TOML", value: "toml" }, | ||
{ label: "Shell", value: "shell" }, | ||
]} | ||
> | ||
<TabItem value="toml"> | ||
<CodeSnippet | ||
snippet={`<!-- Bad: Using blocktranslate without trimmed -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktranslate %} some value {% endblocktranslate %}\n<!-- Bad: Using blocktrans without trimmed -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktrans %} some value {% endblocktrans %}\n<!-- Bad: Using blocktranslate without trimmed but with other options -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktranslate count counter=list|length %} | ||
some value | ||
{% endblocktranslate %}\n<!-- Bad: Using blocktrans without trimmed but with other options -->\n<!-- django_block_translate_trimmed = true -->\n{% blocktrans with book_t=book|title %} | ||
some value | ||
{% endblocktrans %}\n\n`} | ||
annotations={[{"file": "test.html", "column": 1, "line": 3, "code": "django_block_translate_trimmed", "message": "`{% blocktranslate %}` must use the `trimmed` option"}, {"file": "test.html", "column": 1, "line": 6, "code": "django_block_translate_trimmed", "message": "`{% blocktrans %}` must use the `trimmed` option"}, {"file": "test.html", "column": 1, "line": 9, "code": "django_block_translate_trimmed", "message": "`{% blocktranslate count counter=list|length %}` must use the `trimmed` option"}, {"file": "test.html", "column": 1, "line": 12, "code": "django_block_translate_trimmed", "message": "`{% blocktrans with book_t=book|title %}` must use the `trimmed` option"}]} | ||
lang="html" | ||
/> | ||
</TabItem> | ||
<TabItem value="shell"> | ||
<CodeSnippet | ||
snippet={`<!-- Bad: Using blocktranslate without trimmed -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktranslate %} some value {% endblocktranslate %}\n<!-- Bad: Using blocktrans without trimmed -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktrans %} some value {% endblocktrans %}\n<!-- Bad: Using blocktranslate without trimmed but with other options -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktranslate count counter=list|length %} | ||
some value | ||
{% endblocktranslate %}\n<!-- Bad: Using blocktrans without trimmed but with other options -->\n<!-- curlylint --rule 'django_block_translate_trimmed: true' . -->\n{% blocktrans with book_t=book|title %} | ||
some value | ||
{% endblocktrans %}\n\n`} | ||
annotations={[{"file": "test.html", "column": 1, "line": 3, "code": "django_block_translate_trimmed", "message": "`{% blocktranslate %}` must use the `trimmed` option"}, {"file": "test.html", "column": 1, "line": 6, "code": "django_block_translate_trimmed", "message": "`{% blocktrans %}` must use the `trimmed` option"}, {"file": "test.html", "column": 1, "line": 9, "code": "django_block_translate_trimmed", "message": "`{% blocktranslate count counter=list|length %}` must use the `trimmed` option"}, {"file": "test.html", "column": 1, "line": 12, "code": "django_block_translate_trimmed", "message": "`{% blocktrans with book_t=book|title %}` must use the `trimmed` option"}]} | ||
lang="html" | ||
/> | ||
</TabItem> | ||
</Tabs> | ||
|
||
## Resources | ||
|
||
- [Django translations](https://docs.djangoproject.com/en/stable/topics/i18n/translation/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: this re-order is required because the approach is greedy, the first match is used.
So if we want to ensure that
blocktranslate
gets pulled in and it does not get treated asblocktrans
orblock
we need to ensure that it is first.Hope that makes sense.
Also blocktranslate is the Django 4.0 variant.