Skip to content

Commit

Permalink
feat(core): allow disabling registered task sync generators (#27638)
Browse files Browse the repository at this point in the history
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

There's no way to disable sync generators registered in inferred tasks
by a Crystal plugin.

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

There should be a way to disable sync generators registered in inferred
tasks by a Crystal plugin.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
<!-- Fixes NXC-904 -->

Fixes #
  • Loading branch information
leosvelperez authored Aug 28, 2024
1 parent a0dc0f1 commit 97fa7f1
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 24 deletions.
7 changes: 7 additions & 0 deletions packages/nx/schemas/nx-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 15 additions & 1 deletion packages/nx/src/command-line/sync/sync.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -18,9 +19,22 @@ interface SyncOptions extends SyncArgs {
export function syncHandler(options: SyncOptions): Promise<number> {
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) {
Expand Down
7 changes: 6 additions & 1 deletion packages/nx/src/config/nx-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
}

/**
Expand Down
22 changes: 18 additions & 4 deletions packages/nx/src/daemon/server/sync-generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -28,6 +28,7 @@ let registeredSyncGenerators: Set<string> | 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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -193,16 +200,23 @@ export async function getCachedRegisteredSyncGenerators(): Promise<string[]> {
}

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;
Expand Down
18 changes: 6 additions & 12 deletions packages/nx/src/tasks-runner/run-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -233,18 +234,11 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(
);

// collect unique syncGenerators from the tasks
const uniqueSyncGenerators = new Set<string>();
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
Expand Down
53 changes: 47 additions & 6 deletions packages/nx/src/utils/sync-generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -72,11 +73,12 @@ export async function flushSyncGeneratorChanges(
}

export async function collectAllRegisteredSyncGenerators(
projectGraph: ProjectGraph
projectGraph: ProjectGraph,
nxJson: NxJsonConfiguration
): Promise<string[]> {
if (!daemonClient.enabled()) {
return [
...collectRegisteredTaskSyncGenerators(projectGraph),
...collectEnabledTaskSyncGeneratorsFromProjectGraph(projectGraph, nxJson),
...collectRegisteredGlobalSyncGenerators(),
];
}
Expand Down Expand Up @@ -122,10 +124,14 @@ export async function runSyncGenerator(
};
}

export function collectRegisteredTaskSyncGenerators(
projectGraph: ProjectGraph
export function collectEnabledTaskSyncGeneratorsFromProjectGraph(
projectGraph: ProjectGraph,
nxJson: NxJsonConfiguration
): Set<string> {
const taskSyncGenerators = new Set<string>();
const disabledTaskSyncGenerators = new Set(
nxJson.sync?.disabledTaskSyncGenerators ?? []
);

for (const {
data: { targets },
Expand All @@ -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<string> {
const taskSyncGenerators = new Set<string>();
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);
}
}
Expand Down

0 comments on commit 97fa7f1

Please sign in to comment.