fix(core): target defaults should be able to apply to multiple targets with the same executor (#21438)

This commit is contained in:
Craigory Coppola 2024-02-01 18:30:43 -06:00 committed by GitHub
parent 2781800e36
commit c4b9a82319
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 110 additions and 33 deletions

View File

@ -233,4 +233,67 @@ describe('target-defaults plugin', () => {
} }
`); `);
}); });
describe('executor key', () => {
it('should support multiple targets with the same executor', () => {
memfs.vol.fromJSON(
{
'project.json': JSON.stringify({
name: 'root',
targets: {
echo: {
executor: 'nx:run-commands',
options: {
command: 'echo 1',
},
},
echo2: {
executor: 'nx:run-commands',
options: {
command: 'echo 2',
},
},
},
}),
},
'/root'
);
context.nxJsonConfiguration.targetDefaults = {
'nx:run-commands': {
options: {
cwd: '{projectRoot}',
},
},
};
expect(createNodesFn('project.json', undefined, context))
.toMatchInlineSnapshot(`
{
"projects": {
".": {
"targets": {
"echo": {
"options": {
"cwd": "{projectRoot}",
},
},
"echo2": {
"options": {
"cwd": "{projectRoot}",
},
},
"nx:run-commands": {
"options": {
"cwd": "{projectRoot}",
},
Symbol(ONLY_MODIFIES_EXISTING_TARGET): true,
},
},
},
},
}
`);
});
});
}); });

View File

@ -67,6 +67,7 @@ export const TargetDefaultsPlugin: NxPluginV2 = {
return true; return true;
}), }),
...Object.keys(projectJson?.targets ?? {}), ...Object.keys(projectJson?.targets ?? {}),
...Object.keys(packageJson?.nx?.targets ?? {}),
]); ]);
const executorToTargetMap = getExecutorToTargetMap( const executorToTargetMap = getExecutorToTargetMap(
@ -74,27 +75,31 @@ export const TargetDefaultsPlugin: NxPluginV2 = {
projectJson projectJson
); );
const newTargets: Record< const modifiedTargets: Record<
string, string,
TargetConfiguration & { [ONLY_MODIFIES_EXISTING_TARGET]?: boolean } TargetConfiguration & { [ONLY_MODIFIES_EXISTING_TARGET]?: boolean }
> = {}; > = {};
for (const defaultSpecifier in targetDefaults) { for (const defaultSpecifier in targetDefaults) {
const targetName = const targetNames =
executorToTargetMap.get(defaultSpecifier) ?? defaultSpecifier; executorToTargetMap.get(defaultSpecifier) ?? new Set();
newTargets[targetName] = structuredClone( targetNames.add(defaultSpecifier);
targetDefaults[defaultSpecifier]
); for (const targetName of targetNames) {
// TODO: Remove this after we figure out a way to define new targets modifiedTargets[targetName] = structuredClone(
// in target defaults targetDefaults[defaultSpecifier]
if (!projectDefinedTargets.has(targetName)) { );
newTargets[targetName][ONLY_MODIFIES_EXISTING_TARGET] = true; // TODO: Remove this after we figure out a way to define new targets
// in target defaults
if (!projectDefinedTargets.has(targetName)) {
modifiedTargets[targetName][ONLY_MODIFIES_EXISTING_TARGET] = true;
}
} }
} }
return { return {
projects: { projects: {
[root]: { [root]: {
targets: newTargets, targets: modifiedTargets,
}, },
}, },
}; };
@ -106,20 +111,20 @@ function getExecutorToTargetMap(
packageJson: PackageJson, packageJson: PackageJson,
projectJson: ProjectConfiguration projectJson: ProjectConfiguration
) { ) {
const executorToTargetMap = new Map<string, string>(); const executorToTargetMap = new Map<string, Set<string>>();
if (packageJson?.scripts) { const targets = Object.keys({
for (const script in packageJson.scripts) { ...projectJson?.targets,
executorToTargetMap.set('nx:run-script', script); ...packageJson?.scripts,
} ...packageJson?.nx?.targets,
} });
if (projectJson?.targets) { for (const target of targets) {
for (const target in projectJson.targets) { const executor =
if (projectJson.targets[target].executor) { projectJson?.targets?.[target]?.executor ??
executorToTargetMap.set(projectJson.targets[target].executor, target); packageJson?.nx?.targets?.[target]?.executor ??
} else if (projectJson.targets[target].command) { 'nx:run-script';
executorToTargetMap.set('nx:run-commands', target); const targetsForExecutor = executorToTargetMap.get(executor) ?? new Set();
} targetsForExecutor.add(target);
} executorToTargetMap.set(executor, targetsForExecutor);
} }
return executorToTargetMap; return executorToTargetMap;
} }

View File

@ -403,6 +403,21 @@ describe('project-configuration-utils', () => {
`); `);
}); });
}); });
describe('cache', () => {
it('should not be merged for incompatible targets', () => {
const result = mergeTargetConfigurations(
{
executor: 'foo',
},
{
executor: 'bar',
cache: true,
}
);
expect(result.cache).not.toBeDefined();
});
});
}); });
describe('mergeProjectConfigurationIntoRootMap', () => { describe('mergeProjectConfigurationIntoRootMap', () => {

View File

@ -4,7 +4,6 @@ import { readJsonFile } from './fileutils';
import { import {
buildTargetFromScript, buildTargetFromScript,
PackageJson, PackageJson,
PackageJsonTargetConfiguration,
readModulePackageJson, readModulePackageJson,
readTargetsFromPackageJson, readTargetsFromPackageJson,
} from './package-json'; } from './package-json';
@ -36,7 +35,7 @@ describe('buildTargetFromScript', () => {
script: 'other', script: 'other',
}, },
executor: 'custom:execute', executor: 'custom:execute',
} as PackageJsonTargetConfiguration, },
}, },
}); });

View File

@ -7,16 +7,11 @@ import {
import { readJsonFile } from './fileutils'; import { readJsonFile } from './fileutils';
import { getNxRequirePaths } from './installation-directory'; import { getNxRequirePaths } from './installation-directory';
export type PackageJsonTargetConfiguration = Omit<
TargetConfiguration,
'executor'
>;
export interface NxProjectPackageJsonConfiguration { export interface NxProjectPackageJsonConfiguration {
implicitDependencies?: string[]; implicitDependencies?: string[];
tags?: string[]; tags?: string[];
namedInputs?: { [inputName: string]: (string | InputDefinition)[] }; namedInputs?: { [inputName: string]: (string | InputDefinition)[] };
targets?: Record<string, PackageJsonTargetConfiguration>; targets?: Record<string, TargetConfiguration>;
includedScripts?: string[]; includedScripts?: string[];
} }