Skip to content
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

feat(eslint-plugin-template): add require-localize-metadata rule #844

Merged

Conversation

abaran30
Copy link
Contributor

@abaran30 abaran30 commented Nov 23, 2021

Similar to #804, this pull request adds the option to enforce the requirement of a description for i18n metadata when using $localize in component code.

TODO:

  • Address all questions/comments below
  • Documentation

Pull request is in draft mode; please see my comments below!

FYI @JamesHenry , I know that you haven't used Angular i18n, but perhaps you could chime in on the creation of this new rule? See my comments for require-localize-metadata.ts.

@abaran30 abaran30 force-pushed the feat/localize-require-metadata branch from f2bde02 to 5b2d478 Compare November 23, 2021 19:10

const VALID_LOCALIZED_STRING_WITH_DESCRIPTION = new RegExp(/`:[^|]*:.*`/);

// TODO: The following values are also used in eslint-plugin-template/i18n, and should likely be centralized
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a good location for these values?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the comment, I think having the small bit of repetition is fine and allows for them to remain independent and be more easily refactored if the structure of Angular guides changes in future

requireDescription: false,
};

const VALID_LOCALIZED_STRING_WITH_DESCRIPTION = new RegExp(/`:[^|]*:.*`/);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts on this RegExp?

taggedTemplateExpression: TSESTree.TaggedTemplateExpression,
) {
const identifierName = (
taggedTemplateExpression.tag as TSESTree.Identifier

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does it need casting?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because tag is of type LeftHandSideExpression, which is:

export declare type LeftHandSideExpression = ArrayExpression | ArrayPattern | ArrowFunctionExpression | CallExpression | ClassExpression | FunctionExpression | Identifier | JSXElement | JSXFragment | LiteralExpression | MemberExpression | MetaProperty | ObjectExpression | ObjectPattern | SequenceExpression | Super | TaggedTemplateExpression | ThisExpression | TSAsExpression | TSNonNullExpression | TSTypeAssertion;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adbaran1 It would be better to narrow the type through control flow analysis by actually checking the shape of the tag to check that it is an identifier.

You can use the utility TSESLintASTUtils.isIdentifier(...) from @typescript-eslint/experimental-utils to do exactly what you need and TypeScript will pick up on the types through the control flow analysis.

@abaran30 abaran30 marked this pull request as ready for review February 11, 2022 20:28
@JamesHenry JamesHenry changed the title feat(require-localize-metadata): option to enforce that $localize tagged messages contain a description feat(eslint-plugin-template): add require-localize-metadata rule Feb 13, 2022
Copy link
Member

@JamesHenry JamesHenry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for this @adbaran1, I'm really sorry for how long it has taken me to get back to you on this.

I moved countries a couple of times so things have been very chaotic.


const VALID_LOCALIZED_STRING_WITH_DESCRIPTION = new RegExp(/`:[^|]*:.*`/);

// TODO: The following values are also used in eslint-plugin-template/i18n, and should likely be centralized
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the comment, I think having the small bit of repetition is fine and allows for them to remain independent and be more easily refactored if the structure of Angular guides changes in future

},
defaultOptions: [DEFAULT_OPTIONS],
create(context, [{ requireDescription }]) {
function reportRequireLocalizeMetadataError(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please can you refactor this implementation to just inline everything in the Node handler method?

There is very little code here but the dedication to wrapping every step into functions hurts readability in my opinion because of how it changes the flow of the document.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment below about eventually being able to support custom ID and meaning.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense @adbaran1 👍

taggedTemplateExpression: TSESTree.TaggedTemplateExpression,
) {
const identifierName = (
taggedTemplateExpression.tag as TSESTree.Identifier
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adbaran1 It would be better to narrow the type through control flow analysis by actually checking the shape of the tag to check that it is an identifier.

You can use the utility TSESLintASTUtils.isIdentifier(...) from @typescript-eslint/experimental-utils to do exactly what you need and TypeScript will pick up on the types through the control flow analysis.

{
type: 'object',
properties: {
requireDescription: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what purpose this option serves given the whole rule is dedicated to this purpose?

This is further backed up by the fact you don't have tests for when it is disabled.

I would think that if someone does not want to require the description they would simply not use this rule right?

Copy link
Contributor Author

@abaran30 abaran30 Feb 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JamesHenry no worries, and I hope things are less chaotic now 😄 . The reason for this setup is to be able to support custom ID and meaning, which are the other two i18n metadata parameters (see i18n metadata for translation). This pull request is only to support description for the time being, which is why the implementation looks the way it does (i.e. having functions like testLocalizeTemplateElementWithDescription).

With that all said, let me know what you think about the overall approach.

@abaran30 abaran30 force-pushed the feat/localize-require-metadata branch from 2dfe0a9 to 1d4eed3 Compare February 14, 2022 15:15
@codecov
Copy link

codecov bot commented Feb 22, 2022

Codecov Report

Merging #844 (10f48b8) into master (4c11177) will increase coverage by 0.09%.
The diff coverage is 96.15%.

@@            Coverage Diff             @@
##           master     #844      +/-   ##
==========================================
+ Coverage   86.36%   86.45%   +0.09%     
==========================================
  Files         145      147       +2     
  Lines        2720     2746      +26     
  Branches      438      441       +3     
==========================================
+ Hits         2349     2374      +25     
  Misses        220      220              
- Partials      151      152       +1     
Flag Coverage Δ
unittest 86.45% <96.15%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...lint-plugin/src/rules/require-localize-metadata.ts 95.00% <95.00%> (ø)
...gin/tests/rules/require-localize-metadata/cases.ts 100.00% <100.00%> (ø)

},
defaultOptions: [DEFAULT_OPTIONS],
create(context, [{ requireDescription }]) {
function reportRequireLocalizeMetadataError(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense @adbaran1 👍

@alex-okrushko
Copy link

@JamesHenry Looks like Adrian has addresses all the comments. Anything else needs to be done before it's merged?
Thanks!

@JamesHenry
Copy link
Member

Thanks again for your patience on this @adbaran1 @alex-okrushko.

I think the description of the overall rule matching the intent behind a subset of its intended features is still confusing but I will amend that post-merge

@JamesHenry JamesHenry merged commit ca1edf0 into angular-eslint:master Apr 2, 2022
@abaran30
Copy link
Contributor Author

abaran30 commented Apr 4, 2022

Thank you @JamesHenry. Please let us know how we can assist you in making it all better. We can look to add support for Angular i18n meaning and IDs to make the overall setup more clear ASAP.

crapStone pushed a commit to Calciumdibromid/CaBr2 that referenced this pull request Apr 9, 2022
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint) | devDependencies | minor | [`13.1.0` -> `13.2.0`](https://renovatebot.com/diffs/npm/@angular-eslint%2fbuilder/13.1.0/13.2.0) |
| [@angular-eslint/eslint-plugin](https://github.com/angular-eslint/angular-eslint) | devDependencies | minor | [`13.1.0` -> `13.2.0`](https://renovatebot.com/diffs/npm/@angular-eslint%2feslint-plugin/13.1.0/13.2.0) |
| [@angular-eslint/eslint-plugin-template](https://github.com/angular-eslint/angular-eslint) | devDependencies | minor | [`13.1.0` -> `13.2.0`](https://renovatebot.com/diffs/npm/@angular-eslint%2feslint-plugin-template/13.1.0/13.2.0) |
| [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint) | devDependencies | minor | [`13.1.0` -> `13.2.0`](https://renovatebot.com/diffs/npm/@angular-eslint%2fschematics/13.1.0/13.2.0) |
| [@angular-eslint/template-parser](https://github.com/angular-eslint/angular-eslint) | devDependencies | minor | [`13.1.0` -> `13.2.0`](https://renovatebot.com/diffs/npm/@angular-eslint%2ftemplate-parser/13.1.0/13.2.0) |

---

### Release Notes

<details>
<summary>angular-eslint/angular-eslint (@&#8203;angular-eslint/builder)</summary>

### [`v13.2.0`](https://github.com/angular-eslint/angular-eslint/blob/HEAD/packages/builder/CHANGELOG.md#&#8203;1320-httpsgithubcomangular-eslintangular-eslintcomparev1310v1320-2022-04-03)

[Compare Source](angular-eslint/angular-eslint@v13.1.0...v13.2.0)

**Note:** Version bump only for package [@&#8203;angular-eslint/builder](https://github.com/angular-eslint/builder)

</details>

<details>
<summary>angular-eslint/angular-eslint (@&#8203;angular-eslint/eslint-plugin)</summary>

### [`v13.2.0`](https://github.com/angular-eslint/angular-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#&#8203;1320-httpsgithubcomangular-eslintangular-eslintcomparev1310v1320-2022-04-03)

[Compare Source](angular-eslint/angular-eslint@v13.1.0...v13.2.0)

##### Features

-   **eslint-plugin-template:** add require-localize-metadata rule ([#&#8203;844](angular-eslint/angular-eslint#844)) ([ca1edf0](angular-eslint/angular-eslint@ca1edf0))

</details>

<details>
<summary>angular-eslint/angular-eslint (@&#8203;angular-eslint/eslint-plugin-template)</summary>

### [`v13.2.0`](https://github.com/angular-eslint/angular-eslint/blob/HEAD/packages/eslint-plugin-template/CHANGELOG.md#&#8203;1320-httpsgithubcomangular-eslintangular-eslintcomparev1310v1320-2022-04-03)

[Compare Source](angular-eslint/angular-eslint@v13.1.0...v13.2.0)

##### Features

-   **parser:** propagate parse errors from angular compiler ([#&#8203;969](angular-eslint/angular-eslint#969)) ([ab9b496](angular-eslint/angular-eslint@ab9b496))

</details>

<details>
<summary>angular-eslint/angular-eslint (@&#8203;angular-eslint/schematics)</summary>

### [`v13.2.0`](https://github.com/angular-eslint/angular-eslint/blob/HEAD/packages/schematics/CHANGELOG.md#&#8203;1320-httpsgithubcomangular-eslintangular-eslintcomparev1310v1320-2022-04-03)

[Compare Source](angular-eslint/angular-eslint@v13.1.0...v13.2.0)

##### Bug Fixes

-   **schematics:** support more permutations of ng-add ([#&#8203;970](angular-eslint/angular-eslint#970)) ([0bf549b](angular-eslint/angular-eslint@0bf549b))

</details>

<details>
<summary>angular-eslint/angular-eslint (@&#8203;angular-eslint/template-parser)</summary>

### [`v13.2.0`](https://github.com/angular-eslint/angular-eslint/blob/HEAD/packages/template-parser/CHANGELOG.md#&#8203;1320-httpsgithubcomangular-eslintangular-eslintcomparev1310v1320-2022-04-03)

[Compare Source](angular-eslint/angular-eslint@v13.1.0...v13.2.0)

##### Features

-   **parser:** propagate parse errors from angular compiler ([#&#8203;969](angular-eslint/angular-eslint#969)) ([ab9b496](angular-eslint/angular-eslint@ab9b496))

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Co-authored-by: cabr2-bot <[email protected]>
Co-authored-by: 6543 <[email protected]>
Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1281
Reviewed-by: 6543 <[email protected]>
Co-authored-by: Calciumdibromid Bot <[email protected]>
Co-committed-by: Calciumdibromid Bot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants