Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix(migrations): inject migration not work in multi-project workspace…#66130

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
aparzi wants to merge1 commit intoangular:main
base:main
Choose a base branch
Loading
fromaparzi:fix-inject-migration-multiple-project
Open
Show file tree
Hide file tree
Changes fromall 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
fix(migrations): inject migration not work in multi-project workspace…
… with option pathFix inject migration in multi-project workspace. The inject migration doesn't work when targeting one of the projects due to either not finding any files in other projects or considering them external thus it throws a SchematicsExceptionFixes:#66074
  • Loading branch information
@aparzi
aparzi committedDec 17, 2025
commitc6e07da13fe9c9e10776f0bae0c2ef7003ab4a0f
66 changes: 37 additions & 29 deletionspackages/core/schematics/ng-generate/inject-migration/index.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,8 +6,9 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {Rule, SchematicsException, Tree} from '@angular-devkit/schematics';
import {Rule,SchematicContext,SchematicsException, Tree} from '@angular-devkit/schematics';
import {join, relative} from 'path';
import ts from 'typescript';

import {normalizePath} from '../../utils/change_tracker';
import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host';
Expand All@@ -21,49 +22,54 @@ interface Options extends MigrationOptions {
}

export function migrate(options: Options): Rule {
return async (tree: Tree) => {
const {buildPaths, testPaths} = await getProjectTsConfigPaths(tree);
return async (tree: Tree, context: SchematicContext) => {
const basePath = process.cwd();
let pathToMigrate: string | undefined;
if (options.path) {
if (options.path.startsWith('..')) {
throw new SchematicsException(
'Cannot run inject migration outside of the current project.',
);
}
pathToMigrate = normalizePath(join(basePath, options.path));
}

const {buildPaths, testPaths} = await getProjectTsConfigPaths(tree);
const allPaths = [...buildPaths, ...testPaths];
const pathToMigrate = normalizePath(join(basePath, options.path));

if (!allPaths.length) {
throw new SchematicsException(
'Could not find any tsconfig file. Cannot run the inject migration.',
);
context.logger.warn('Could not find any tsconfig file. Cannot run the inject migration.');
return;
}

let sourceFilesCount = 0;

for (const tsconfigPath of allPaths) {
runInjectMigration(tree, tsconfigPath, basePath, pathToMigrate, options);
const program = createMigrationProgram(tree, tsconfigPath, basePath);
const sourceFiles = program
.getSourceFiles()
.filter(
(sourceFile) =>
(pathToMigrate ? sourceFile.fileName.startsWith(pathToMigrate) : true) &&
canMigrateFile(basePath, sourceFile, program),
);

sourceFilesCount += runInjectMigration(tree, sourceFiles, basePath, options);
}

if (sourceFilesCount === 0) {
context.logger.warn('Inject migration did not find any files to migrate');
}
};
}

function runInjectMigration(
tree: Tree,
tsconfigPath: string,
sourceFiles: ts.SourceFile[],
basePath: string,
pathToMigrate: string,
schematicOptions: Options,
): void {
if (schematicOptions.path.startsWith('..')) {
throw new SchematicsException('Cannot run inject migration outside of the current project.');
}

const program = createMigrationProgram(tree, tsconfigPath, basePath);
const sourceFiles = program
.getSourceFiles()
.filter(
(sourceFile) =>
sourceFile.fileName.startsWith(pathToMigrate) &&
canMigrateFile(basePath, sourceFile, program),
);

if (sourceFiles.length === 0) {
throw new SchematicsException(
`Could not find any files to migrate under the path ${pathToMigrate}. Cannot run the inject migration.`,
);
}
): number {
let migratedFiles = 0;

for (const sourceFile of sourceFiles) {
const changes = migrateFile(sourceFile, schematicOptions);
Expand All@@ -79,6 +85,8 @@ function runInjectMigration(
}

tree.commitUpdate(update);
migratedFiles++;
}
}
return migratedFiles;
}
70 changes: 70 additions & 0 deletionspackages/core/schematics/test/inject_migration_spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -411,6 +411,76 @@ describe('inject migration', () => {
]);
});

it('should migrate files present in other workspace projects', async () => {
writeFile('/tsconfig.json', '{}');

// Multiple projects...
writeFile(
'/angular.json',
JSON.stringify({
version: 1,
projects: {
app: {root: '', architect: {build: {options: {tsConfig: './tsconfig.json'}}}},
lib: {root: 'lib', architect: {build: {options: {tsConfig: './lib/tsconfig.json'}}}},
},
}),
);

// The lib tsconfig includes only its own folder so the second program does see the file.
writeFile('/lib/tsconfig.json', JSON.stringify({include: ['**/*.ts']}));

// File that should be migrated exists only under the second project's folder.
writeFile(
'/lib/should-migrate/dir.ts',
[
`import { Directive } from '@angular/core';`,
`import { Foo } from 'foo';`,
``,
`@Directive()`,
`class MyDir {`,
` constructor(private foo: Foo) {}`,
`}`,
].join('\n'),
);

// Unrelated file outside the specified path should remain unchanged.
writeFile(
'/other.ts',
[
`import { Directive } from '@angular/core';`,
`import { Foo } from 'foo';`,
``,
`@Directive()`,
`class Other {`,
` constructor(private foo: Foo) {}`,
`}`,
].join('\n'),
);

// Files should be migrated under the path
await runMigration({path: 'lib/should-migrate'});

expect(tree.readContent('/lib/should-migrate/dir.ts').split('\n')).toEqual([
`import { Directive, inject } from '@angular/core';`,
`import { Foo } from 'foo';`,
``,
`@Directive()`,
`class MyDir {`,
` private foo = inject(Foo);`,
`}`,
]);

expect(tree.readContent('/other.ts').split('\n')).toEqual([
`import { Directive } from '@angular/core';`,
`import { Foo } from 'foo';`,
``,
`@Directive()`,
`class Other {`,
` constructor(private foo: Foo) {}`,
`}`,
]);
});

it('should only migrate the specified file', async () => {
writeFile(
'/dir.ts',
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp