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;
|
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);
|
||||||
|
|
||||||
|
for (const targetName of targetNames) {
|
||||||
|
modifiedTargets[targetName] = structuredClone(
|
||||||
targetDefaults[defaultSpecifier]
|
targetDefaults[defaultSpecifier]
|
||||||
);
|
);
|
||||||
// TODO: Remove this after we figure out a way to define new targets
|
// TODO: Remove this after we figure out a way to define new targets
|
||||||
// in target defaults
|
// in target defaults
|
||||||
if (!projectDefinedTargets.has(targetName)) {
|
if (!projectDefinedTargets.has(targetName)) {
|
||||||
newTargets[targetName][ONLY_MODIFIES_EXISTING_TARGET] = true;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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', () => {
|
||||||
|
|||||||
@ -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,
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -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[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user