Skip to content

Commit f32c977

Browse files
committed
fix(ng-update): better detection for workspace project in v9 hammer migration
Currently the v9 HammerJS migration determines the workspace project by consulting the `ts.Program` that has been constructed. This logic is not guaranteed to work because a TypeScript program doesn't necessarily need to contain any "root" file names. This means that we cannot reliably determine the workspace project from the `ts.Program` and we will throw an error that no project could be found. We can improve this logic by simply using the workspace project that is associated with the originating tsconfig file. This was previously not possible, but 411d048 enabled us to pass through the workspace project. Fixes #18504.
1 parent 198911f commit f32c977

File tree

5 files changed

+28
-93
lines changed

5 files changed

+28
-93
lines changed

src/cdk/schematics/update-tool/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ export function runMigrationRules<T>(
5050
// Create instances of all specified migration rules.
5151
for (const ruleCtor of ruleTypes) {
5252
const rule = new ruleCtor(
53-
program, typeChecker, targetVersion, upgradeData, tree, getUpdateRecorder, basePath, logger,
54-
isTestTarget, tsconfigPath);
53+
project, program, typeChecker, targetVersion, upgradeData, tree, getUpdateRecorder,
54+
basePath, logger, isTestTarget, tsconfigPath);
5555
rule.init();
5656
if (rule.ruleEnabled) {
5757
rules.push(rule);

src/cdk/schematics/update-tool/migration-rule.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import {logging} from '@angular-devkit/core';
1010
import {SchematicContext, Tree, UpdateRecorder} from '@angular-devkit/schematics';
11+
import {WorkspaceProject} from '@schematics/angular/utility/workspace-models';
1112
import * as ts from 'typescript';
1213
import {ResolvedResource} from './component-resource-collector';
1314
import {TargetVersion} from './target-version';
@@ -32,6 +33,8 @@ export class MigrationRule<T> {
3233
ruleEnabled = true;
3334

3435
constructor(
36+
/** Workspace project the migration rule runs against. */
37+
public project: WorkspaceProject,
3538
/** TypeScript program for the migration. */
3639
public program: ts.Program,
3740
/** TypeChecker instance for the analysis program. */

src/material/schematics/ng-update/test-cases/v9/misc/hammer-migration-v9.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ describe('v9 HammerJS removal', () => {
3838
`);
3939
}
4040

41+
it('should not throw if project tsconfig does not have explicit root file names', async () => {
42+
await runner.runExternalSchematicAsync(
43+
'@schematics/angular', 'application', {name: 'second-project'}, tree).toPromise();
44+
writeFile('/projects/cdk-testing/tsconfig.app.json', JSON.stringify({
45+
extends: '../../tsconfig.json',
46+
compilerOptions: {
47+
outDir: '../../out-tsc/app',
48+
types: []
49+
}}
50+
));
51+
addPackageToPackageJson(tree, 'hammerjs', '0.0.0');
52+
await expectAsync(runMigration()).not.toBeRejected();
53+
});
54+
4155
describe('hammerjs not used', () => {
4256
it('should remove hammerjs from "package.json" file', async () => {
4357
addPackageToPackageJson(tree, 'hammerjs', '0.0.0');

src/material/schematics/ng-update/upgrade-rules/hammer-gestures-v9/cli-workspace.ts

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/material/schematics/ng-update/upgrade-rules/hammer-gestures-v9/hammer-gestures-rule.ts

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import {readFileSync} from 'fs';
3333
import {dirname, join, relative} from 'path';
3434
import * as ts from 'typescript';
3535

36-
import {getProjectFromProgram} from './cli-workspace';
3736
import {findHammerScriptImportElements} from './find-hammer-script-tags';
3837
import {findMainModuleExpression} from './find-main-module';
3938
import {isHammerJsUsedInTemplate} from './hammer-template-check';
@@ -242,8 +241,7 @@ export class HammerGesturesRule extends MigrationRule<null> {
242241
* 4) Setup the "HammerModule" in the root app module (if not done already).
243242
*/
244243
private _setupHammerWithCustomEvents() {
245-
const project = this._getProjectOrThrow();
246-
const sourceRoot = devkitNormalize(project.sourceRoot || project.root);
244+
const sourceRoot = devkitNormalize(this.project.sourceRoot || this.project.root);
247245
const newConfigPath =
248246
devkitJoin(sourceRoot, this._getAvailableGestureConfigFileName(sourceRoot));
249247

@@ -261,20 +259,18 @@ export class HammerGesturesRule extends MigrationRule<null> {
261259
// Setup the gesture config provider and the "HammerModule" in the root module
262260
// if not done already. The "HammerModule" is needed in v9 since it enables the
263261
// Hammer event plugin that was previously enabled by default in v8.
264-
this._setupNewGestureConfigInRootModule(project, newConfigPath);
265-
this._setupHammerModuleInRootModule(project);
262+
this._setupNewGestureConfigInRootModule(newConfigPath);
263+
this._setupHammerModuleInRootModule();
266264
}
267265

268266
/**
269267
* Sets up the standard hammer module in the project and removes all
270268
* references to the deprecated Angular Material gesture config.
271269
*/
272270
private _setupHammerWithStandardEvents() {
273-
const project = this._getProjectOrThrow();
274-
275271
// Setup the HammerModule. The HammerModule enables support for
276272
// the standard HammerJS events.
277-
this._setupHammerModuleInRootModule(project);
273+
this._setupHammerModuleInRootModule();
278274
this._removeMaterialGestureConfigSetup();
279275
}
280276

@@ -285,13 +281,11 @@ export class HammerGesturesRule extends MigrationRule<null> {
285281
* 3) Remove "hammerjs" from all index HTML files of the current project.
286282
*/
287283
private _removeHammerSetup() {
288-
const project = this._getProjectOrThrow();
289-
290284
this._installImports.forEach(i => this._importManager.deleteImportByDeclaration(i));
291285

292286
this._removeMaterialGestureConfigSetup();
293287
this._removeHammerModuleReferences();
294-
this._removeHammerFromIndexFile(project);
288+
this._removeHammerFromIndexFile(this.project);
295289
}
296290

297291
/**
@@ -645,8 +639,8 @@ export class HammerGesturesRule extends MigrationRule<null> {
645639
}
646640

647641
/** Sets up the Hammer gesture config in the root module if needed. */
648-
private _setupNewGestureConfigInRootModule(project: WorkspaceProject, gestureConfigPath: string) {
649-
const mainFilePath = join(this.basePath, getProjectMainFile(project));
642+
private _setupNewGestureConfigInRootModule(gestureConfigPath: string) {
643+
const mainFilePath = join(this.basePath, getProjectMainFile(this.project));
650644
const rootModuleSymbol = this._getRootModuleSymbol(mainFilePath);
651645

652646
if (rootModuleSymbol === null) {
@@ -722,8 +716,8 @@ export class HammerGesturesRule extends MigrationRule<null> {
722716
}
723717

724718
/** Sets up the "HammerModule" in the root module of the project. */
725-
private _setupHammerModuleInRootModule(project: WorkspaceProject) {
726-
const mainFilePath = join(this.basePath, getProjectMainFile(project));
719+
private _setupHammerModuleInRootModule() {
720+
const mainFilePath = join(this.basePath, getProjectMainFile(this.project));
727721
const rootModuleSymbol = this._getRootModuleSymbol(mainFilePath);
728722

729723
if (rootModuleSymbol === null) {
@@ -820,23 +814,6 @@ export class HammerGesturesRule extends MigrationRule<null> {
820814
});
821815
}
822816

823-
/**
824-
* Gets the project from the current program or throws if no project
825-
* could be found.
826-
*/
827-
private _getProjectOrThrow(): WorkspaceProject {
828-
const workspace = getWorkspace(this.tree);
829-
const project = getProjectFromProgram(workspace, this.program);
830-
831-
if (!project) {
832-
throw new SchematicsException(
833-
'Could not find project to perform HammerJS v9 migration. ' +
834-
'Please ensure your workspace configuration defines a project.');
835-
}
836-
837-
return project;
838-
}
839-
840817
/** Global state of whether Hammer is used in any analyzed project target. */
841818
static globalUsesHammer = false;
842819

0 commit comments

Comments
 (0)