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

Make i18n extractor execution idempotent #39262

Closed
acalvo opened this issue Oct 14, 2020 · 16 comments
Closed

Make i18n extractor execution idempotent #39262

acalvo opened this issue Oct 14, 2020 · 16 comments
Assignees
Labels
area: i18n feature Issue that requests a new feature P4 A relatively minor issue that is not relevant to core functions state: has PR
Milestone

Comments

@acalvo
Copy link

acalvo commented Oct 14, 2020

🚀 feature request

Relevant Package

This feature request is for @angular/localize

Description

Each time you run ng xi18n --ivy, the output changes, as the order of the trans-units is different from execution to execution.

Describe the solution you'd like

The output could be sorted (in any way) to ensure that if the source code doesn't change, the output is always the same. This would make it easier to see the changes in the version control system, etc.

Describe alternatives you've considered

Meanwhile, we are ordering the resulting XLIFF by ourselves.

@petebacondarwin
Copy link
Member

Can I assume that if you do not change the source code then the extracted output is indeed the same from one run to the next? And that the changes to the ordering you see are due to changes to the source code?

@petebacondarwin petebacondarwin added area: i18n feature Issue that requests a new feature P4 A relatively minor issue that is not relevant to core functions labels Oct 14, 2020
@ngbot ngbot bot modified the milestone: Backlog Oct 14, 2020
@acalvo
Copy link
Author

acalvo commented Oct 14, 2020

Can I assume that if you do not change the source code then the extracted output is indeed the same from one run to the next? And that the changes to the ordering you see are due to changes to the source code?

No, it isn't, and that's our main problem...

With no changes to the source code I run ng xi18n --ivy and get a XLIFF output. Ok. I run it again, and get the a different output (same messages, same IDs, but different order).

@petebacondarwin
Copy link
Member

Hmm, I guess this must be due to the async webpack build in the CLI, that can cause source files to be compiled in different orders...

@petebacondarwin
Copy link
Member

I'm going to see if I can sort the messages by the file that they are in....

@suer85
Copy link

suer85 commented Dec 18, 2020

@acalvo how are you ordering the result yourself?

@acalvo
Copy link
Author

acalvo commented Dec 18, 2020

@suer85 once Angular generates the XLIFF, we run a script to sort it an replace the file generated by Angular.

This sort-xlf.ts works for us:

import * as fs from 'fs';
import * as libxmljs from 'libxmljs';
import * as path from 'path';

const i18nDir = process.argv[2];
const ns = 'urn:oasis:names:tc:xliff:document:1.2';

const xmlDoc = libxmljs.parseXml(fs.readFileSync(path.join(i18nDir, 'translation.en.xlf')).toString());
const body = xmlDoc.get('//ns:body', { ns });
const transUnits = body.childNodes() as Array<libxmljs.Element>;
const newBody = new libxmljs.Element(xmlDoc, 'body', '');
newBody.addChild(transUnits[0]);
transUnits.filter(x => x.type() === 'element').sort((a, b) => {
  return parseInt(a.attr('id').value(), 10) - parseInt(b.attr('id').value(), 10);
}).forEach(t => {
  newBody.addChild(t);
});
newBody.addChild(transUnits[transUnits.length - 1]);
body.replace(newBody);
fs.writeFileSync(path.join(i18nDir, 'translation.en.xlf'), xmlDoc.toString(), 'utf8');

And execute it this way: ng extract-i18n --ivy --output-path $I18N_DIR --out-file translation.en.xlf --progress false && npx ts-node sort-xlf.ts $I18N_DIR"

Hope it helps as a workaround till it's properly solved by the Angular team :)

@petebacondarwin
Copy link
Member

Working on it right now!

petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Dec 18, 2020
…nt order

The CLI integration can provide code files in a non-deterministic
order, which led to the extracted translation files having
messages in a non-consistent order between extractions.

This commit fixes this by ensuring that serialized messages
are ordered by their location.

Fixes angular#39262
petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Dec 19, 2020
…nt order

