fix(core): target defaults should be able to apply to multiple targets with the same executor (#21438)
This commit is contained in:
parent
2781800e36
commit
c4b9a82319
@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -67,6 +67,7 @@ export const TargetDefaultsPlugin: NxPluginV2 = {
|
||||
return true;
|
||||
}),
|
||||
...Object.keys(projectJson?.targets ?? {}),
|
||||
...Object.keys(packageJson?.nx?.targets ?? {}),
|
||||
]);
|
||||
|
||||
const executorToTargetMap = getExecutorToTargetMap(
|
||||
@ -74,27 +75,31 @@ export const TargetDefaultsPlugin: NxPluginV2 = {
|
||||
projectJson
|
||||
);
|
||||
|
||||
const newTargets: Record<
|
||||
const modifiedTargets: Record<
|
||||
string,
|
||||
TargetConfiguration & { [ONLY_MODIFIES_EXISTING_TARGET]?: boolean }
|
||||
> = {};
|
||||
for (const defaultSpecifier in targetDefaults) {
|
||||
const targetName =
|
||||
executorToTargetMap.get(defaultSpecifier) ?? defaultSpecifier;
|
||||
newTargets[targetName] = structuredClone(
|
||||
targetDefaults[defaultSpecifier]
|
||||
);
|
||||
// TODO: Remove this after we figure out a way to define new targets
|
||||
// in target defaults
|
||||
if (!projectDefinedTargets.has(targetName)) {
|
||||
newTargets[targetName][ONLY_MODIFIES_EXISTING_TARGET] = true;
|
||||
const targetNames =
|
||||
executorToTargetMap.get(defaultSpecifier) ?? new Set();
|
||||
targetNames.add(defaultSpecifier);
|
||||
|
||||
for (const targetName of targetNames) {
|
||||
modifiedTargets[targetName] = structuredClone(
|
||||
targetDefaults[defaultSpecifier]
|
||||
);
|
||||
// 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 {
|
||||
projects: {
|
||||
[root]: {
|
||||
targets: newTargets,
|
||||
targets: modifiedTargets,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -106,20 +111,20 @@ function getExecutorToTargetMap(
|
||||
packageJson: PackageJson,
|
||||
projectJson: ProjectConfiguration
|
||||
) {
|
||||
const executorToTargetMap = new Map<string, string>();
|
||||
if (packageJson?.scripts) {
|
||||
for (const script in packageJson.scripts) {
|
||||
executorToTargetMap.set('nx:run-script', script);
|
||||
}
|
||||
}
|
||||
if (projectJson?.targets) {
|
||||
for (const target in projectJson.targets) {
|
||||
if (projectJson.targets[target].executor) {
|
||||
executorToTargetMap.set(projectJson.targets[target].executor, target);
|
||||
} else if (projectJson.targets[target].command) {
|
||||
executorToTargetMap.set('nx:run-commands', target);
|
||||
}
|
||||
}
|
||||
const executorToTargetMap = new Map<string, Set<string>>();
|
||||
const targets = Object.keys({
|
||||
...projectJson?.targets,
|
||||
...packageJson?.scripts,
|
||||
...packageJson?.nx?.targets,
|
||||
});
|
||||
for (const target of targets) {
|
||||
const executor =
|
||||
projectJson?.targets?.[target]?.executor ??
|
||||
packageJson?.nx?.targets?.[target]?.executor ??
|
||||
'nx:run-script';
|
||||
const targetsForExecutor = executorToTargetMap.get(executor) ?? new Set();
|
||||
targetsForExecutor.add(target);
|
||||
executorToTargetMap.set(executor, targetsForExecutor);
|
||||
}
|
||||
return executorToTargetMap;
|
||||
}
|
||||
|
||||
@ -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', () => {
|
||||
|
||||
@ -4,7 +4,6 @@ import { readJsonFile } from './fileutils';
|
||||
import {
|
||||
buildTargetFromScript,
|
||||
PackageJson,
|
||||
PackageJsonTargetConfiguration,
|
||||
readModulePackageJson,
|
||||
readTargetsFromPackageJson,
|
||||
} from './package-json';
|
||||
@ -36,7 +35,7 @@ describe('buildTargetFromScript', () => {
|
||||
script: 'other',
|
||||
},
|
||||
executor: 'custom:execute',
|
||||
} as PackageJsonTargetConfiguration,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -7,16 +7,11 @@ import {
|
||||
import { readJsonFile } from './fileutils';
|
||||
import { getNxRequirePaths } from './installation-directory';
|
||||
|
||||
export type PackageJsonTargetConfiguration = Omit<
|
||||
TargetConfiguration,
|
||||
'executor'
|
||||
>;
|
||||
|
||||
export interface NxProjectPackageJsonConfiguration {
|
||||
implicitDependencies?: string[];
|
||||
tags?: string[];
|
||||
namedInputs?: { [inputName: string]: (string | InputDefinition)[] };
|
||||
targets?: Record<string, PackageJsonTargetConfiguration>;
|
||||
targets?: Record<string, TargetConfiguration>;
|
||||
includedScripts?: string[];
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user