Skip to content

refactor(schematics): avoid typescript version conflicts #12989

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

Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ jobs:
<<: *post_checkout
- restore_cache:
key: *cache_key
- run: echo "Temporarily disabled until Bazel setup can be fixed"

- run: bazel run @nodejs//:npm install
# TODO(jelbourn): Update this command to run all tests if the Bazel issues have been fixed.
- run: bazel test src/lib/schematics:unit_tests

- save_cache:
key: *cache_key
paths:
Expand Down
10 changes: 5 additions & 5 deletions src/lib/schematics/utils/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import {InsertChange} from '@schematics/angular/utility/change';
import {getWorkspace, WorkspaceProject} from '@schematics/angular/utility/config';
import {findModuleFromOptions as internalFindModule} from '@schematics/angular/utility/find-module';
import {getAppModulePath} from '@schematics/angular/utility/ng-ast-utils';
import * as ts from 'typescript';
import {getProjectMainFile} from './project-main-file';

import {ts} from './version-agnostic-typescript';

/** Reads file given path and returns TypeScript source file. */
export function getSourceFile(host: Tree, path: string): ts.SourceFile {
export function getSourceFile(host: Tree, path: string) {
const buffer = host.read(path);
if (!buffer) {
throw new SchematicsException(`Could not find file for path: ${path}`);
Expand Down Expand Up @@ -50,8 +49,9 @@ export function addModuleImportToModule(host: Tree, modulePath: string, moduleNa
throw new SchematicsException(`Module not found: ${modulePath}`);
}

// TODO: cast to any, because the types for ts.SourceFile
// aren't compatible with `strictFunctionTypes`.
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
// that is a type signature mismatch at compilation which is not valid.
const changes = addImportToModule(moduleSource as any, modulePath, moduleName, src);
const recorder = host.beginUpdate(modulePath);

Expand Down
32 changes: 19 additions & 13 deletions src/lib/schematics/utils/build-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,17 @@ import {buildDefaultPath} from '@schematics/angular/utility/project';
import {validateHtmlSelector, validateName} from '@schematics/angular/utility/validation';
import {readFileSync} from 'fs';
import {dirname, join, resolve} from 'path';
import * as ts from 'typescript';
import {getProjectFromWorkspace} from './get-project';
import {getDefaultComponentOptions} from './schematic-options';
import {ts} from './version-agnostic-typescript';

function readIntoSourceFile(host: Tree, modulePath: string): ts.SourceFile {
function readIntoSourceFile(host: Tree, modulePath: string) {
const text = host.read(modulePath);
if (text === null) {
throw new SchematicsException(`File ${modulePath} does not exist.`);
}
const sourceText = text.toString('utf-8');

return ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
return ts.createSourceFile(modulePath, text.toString('utf-8'), ts.ScriptTarget.Latest, true);
}

function addDeclarationToNgModule(options: ComponentOptions): Rule {
Expand All @@ -68,9 +67,11 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
const relativePath = buildRelativePath(modulePath, componentPath);
const classifiedName = strings.classify(`${options.name}Component`);

// TODO: cast to any, because the types for ts.SourceFile
// aren't compatible with `strictFunctionTypes`.
const declarationChanges = addDeclarationToModule(source as any,
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
// that is a type signature mismatch at compilation which is not valid.
const declarationChanges = addDeclarationToModule(
source as any,
modulePath,
classifiedName,
relativePath);
Expand All @@ -88,9 +89,12 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
const source = readIntoSourceFile(host, modulePath);
const exportRecorder = host.beginUpdate(modulePath);

// TODO: cast to any, because the types for ts.SourceFile
// aren't compatible with `strictFunctionTypes`.
const exportChanges = addExportToModule(source as any, modulePath,
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
// that is a type signature mismatch at compilation which is not valid.
const exportChanges = addExportToModule(
source as any,
modulePath,
strings.classify(`${options.name}Component`),
relativePath);

Expand All @@ -107,10 +111,12 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
const source = readIntoSourceFile(host, modulePath);
const entryComponentRecorder = host.beginUpdate(modulePath);

// TODO: cast to any, because the types for ts.SourceFile
// aren't compatible with `strictFunctionTypes`.
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
// that is a type signature mismatch at compilation which is not valid.
const entryComponentChanges = addEntryComponentToModule(
source as any, modulePath,
source as any,
modulePath,
strings.classify(`${options.name}Component`),
relativePath);

Expand Down
33 changes: 33 additions & 0 deletions src/lib/schematics/utils/version-agnostic-typescript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

/** This is just a type import and won't be generated in the release output. */
import typescript = require('@schematics/angular/node_modules/typescript');

/**
* This is an agnostic re-export of TypeScript. Depending on the context, this module file will
* return the TypeScript version that is being shipped within the `@schematics/angular` package,
* or fall back to the TypeScript version that has been flattened in the node modules.
*
* This is necessary because we parse TypeScript files and pass the resolved AST to the
* `@schematics/angular` package which might have a different TypeScript version installed.
*/
let ts: typeof typescript;

try {
ts = require('@schematics/angular/node_modules/typescript');
} catch {
try {
ts = require('typescript');
} catch {
throw new Error('Error: Could not find TypeScript for the Angular Material schematics. ' +
'Please report an issue on the Angular Material repository.');
}
}

export {ts};