diff --git a/src/cdk/schematics/update-tool/index.ts b/src/cdk/schematics/update-tool/index.ts index b2561a542f6f..7e60e21190b9 100644 --- a/src/cdk/schematics/update-tool/index.ts +++ b/src/cdk/schematics/update-tool/index.ts @@ -50,13 +50,17 @@ export class UpdateProject { * @param data Upgrade data that is passed to all migration rules. * @param additionalStylesheetPaths Additional stylesheets that should be migrated, if not * referenced in an Angular component. This is helpful for global stylesheets in a project. + * @param limitToDirectory If specified, changes will be limited to the given directory. */ migrate( migrationTypes: MigrationCtor[], target: TargetVersion | null, data: Data, additionalStylesheetPaths?: string[], + limitToDirectory?: string, ): {hasFailures: boolean} { + limitToDirectory &&= this._fileSystem.resolve(limitToDirectory); + // Create instances of the specified migrations. const migrations = this._createMigrations(migrationTypes, target, data); // Creates the component resource collector. The collector can visit arbitrary @@ -65,9 +69,14 @@ export class UpdateProject { const resourceCollector = new ComponentResourceCollector(this._typeChecker, this._fileSystem); // Collect all of the TypeScript source files we want to migrate. We don't // migrate type definition files, or source files from external libraries. - const sourceFiles = this._program - .getSourceFiles() - .filter(f => !f.isDeclarationFile && !this._program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = this._program.getSourceFiles().filter(f => { + return ( + !f.isDeclarationFile && + (limitToDirectory == null || + this._fileSystem.resolve(f.fileName).startsWith(limitToDirectory)) && + !this._program.isSourceFileFromExternalLibrary(f) + ); + }); // Helper function that visits a given TypeScript node and collects all referenced // component resources (i.e. stylesheets or templates). Additionally, the helper @@ -121,11 +130,13 @@ export class UpdateProject { if (additionalStylesheetPaths) { additionalStylesheetPaths.forEach(filePath => { const resolvedPath = this._fileSystem.resolve(filePath); - const stylesheet = resourceCollector.resolveExternalStylesheet(resolvedPath, null); - // Do not visit stylesheets which have been referenced from a component. - if (!this._analyzedFiles.has(resolvedPath) && stylesheet) { - migrations.forEach(r => r.visitStylesheet(stylesheet)); - this._analyzedFiles.add(resolvedPath); + if (limitToDirectory == null || resolvedPath.startsWith(limitToDirectory)) { + const stylesheet = resourceCollector.resolveExternalStylesheet(resolvedPath, null); + // Do not visit stylesheets which have been referenced from a component. + if (!this._analyzedFiles.has(resolvedPath) && stylesheet) { + migrations.forEach(r => r.visitStylesheet(stylesheet)); + this._analyzedFiles.add(resolvedPath); + } } }); } diff --git a/src/material/schematics/ng-generate/mdc-migration/index.ts b/src/material/schematics/ng-generate/mdc-migration/index.ts index e59143924d59..62d9c28fa7e6 100644 --- a/src/material/schematics/ng-generate/mdc-migration/index.ts +++ b/src/material/schematics/ng-generate/mdc-migration/index.ts @@ -68,6 +68,7 @@ function runMigrations( migrators: ComponentMigrator[], analyzedFiles: Set, additionalStylesheetPaths: string[], + limitToDirectory?: string, ): boolean { const program = UpdateProject.createProgramFromTsconfig(tsconfigPath, fileSystem); const project = new UpdateProject(context, program, fileSystem, analyzedFiles, context.logger); @@ -76,6 +77,7 @@ function runMigrations( null, migrators, additionalStylesheetPaths, + limitToDirectory, ).hasFailures; } @@ -93,11 +95,11 @@ export default function (options: Schema): Rule { const analyzedFiles = new Set(); const componentsToMigrate = getComponentsToMigrate(options.components); const migrators = MIGRATORS.filter(m => componentsToMigrate.has(m.component)); - let additionalStylesheetPaths = options.directory - ? findStylesheetFiles(tree, options.directory) - : []; let success = true; + if (options.directory) { + logger.info(`Limiting migration to: ${options.directory}`); + } logger.info(`Migrating components:\n${[...componentsToMigrate].join('\n')}`); for (const projectName of projectNames) { @@ -114,9 +116,7 @@ export default function (options: Schema): Rule { continue; } - if (!options.directory) { - additionalStylesheetPaths = findStylesheetFiles(tree, project.root); - } + const additionalStylesheetPaths = findStylesheetFiles(tree, project.root); logger.info(`Migrating project: ${projectName}`); @@ -128,6 +128,7 @@ export default function (options: Schema): Rule { migrators, analyzedFiles, additionalStylesheetPaths, + options.directory || undefined, ); } } diff --git a/src/material/schematics/ng-generate/mdc-migration/schema.d.ts b/src/material/schematics/ng-generate/mdc-migration/schema.d.ts index f7a47cfebc87..7dafeb963e4e 100644 --- a/src/material/schematics/ng-generate/mdc-migration/schema.d.ts +++ b/src/material/schematics/ng-generate/mdc-migration/schema.d.ts @@ -13,7 +13,7 @@ export interface Schema { * Source files determined outside of this directory will be ignored, * allowing for an incremental migration. * - * If not set, the directory is determined based on the specified tsconfig. + * If not set, the directory is determined based on the workspace. */ directory?: string; diff --git a/src/material/schematics/ng-generate/mdc-migration/schema.json b/src/material/schematics/ng-generate/mdc-migration/schema.json index a8366d04a8b9..1cb4331cf700 100644 --- a/src/material/schematics/ng-generate/mdc-migration/schema.json +++ b/src/material/schematics/ng-generate/mdc-migration/schema.json @@ -9,7 +9,7 @@ "format": "path", "description": "Workspace-relative path to a directory which will be migrated.", "alias": "d", - "default": "" + "x-prompt": "Limit the migration to a specific directory? (Enter directory or leave blank for all directories)" }, "components": { "type": "array",