Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
feat(compiler-cli): adding mapping option for migration tool
  • Loading branch information
ocombe committed Jul 17, 2017
commit ccb2ae96e17d9d5b7373f4a1337236f1836b80ef
44 changes: 44 additions & 0 deletions packages/compiler-cli/integrationtest/src/mapping_v1_to_v0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"8136548302122759730": {
"ids": [
"76e1eccb1b772fa9f294ef9c146ea6d0efa8a2d4"
],
"sources": [
{
"filePath": "src/basic.ts",
"startLine": 1,
"startCol": 44,
"endLine": 1,
"endCol": 44

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)

}
]
},
"3492007542396725315": {
"ids": [
"65cc4ab3b4c438e07c89be2b677d08369fb62da2"
],
"sources": [
{
"filePath": "src/basic.ts",
"startLine": 5,
"startCol": 35,
"endLine": 5,
"endCol": 35
}
]
},
"126808141597411718": {
"ids": [
"b0a17f08a4bd742b2acf39780c257c2f519d33ed"
],
"sources": [
{
"filePath": "node_modules/third_party/other_comp.d.ts",
"startLine": 1,
"startCol": 11,
"endLine": 2,
"endCol": 11
}
]
}
}
35 changes: 17 additions & 18 deletions packages/compiler-cli/integrationtest/test/test_ngtools_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function main() {
.then(() => codeGenTest(true))
.then(() => i18nTest())
.then(() => i18nMigrationTest())
// .then(() => i18nMigrationMappingTest())
.then(() => i18nMigrationMappingTest())
.then(() => lazyRoutesTest())
.then(() => {
console.log('All done!');
Expand Down Expand Up @@ -222,7 +222,7 @@ function i18nMigrationTest() {
/**
* Testing that the map file generated by the migration tool is correctly generated
*/
/*function i18nMigrationMappingTest() {
function i18nMigrationMappingTest() {
const basePath = path.join(__dirname, '../');
const srcPath = path.join(__dirname, '../src');
const project = path.join(basePath, 'tsconfig-xi18n.json');
Expand All @@ -247,6 +247,7 @@ function i18nMigrationTest() {
angularCompilerOptions: config.ngOptions,
i18nFormat: 'xlf',
files: path.join(srcPath, 'messages_v0.fr.xlf'),
resolve: 'auto',
mapping: true,
readResource: (fileName: string) => {
readResources.push(fileName);
Expand All @@ -260,26 +261,24 @@ function i18nMigrationTest() {
.then((files: string[]) => {
console.log(`>>> i18n migration mapping done, asserting mapping file`);

const mappingFile = 'messages_v0.fr_mapping.json';
const mappingFile = 'mapping_v1_to_v0.json';
const allFiles = glob.sync(path.join(srcPath, '**/ /*'), {nodir: true});

assert(wroteFiles.length == 1, `Expected a single mapping file.`);
assert(
wroteFiles[0].fileName.endsWith(mappingFile),
`Expected the mapping file to be "${mappingFile}" but it was ${wroteFiles[0].fileName}
instead.`);

assertFilesRead(allFiles, readResources);
assert(wroteFiles.length == 1, `Expected a single mapping file.`);
assert(
wroteFiles[0].fileName.endsWith(mappingFile),
`Expected the mapping file to be "${mappingFile}" but it was ${wroteFiles[0].fileName} instead.`);

assert.deepEqual(
JSON.parse(wroteFiles[0].content),
JSON.parse(fs.readFileSync(path.join(srcPath, 'messages_mapping.json'), 'utf8')),
`Expected mapping file to have been generated`);
assertFilesRead(allFiles, readResources);

console.log(`done, no errors.`);
})
.catch(onRejected('Migration failed'));
}*/
assert.deepEqual(
JSON.parse(wroteFiles[0].content),
JSON.parse(fs.readFileSync(path.join(srcPath, mappingFile), 'utf8')),
`Expected correct mapping file to have been generated`);
console.log(`done, no errors.`);
})
.catch(onRejected('Migration failed'));
}

function assertFilesRead(allFiles: string[], readResources: string[], wroteFiles?: string[]): void {
allFiles.forEach((fileName: string) => {
Expand Down
12 changes: 9 additions & 3 deletions packages/compiler-cli/integrationtest/tsconfig-xi18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@
// For TypeScript 1.8, we have to lay out generated files
// in the same source directory with your code.
"genDir": ".",
"debug": true
"debug": true,
"enableSummariesForJit": true,
"alwaysCompileGeneratedCode": true

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

},

"compilerOptions": {
"target": "es5",
"experimentalDecorators": true,
"noImplicitAny": true,
"strictNullChecks": true,
"skipLibCheck": true,
"moduleResolution": "node",
"outDir": "./out",
"rootDir": "",
"declaration": true,
"lib": ["es6", "dom"],
"baseUrl": ".",
// Prevent scanning up the directory tree for types
"typeRoots": ["node_modules/@types"]
"typeRoots": ["node_modules/@types"],
"noUnusedLocals": true,
"sourceMap": true,
"outDir": "./out"
},

"files": [
Expand Down
1 change: 1 addition & 0 deletions packages/compiler-cli/src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export class CodeGenerator {
locale: cliOptions.locale,
i18nVersion: normalizeI18nVersion(cliOptions.i18nVersion),
enableLegacyTemplate: options.enableLegacyTemplate !== false,
enableSummariesForJit: options.enableSummariesForJit !== false,
});

return new CodeGenerator(options, program, tsCompilerHost, aotCompiler, ngCompilerHost);
Expand Down
5 changes: 5 additions & 0 deletions packages/compiler-cli/src/i18n_options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,8 @@ export function normalizeMissingTranslation(missingTranslation?: string | null):
}
return MissingTranslationStrategy.Warning;
}

/** @internal */
export function normalizeMapping(mapping?: string | boolean | null): boolean {

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

return typeof mapping !== 'undefined' && mapping !== 'false' && mapping !== null;
}
10 changes: 7 additions & 3 deletions packages/compiler-cli/src/migrate_i18n_0to1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@ import 'reflect-metadata';
import * as tsc from '@angular/tsc-wrapped';
import * as ts from 'typescript';

import {normalizeFiles, normalizeI18nFormat, normalizeResolve} from './i18n_options';
import {normalizeFiles, normalizeI18nFormat, normalizeMapping, normalizeResolve} from './i18n_options';
import {V0ToV1Migration} from './migration/v0_to_v1';

export class CliOptions extends tsc.CliOptions {
public i18nFormat: string|null;
public files: string|null;
public resolve: string|null;
public mapping: string|null;

constructor({i18nFormat = null, files = null, resolve = null}: {
constructor({i18nFormat = null, files = null, resolve = null, mapping = null}: {
i18nFormat?: string,
files?: string,
resolve?: string,
mapping?: string,
}) {
super({});
this.i18nFormat = i18nFormat;
this.files = files;
this.resolve = resolve;
this.mapping = mapping;
}
}

Expand All @@ -43,10 +46,11 @@ function extract(
const files = normalizeFiles(cliOptions.files);
const format = normalizeI18nFormat(cliOptions.i18nFormat);
const autoResolve = normalizeResolve(cliOptions.resolve);
const isMapping = normalizeMapping(cliOptions.mapping);

const migration = V0ToV1Migration.create(ngOptions, program, host, files, format, autoResolve);

return migration.execute();
return migration.execute(isMapping);
}

// Entry point
Expand Down
28 changes: 21 additions & 7 deletions packages/compiler-cli/src/migration/v0_to_v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import {I18nVersion} from '@angular/core';
import * as tsc from '@angular/tsc-wrapped';
import {readFileSync} from 'fs';
import * as inquirer from 'inquirer';
import {join} from 'path';
import * as ts from 'typescript';

import {CompilerHost, CompilerHostContext, ModuleResolutionHostAdapter} from '../compiler_host';
import {Extractor} from '../extractor';
import {PathMappedCompilerHost} from '../path_mapped_compiler_host';



/**
* Resolves the conflicts during migration:
* - manually by asking the user which translation to keep when `autoResolve` is `false`,
Expand Down Expand Up @@ -49,15 +51,21 @@ function resolveConflicts(
*/
export class V0ToV1Migration {
constructor(
private host: ts.CompilerHost, private extractor: Extractor, private files: string[],
private format: string, private autoResolve: boolean) {}
private options: tsc.AngularCompilerOptions, private host: ts.CompilerHost,
private extractor: Extractor, private files: string[], private format: string,
private autoResolve: boolean) {}

execute(): Promise<string[]> {
execute(isMapping: boolean): Promise<string[]> {

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()

return this.extractor.extractBundle().then((bundle: compiler.MessageBundle) => {
const v1toV0 = compiler.generateV1ToV0Map(bundle, this.format);
const v1toV0 =
compiler.generateV1ToV0Map(bundle, this.format, join(this.options.genDir, '/'));

return this.files.reduce(
(p, file) => p.then(this.genMigrateFileCallback(v1toV0, file)), Promise.resolve([]));
if (isMapping) {
return Promise.resolve(this.genMappingFile(v1toV0));
} else {
return this.files.reduce(
(p, file) => p.then(this.genMigrateFileCallback(v1toV0, file)), Promise.resolve([]));
}
});
}

Expand All @@ -79,6 +87,12 @@ export class V0ToV1Migration {
};
}

private genMappingFile(v1toV0: compiler.V1ToV0Map): string[] {
let dstPath = join(this.options.genDir, `mapping_v1_to_v0.json`);

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

this.host.writeFile(dstPath, JSON.stringify(v1toV0), false);
return [dstPath];
}

static create(
options: tsc.AngularCompilerOptions, program: ts.Program, tsCompilerHost: ts.CompilerHost,
files: string[], format: string, autoResolve: boolean,
Expand All @@ -94,6 +108,6 @@ export class V0ToV1Migration {
I18nVersion.V1, options, program, tsCompilerHost, null, compilerHostContext,
ngCompilerHost);

return new V0ToV1Migration(tsCompilerHost, extractor, files, format, autoResolve);
return new V0ToV1Migration(options, tsCompilerHost, extractor, files, format, autoResolve);
}
}
6 changes: 4 additions & 2 deletions packages/compiler-cli/src/ngtools_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import * as ts from 'typescript';
import {CodeGenerator} from './codegen';
import {CompilerHost, CompilerHostContext, ModuleResolutionHostAdapter} from './compiler_host';
import {Extractor} from './extractor';
import {normalizeFiles, normalizeI18nFormat, normalizeResolve} from './i18n_options';
import {normalizeFiles, normalizeI18nFormat, normalizeMapping, normalizeResolve} from './i18n_options';
import {V0ToV1Migration} from './migration/v0_to_v1'
import {listLazyRoutesOfModule} from './ngtools_impl';
import {PathMappedCompilerHost} from './path_mapped_compiler_host';
Expand Down Expand Up @@ -81,6 +81,7 @@ export interface NgTools_InternalApi_NG2_MigrateI18n_Options {
// Every new property under this line should be optional.
i18nFormat?: string;
resolve?: string;
mapping?: boolean;
}

/**
Expand Down Expand Up @@ -187,12 +188,13 @@ export class NgTools_InternalApi_NG_2 {
const files = normalizeFiles(options.files);
const format = normalizeI18nFormat(options.i18nFormat);
const autoResolve = normalizeResolve(options.resolve);
const isMapping = normalizeMapping(options.mapping);

// Create the i18n migrator
const migrator = V0ToV1Migration.create(
options.angularCompilerOptions, options.program, options.host, files, format, autoResolve,
hostContext);

return migrator.execute();
return migrator.execute(isMapping);
}
}
15 changes: 12 additions & 3 deletions packages/compiler/src/i18n/migration/v0_to_v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,34 @@ export type V0ToV1Map = {
* - `ids`: the list of v0 ids that the v1 id replaces.
* - `sources`: the list of `MessageSpan` for the v1 id.
*/
export function generateV1ToV0Map(messageBundle: MessageBundle, formatName: string): V1ToV0Map {
export function generateV1ToV0Map(
messageBundle: MessageBundle, formatName: string, basePath: string = ''): V1ToV0Map {
const serializerV0 = createSerializer(formatName, I18nVersion.V0);
const serializerV1 = createSerializer(formatName, I18nVersion.V1);

const v1ToV0: V1ToV0Map = {};

function cleanPaths(sources: MessageSpan[]) {
return [...sources].map(source => {

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] ?

source.filePath = source.filePath.replace(basePath, '');
return source;
});
}

messageBundle.getMessages().forEach((msg: Message) => {
const v0 = serializerV0.digest(msg);
const v1 = serializerV1.digest(msg);
const sources = cleanPaths(msg.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 ?


if (v1ToV0.hasOwnProperty(v1)) {
if (v1ToV0[v1].ids.indexOf(v0) === -1) {
v1ToV0[v1].ids.push(v0);
v1ToV0[v1].sources !.push(...msg.sources);
v1ToV0[v1].sources !.push(...sources);
}
} else {
v1ToV0[v1] = {
ids: [v0],
sources: msg.sources,
sources: sources,
};
}
});
Expand Down
14 changes: 7 additions & 7 deletions packages/compiler/test/i18n/migration/v0_to_v1_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@ export function main(): void {
<p i18n="@@fixed_id">foo {{buz}}</p>
`;
const bundle = new MessageBundle(new HtmlParser, [], {});
bundle.updateFromTemplate(HTML, '/path/to/html', DEFAULT_INTERPOLATION_CONFIG);
const v1toV0 = generateV1ToV0Map(bundle, 'xmb');
bundle.updateFromTemplate(HTML, '/root/path/to/html', DEFAULT_INTERPOLATION_CONFIG);
const v1toV0 = generateV1ToV0Map(bundle, 'xmb', '/root/');

// `foo {{bar}}` and `foo {{baz}}` generate different v0 ids but a single v1 id
expect(v1toV0).toEqual({
'3667842621564887364': {
ids: ['3667842621564887364'],
sources: [
{filePath: '/path/to/html', startLine: 2, startCol: 9, endLine: 2, endCol: 9},
{filePath: 'path/to/html', startLine: 2, startCol: 9, endLine: 2, endCol: 9},
],
},
'7312636350219285759': {
ids: ['7291167978964532459', '2231161507516844600'],
sources: [
{filePath: '/path/to/html', startLine: 3, startCol: 9, endLine: 3, endCol: 9},
{filePath: '/path/to/html', startLine: 4, startCol: 9, endLine: 4, endCol: 9},
{filePath: 'path/to/html', startLine: 3, startCol: 9, endLine: 3, endCol: 9},
{filePath: 'path/to/html', startLine: 4, startCol: 9, endLine: 4, endCol: 9},
],
},
'fixed_id': {
ids: ['fixed_id'],
sources: [
{filePath: '/path/to/html', startLine: 5, startCol: 22, endLine: 5, endCol: 22},
{filePath: 'path/to/html', startLine: 5, startCol: 22, endLine: 5, endCol: 22},
],
},
});
Expand Down Expand Up @@ -174,4 +174,4 @@ export function main(): void {

});
});
}
}
1 change: 1 addition & 0 deletions scripts/ci/offline_compiler_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ cp -v package.json $TMP

# Test migration
./node_modules/.bin/ng-migrate-i18n-0to1 -p tsconfig-xi18n.json --i18nFormat=xlf --files=src/messages_v0.fr.xlf --resolve=auto
./node_modules/.bin/ng-migrate-i18n-0to1 -p tsconfig-xi18n.json --i18nFormat=xlf --files=src/messages_v0.fr.xlf --resolve=auto --mapping=true

# Removed until #15219 is fixed
# node test/test_summaries.js
Expand Down