Skip to content

fix(compiler): fix i18n IDs generation, add a migration tool #17638

Closed
ocombe wants to merge 15 commits intoangular:masterfrom
ocombe:i18n-version
Closed

fix(compiler): fix i18n IDs generation, add a migration tool #17638
ocombe wants to merge 15 commits intoangular:masterfrom
ocombe:i18n-version

Conversation

@ocombe
Copy link
Copy Markdown
Contributor

@ocombe ocombe commented Jun 20, 2017

Please check if the PR fulfills these requirements

  • Tests for the changes have been added

What kind of change does this PR introduce?

  • Bugfix

What is the current behavior?
See #15573.

What is the new behavior?
When we extract messages we digest them to generate ids (unless the id is provided).
With this fix we ignore the content of the placeholder when we digest to only use the fact that it's a placeholder and its position.
We already did the same thing with ICU expressions for XMB and this previous fix is now also applied to ICU expressions for XLIFF (now that XLIFF supports ICU expressions).
Example previously <p i18n>{{expr}}</p>, <p i18n>{{ expr }}</p> and <p i18n>{{expr2}}</p> had different ids but the exact same content once extracted. With this fix those 3 messages will only be extracted once with the same id.
We also aligned the digest functions for all serializers, they will all use the decimal digest (instead of sha1 previously for xliff).


Because of the bug #15573 we had to make a breaking change in the way i18n ids are generated.
To mitigate the problem, a new flag can be used to set the version of the digest method used: --i18nVersion with values 0 (old, default for v4) or 1 (new, default for v5) can be used by the cli tools for extraction (ng-xi18n) and AOT (ngc). The token I18N_VERSION can be used in your code for JIT.
We also added a new migration cli tool in @angular/compiler-cli named ng-migrate-i18n-0to1.
Usage is the following: ng-migrate-i18n-0to1 --files src/i18n/*.xlf --format xlf
--files: (required) the translation files that you want to migrate, you can use glob expressions to migrate multiple files at the same time (as long as they use the same format)
--format: (required) the format of the translation files that you want to migrate
--mapping: (optional) if you add this option it will generate a json file of mappings {newId --> [oldIds]} instead of migrating the translation files
--resolve: (optional) "manual" by default, you can use "auto" so that the cli tool doesn't ask when it finds conflicts (in which case it will take the first value)

Does this PR introduce a breaking change?

  • Yes

Unfortunately this is a breaking change because the auto-generated ids for extracted messages will change if the message contains placeholders (or ICU expressions for XLIFF)...
To mitigate the problem, a new flag can be used to set the version of the digest method used. It is --i18nVersion with values 0 (old, default for v4) or 1 (new, default for v5) for ngc, and the token I18N_VERSION for JIT.
For now we still use the old method to generate the ids, but once v5 is released we will reverse the flag to only use the new version.

@ocombe ocombe added area: i18n Issues related to localization and internationalization breaking changes action: review The PR is still awaiting reviews from at least one requested reviewer labels Jun 20, 2017
@ocombe ocombe requested a review from vicb June 20, 2017 16:54
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  • Should we throw in this case ?
  • change param to i18nFormat: string | null ?

Copy link
Copy Markdown
Contributor

@vicb vicb Jun 22, 2017

Choose a reason for hiding this comment

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

nit: this is not the startOfEl - add a comment ?

better: extract content.lastIndexOf('>', sources[0].startSourceSpan !.start.offset) + 1 to an helper function to factorize, add doc there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What are start and end used for ?
Would your logic work if source elements are not back to back

<source>1</source>
<other>
<source>2</source>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

good point, it would fail :(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

unused ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unused but required since we extend ml.RecursiveVisitor.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why would it be required ?

Copy link
Copy Markdown
Contributor

@vicb vicb Jun 22, 2017

Choose a reason for hiding this comment

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

  • using remove for something with is not removed is a bad idea - old1 & old2 ?
  • be consistent why mapping and an inline mapping ? use v0ToV1 and v1ToV0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

move this at describe level to avoir repeating ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why do we have to change the tsconfig here ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

because of a change that @tbosch made on master, without these parameters the tests won't work

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd rather have execute and generateMapping()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[...sources] ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what is the rationale here ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

revert ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

revert ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove ?

Copy link
Copy Markdown
Contributor

@vicb vicb Jun 26, 2017

Choose a reason for hiding this comment

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

remove "?"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Did you create an issue for this bug as discussed in the shared doc ? (startCol = endCol)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove ? from here for consistency

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

const

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should be el.visit(this, null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

sourcesInfos -> srcElements ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

.find -> .some

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

.find -> .some

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

sources -> srcElements

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

probably you should merge SourceInfosVisitor with MsgInfosVisitor ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

wouldn't replacing the id (right above) shift the sourcespan for the sources ?
If yes, why is this not caught by the tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

because in my test the "old" id and the "new" id have the same length. Replacing "old" by "old2" made the tests fail

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe use constants here const XLIFF_MSG_EL = 'trans-unit';

@googlebot
Copy link
Copy Markdown

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this state. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

@mary-poppins
Copy link
Copy Markdown

@mary-poppins
Copy link
Copy Markdown

@mhevery mhevery force-pushed the i18n-version branch 3 times, most recently from a3bb636 to ccb2ae9 Compare July 26, 2017 18:06
@ocombe
Copy link
Copy Markdown
Contributor Author

ocombe commented Nov 3, 2017

Closing this for now because it's completely out of date and our code has changed too much. We'll have to start over if we want to fix this problem.

@ocombe ocombe closed this Nov 3, 2017
@angular-automatic-lock-bot
Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 12, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: i18n Issues related to localization and internationalization breaking changes cla: no state: blocked

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants