fix(core): tree should not be changed after committed to disk in migrations (#17071)

This commit is contained in:
Craigory Coppola 2023-05-23 17:07:08 -04:00 committed by GitHub
parent d20c2d8492
commit f95f8c4b69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 22 deletions

View File

@ -656,7 +656,11 @@ export async function generate(
const logger = getLogger(verbose);
const fsHost = new NxScopeHostUsedForWrappedSchematics(
root,
new FsTree(root, verbose)
new FsTree(
root,
verbose,
`ng-cli generator: ${opts.collectionName}:${opts.generatorName}`
)
);
const workflow = createWorkflow(fsHost, root, opts);
const collection = getCollection(workflow, opts.collectionName);
@ -745,7 +749,11 @@ export async function runMigration(
const logger = getLogger(isVerbose);
const fsHost = new NxScopeHostUsedForWrappedSchematics(
root,
new FsTree(root, isVerbose)
new FsTree(
root,
isVerbose,
`ng-cli migration: ${packageName}:${migrationName}`
)
);
const workflow = createWorkflow(fsHost, root, {});
const collection = resolveMigrationsCollection(packageName);

View File

@ -364,7 +364,11 @@ export async function generate(cwd: string, args: { [k: string]: any }) {
);
if (ws.isNxGenerator(opts.collectionName, normalizedGeneratorName)) {
const host = new FsTree(workspaceRoot, verbose);
const host = new FsTree(
workspaceRoot,
verbose,
`generating (${opts.collectionName}:${normalizedGeneratorName})`
);
const implementation = implementationFactory();
// @todo(v17): Remove this, isStandalonePreset property is defunct.

View File

@ -33,7 +33,7 @@ path_to_root=$(dirname $BASH_SOURCE)
node ${path.posix.join('$path_to_root', nxWrapperPath(path.posix))} $@`;
export function generateDotNxSetup(version?: string) {
const host = new FsTree(process.cwd(), false);
const host = new FsTree(process.cwd(), false, '.nx setup');
writeMinimalNxJson(host, version);
updateGitIgnore(host);
host.write(nxWrapperPath(), getNxWrapperContents());

View File

@ -1578,7 +1578,11 @@ async function runNxMigration(
name
);
const fn = require(implPath)[fnSymbol];
const host = new FsTree(root, process.env.NX_VERBOSE_LOGGING === 'true');
const host = new FsTree(
root,
process.env.NX_VERBOSE_LOGGING === 'true',
`migration ${collection.name}:${name}`
);
await fn(host, {});
host.lock();
const changes = host.listChanges();

View File

@ -33,7 +33,7 @@ export async function newWorkspace(cwd: string, args: { [k: string]: any }) {
false
);
const host = new FsTree(cwd, false);
const host = new FsTree(cwd, false, 'nx new');
const implementation = implementationFactory();
const task = await implementation(host, combinedOpts);
flushChanges(cwd, host.listChanges());

View File

@ -138,7 +138,11 @@ export class FsTree implements Tree {
*/
private locked = false;
constructor(readonly root: string, private readonly isVerbose: boolean) {}
constructor(
readonly root: string,
private readonly isVerbose: boolean,
private readonly logOperationId?: string
) {}
read(filePath: string): Buffer | null;
read(filePath: string, encoding: BufferEncoding): string | null;
@ -357,20 +361,15 @@ export class FsTree implements Tree {
private assertUnlocked() {
if (this.locked) {
// TODO (v17): Remove condition
if (gt(nxVersion, '17.0.0')) {
throw new Error(
'The tree has already been committed to disk. It can no longer be modified. Do not modify the tree during a GeneratorCallback and ensure that Promises have resolved before the generator returns or resolves.'
);
} else {
output.warn({
title: 'Tree modified after commit to disk.',
bodyLines: [
'The tree has already been committed to disk. It can no longer be modified. Do not modify the tree during a GeneratorCallback and ensure that Promises have resolved before the generator returns or resolves.',
`This will be an error in version 16. Please open an issue on the Nx repo if experiencing this with a first-party plugin, or the plugin's repo if using a community plugin.`,
],
});
}
output.error({
title: `File changes have already been written to disk. Further changes were attempted ${
this.logOperationId ? ` while running ${this.logOperationId}.` : '.'
}`,
bodyLines: [
'The file system can no longer be modified. This commonly happens when a generator attempts to make further changes in its callback, or an asynchronous operation is still running after the generator completes.',
],
});
throw new Error('Tree changed after commit to disk.');
}
}

View File

@ -63,7 +63,7 @@ export default async function (tree: Tree) {
}
}
formatChangedFilesWithPrettierIfAvailable(tree);
await formatChangedFilesWithPrettierIfAvailable(tree);
}
function updateDependsOnAndInputsInsideNxJson(tree: Tree) {
const nxJson = readNxJson(tree);