The CLI integration can provide code files in a non-deterministic
order, which led to the extracted translation files having
messages in a non-consistent order between extractions.

This commit fixes this by ensuring that serialized messages
are ordered by their location.

Fixes angular#39262
@suer85
Copy link

suer85 commented Dec 21, 2020

@suer85 once Angular generates the XLIFF, we run a script to sort it an replace the file generated by Angular.

This sort-xlf.ts works for us:

import * as fs from 'fs';
import * as libxmljs from 'libxmljs';
import * as path from 'path';

const i18nDir = process.argv[2];
const ns = 'urn:oasis:names:tc:xliff:document:1.2';

const xmlDoc = libxmljs.parseXml(fs.readFileSync(path.join(i18nDir, 'translation.en.xlf')).toString());
const body = xmlDoc.get('//ns:body', { ns });
const transUnits = body.childNodes() as Array<libxmljs.Element>;
const newBody = new libxmljs.Element(xmlDoc, 'body', '');
newBody.addChild(transUnits[0]);
transUnits.filter(x => x.type() === 'element').sort((a, b) => {
  return parseInt(a.attr('id').value(), 10) - parseInt(b.attr('id').value(), 10);
}).forEach(t => {
  newBody.addChild(t);
});
newBody.addChild(transUnits[transUnits.length - 1]);
body.replace(newBody);
fs.writeFileSync(path.join(i18nDir, 'translation.en.xlf'), xmlDoc.toString(), 'utf8');

And execute it this way: ng extract-i18n --ivy --output-path $I18N_DIR --out-file translation.en.xlf --progress false && npx ts-node sort-xlf.ts $I18N_DIR"

Hope it helps as a workaround till it's properly solved by the Angular team :)

Thanks :)

@JonasSamuelsson
Copy link

Do you have an ETA for a release where this fix is included?

@petebacondarwin
Copy link
Member

@JonasSamuelsson - the PR is marked for merging into "patch" so it will appear in 11.0.6 very early in 2021.

petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Dec 22, 2020
…nt order

The CLI integration can provide code files in a non-deterministic
order, which led to the extracted translation files having
messages in a non-consistent order between extractions.

This commit fixes this by ensuring that serialized messages
are ordered by their location.

Fixes angular#39262
@minijus
Copy link

minijus commented Jan 4, 2021

Is it already very early in 2021? :)

@petebacondarwin
Copy link
Member

Very very early! Happy New Year.

josephperrott pushed a commit to petebacondarwin/angular that referenced this issue Jan 5, 2021
…nt order

The CLI integration can provide code files in a non-deterministic
order, which led to the extracted translation files having
messages in a non-consistent order between extractions.

This commit fixes this by ensuring that serialized messages
are ordered by their location.

Fixes angular#39262
@acalvo
Copy link
Author

acalvo commented Jan 7, 2021

Thanks for the fix @petebacondarwin ! 😄

Just a quick clarification:

the PR is marked for merging into "patch" so it will appear in 11.0.6 very early in 2021.

This didn't happen, did it? I'm seeing in the Angular changelog that it landed in 11.1.0-next.4 but not in 11.0.6. And the changelog seems to be OK because I just tried it and the old behavior keeps happening in 11.0.6.

This is not a complain - I just wanted to prevent confusion to the people following this issue, as it seems that it'll be included in the 11.1.x branch and not in the 11.0.x line :).

@petebacondarwin
Copy link
Member

Hi @acalvo - it turned out that there was a conflict in merging that PR into the patch branch. Since we are about to release 11.1.0 RC we decided that it was simplest to only merge the PR into the master branch, which means that the fix will be available in 11.1.0. Sorry about the confusion.

@acalvo
Copy link
Author

acalvo commented Jan 7, 2021

Perfect! No worries - I'm sure we all can wait a few weeks till 11.1.0 goes stable 😊

Thanks again.

@angular-automatic-lock-bot
Copy link

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 Feb 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: i18n feature Issue that requests a new feature P4 A relatively minor issue that is not relevant to core functions state: has PR
Projects
None yet
5 participants