refactor(core): static-query schematic incorrectly handles multiple tsconfigs (#29133)

Currently when the static-query runs for a project with multiple TypeScript
configuration files (e.g. a usual CLI project), the migration incorrectly
applies the code transformation multiple times. This is because the migration
is currently based on the source file contents in the file system, while the
actual source file contents could have already changed in the devkit schematic
tree.

PR Close #29133
This commit is contained in:
Paul Gschwendtner 2019-03-09 15:51:33 +01:00 committed by Kara Erickson
parent 3c53713616
commit fca1724ebf
2 changed files with 35 additions and 0 deletions

View File

@ -25,6 +25,16 @@ import {parseTsconfigFile} from './typescript/tsconfig';
export function runStaticQueryMigration(tree: Tree, tsconfigPath: string, basePath: string) {
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
const host = ts.createCompilerHost(parsed.options, true);
// We need to overwrite the host "readFile" method, as we want the TypeScript
// program to be based on the file contents in the virtual file tree. Otherwise
// if we run the migration for multiple tsconfig files which have intersecting
// source files, it can end up updating query definitions multiple times.
host.readFile = fileName => {
const buffer = tree.read(relative(basePath, fileName));
return buffer ? buffer.toString() : undefined;
};
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
const typeChecker = program.getTypeChecker();
const queryVisitor = new NgQueryResolveVisitor(typeChecker);

View File

@ -710,5 +710,30 @@ describe('static-queries migration', () => {
expect(tree.readContent('/index.ts'))
.toContain(`@${queryType}('test', { static: true }) query2: any;`);
});
it('should properly handle multiple tsconfig files', () => {
writeFile('/src/index.ts', `
import {Component, ${queryType}} from '@angular/core';
@Component({template: '<span #test></span>'})
export class MyComp {
private @${queryType}('test') query: any;
}
`);
writeFile('/src/tsconfig.json', JSON.stringify({
compilerOptions: {
lib: ['es2015'],
}
}));
// The migration runs for "/tsconfig.json" and "/src/tsconfig.json" which both
// contain the "src/index.ts" file. This test ensures that we don't incorrectly
// apply the code transformation multiple times with outdated offsets.
runMigration();
expect(tree.readContent('/src/index.ts'))
.toContain(`@${queryType}('test', { static: false }) query: any;`);
});
}
});