diff --git a/packages/nx/schemas/nx-schema.json b/packages/nx/schemas/nx-schema.json index 0d8e145aaf..49a15ae93a 100644 --- a/packages/nx/schemas/nx-schema.json +++ b/packages/nx/schemas/nx-schema.json @@ -282,6 +282,13 @@ "applyChanges": { "type": "boolean", "description": "Whether to automatically apply sync generator changes when running tasks. If not set, the user will be prompted. If set to `true`, the user will not be prompted and the changes will be applied. If set to `false`, the user will not be prompted and the changes will not be applied." + }, + "disabledTaskSyncGenerators": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of registered task sync generators to disable." } }, "additionalProperties": false diff --git a/packages/nx/src/command-line/sync/sync.ts b/packages/nx/src/command-line/sync/sync.ts index 4f35112af5..049f125318 100644 --- a/packages/nx/src/command-line/sync/sync.ts +++ b/packages/nx/src/command-line/sync/sync.ts @@ -1,4 +1,5 @@ import * as ora from 'ora'; +import { readNxJson } from '../../config/nx-json'; import { createProjectGraphAsync } from '../../project-graph/project-graph'; import { output } from '../../utils/output'; import { handleErrors } from '../../utils/params'; @@ -18,9 +19,22 @@ interface SyncOptions extends SyncArgs { export function syncHandler(options: SyncOptions): Promise { return handleErrors(options.verbose, async () => { const projectGraph = await createProjectGraphAsync(); + const nxJson = readNxJson(); const syncGenerators = await collectAllRegisteredSyncGenerators( - projectGraph + projectGraph, + nxJson ); + + if (!syncGenerators.length) { + output.success({ + title: options.check + ? 'The workspace is up to date' + : 'The workspace is already up to date', + bodyLines: ['There are no sync generators to run.'], + }); + return 0; + } + const results = await getSyncGeneratorChanges(syncGenerators); if (!results.length) { diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index fa97fffb61..d91140661c 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -321,11 +321,16 @@ export interface NxSyncConfiguration { /** * Whether to automatically apply sync generator changes when running tasks. - * If not set, the user will be prompted. + * If not set, the user will be prompted in interactive mode. * If set to `true`, the user will not be prompted and the changes will be applied. * If set to `false`, the user will not be prompted and the changes will not be applied. */ applyChanges?: boolean; + + /** + * List of registered task sync generators to disable. + */ + disabledTaskSyncGenerators?: string[]; } /** diff --git a/packages/nx/src/daemon/server/sync-generators.ts b/packages/nx/src/daemon/server/sync-generators.ts index 0f17fb2149..9c3c7843cc 100644 --- a/packages/nx/src/daemon/server/sync-generators.ts +++ b/packages/nx/src/daemon/server/sync-generators.ts @@ -5,8 +5,8 @@ import { FsTree } from '../../generators/tree'; import { hashArray } from '../../hasher/file-hasher'; import { readProjectsConfigurationFromProjectGraph } from '../../project-graph/project-graph'; import { + collectEnabledTaskSyncGeneratorsFromProjectGraph, collectRegisteredGlobalSyncGenerators, - collectRegisteredTaskSyncGenerators, flushSyncGeneratorChanges, runSyncGenerator, type SyncGeneratorChangesResult, @@ -28,6 +28,7 @@ let registeredSyncGenerators: Set | undefined; let scheduledTimeoutId: NodeJS.Timeout | undefined; let storedProjectGraphHash: string | undefined; let storedNxJsonHash: string | undefined; +let storedDisabledTaskSyncGeneratorsHash: string | undefined; const log = (...messageParts: unknown[]) => { serverLogger.log('[SYNC]:', ...messageParts); @@ -146,6 +147,12 @@ export function collectAndScheduleSyncGenerators( // a change imply we need to re-run all the generators // make sure to schedule all the collected generators scheduledGenerators.clear(); + + if (!registeredSyncGenerators.size) { + // there are no generators to run + return; + } + for (const generator of registeredSyncGenerators) { scheduledGenerators.add(generator); } @@ -193,16 +200,23 @@ export async function getCachedRegisteredSyncGenerators(): Promise { } function collectAllRegisteredSyncGenerators(projectGraph: ProjectGraph): void { + const nxJson = readNxJson(); const projectGraphHash = hashProjectGraph(projectGraph); - if (storedProjectGraphHash !== projectGraphHash) { + const disabledTaskSyncGeneratorsHash = hashArray( + nxJson.sync?.disabledTaskSyncGenerators?.sort() ?? [] + ); + if ( + projectGraphHash !== storedProjectGraphHash || + disabledTaskSyncGeneratorsHash !== storedDisabledTaskSyncGeneratorsHash + ) { storedProjectGraphHash = projectGraphHash; + storedDisabledTaskSyncGeneratorsHash = disabledTaskSyncGeneratorsHash; registeredTaskSyncGenerators = - collectRegisteredTaskSyncGenerators(projectGraph); + collectEnabledTaskSyncGeneratorsFromProjectGraph(projectGraph, nxJson); } else { log('project graph hash is the same, not collecting task sync generators'); } - const nxJson = readNxJson(); const nxJsonHash = hashArray(nxJson.sync?.globalGenerators?.sort() ?? []); if (storedNxJsonHash !== nxJsonHash) { storedNxJsonHash = nxJsonHash; diff --git a/packages/nx/src/tasks-runner/run-command.ts b/packages/nx/src/tasks-runner/run-command.ts index f6c774b754..c249dcc17c 100644 --- a/packages/nx/src/tasks-runner/run-command.ts +++ b/packages/nx/src/tasks-runner/run-command.ts @@ -21,6 +21,7 @@ import { isNxCloudUsed } from '../utils/nx-cloud-utils'; import { output } from '../utils/output'; import { handleErrors } from '../utils/params'; import { + collectEnabledTaskSyncGeneratorsFromTaskGraph, flushSyncGeneratorChanges, getSyncGeneratorChanges, syncGeneratorResultsToMessageLines, @@ -233,18 +234,11 @@ async function ensureWorkspaceIsInSyncAndGetGraphs( ); // collect unique syncGenerators from the tasks - const uniqueSyncGenerators = new Set(); - for (const { target } of Object.values(taskGraph.tasks)) { - const { syncGenerators } = - projectGraph.nodes[target.project].data.targets[target.target]; - if (!syncGenerators) { - continue; - } - - for (const generator of syncGenerators) { - uniqueSyncGenerators.add(generator); - } - } + const uniqueSyncGenerators = collectEnabledTaskSyncGeneratorsFromTaskGraph( + taskGraph, + projectGraph, + nxJson + ); if (!uniqueSyncGenerators.size) { // There are no sync generators registered in the tasks to run diff --git a/packages/nx/src/utils/sync-generators.ts b/packages/nx/src/utils/sync-generators.ts index 93a64bad26..0faf492928 100644 --- a/packages/nx/src/utils/sync-generators.ts +++ b/packages/nx/src/utils/sync-generators.ts @@ -2,8 +2,9 @@ import { performance } from 'perf_hooks'; import { parseGeneratorString } from '../command-line/generate/generate'; import { getGeneratorInformation } from '../command-line/generate/generator-utils'; import type { GeneratorCallback } from '../config/misc-interfaces'; -import { readNxJson } from '../config/nx-json'; +import { readNxJson, type NxJsonConfiguration } from '../config/nx-json'; import type { ProjectGraph } from '../config/project-graph'; +import type { TaskGraph } from '../config/task-graph'; import type { ProjectConfiguration } from '../config/workspace-json-project-json'; import { daemonClient } from '../daemon/client/client'; import { isOnDaemon } from '../daemon/is-on-daemon'; @@ -72,11 +73,12 @@ export async function flushSyncGeneratorChanges( } export async function collectAllRegisteredSyncGenerators( - projectGraph: ProjectGraph + projectGraph: ProjectGraph, + nxJson: NxJsonConfiguration ): Promise { if (!daemonClient.enabled()) { return [ - ...collectRegisteredTaskSyncGenerators(projectGraph), + ...collectEnabledTaskSyncGeneratorsFromProjectGraph(projectGraph, nxJson), ...collectRegisteredGlobalSyncGenerators(), ]; } @@ -122,10 +124,14 @@ export async function runSyncGenerator( }; } -export function collectRegisteredTaskSyncGenerators( - projectGraph: ProjectGraph +export function collectEnabledTaskSyncGeneratorsFromProjectGraph( + projectGraph: ProjectGraph, + nxJson: NxJsonConfiguration ): Set { const taskSyncGenerators = new Set(); + const disabledTaskSyncGenerators = new Set( + nxJson.sync?.disabledTaskSyncGenerators ?? [] + ); for (const { data: { targets }, @@ -135,11 +141,46 @@ export function collectRegisteredTaskSyncGenerators( } for (const target of Object.values(targets)) { - if (!target.syncGenerators) { + if (!target.syncGenerators?.length) { continue; } for (const generator of target.syncGenerators) { + if ( + !disabledTaskSyncGenerators.has(generator) && + !taskSyncGenerators.has(generator) + ) { + taskSyncGenerators.add(generator); + } + } + } + } + + return taskSyncGenerators; +} + +export function collectEnabledTaskSyncGeneratorsFromTaskGraph( + taskGraph: TaskGraph, + projectGraph: ProjectGraph, + nxJson: NxJsonConfiguration +): Set { + const taskSyncGenerators = new Set(); + const disabledTaskSyncGenerators = new Set( + nxJson.sync?.disabledTaskSyncGenerators ?? [] + ); + + for (const { target } of Object.values(taskGraph.tasks)) { + const { syncGenerators } = + projectGraph.nodes[target.project].data.targets[target.target]; + if (!syncGenerators?.length) { + continue; + } + + for (const generator of syncGenerators) { + if ( + !disabledTaskSyncGenerators.has(generator) && + !taskSyncGenerators.has(generator) + ) { taskSyncGenerators.add(generator); } }