Skip to content

Commit

Permalink
fix(core): resolve nested delegated executor package correctly (#26979)
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 -->

Resolving the package for delegated executor definitions doesn't take
into account that the package could be nested inside the parent package.

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

Resolving the package for delegated executor definitions should work
correctly.

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

Fixes #26896

(cherry picked from commit 53d2e9c)
  • Loading branch information
leosvelperez authored and FrozenPandaz committed Jul 22, 2024
1 parent e388304 commit dc9e8b2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 20 deletions.
14 changes: 8 additions & 6 deletions packages/nx/src/adapter/ngcli-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,8 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(

private readExecutorsJson(
nodeModule: string,
builder: string
builder: string,
extraRequirePaths: string[] = []
): {
executorsFilePath: string;
executorConfig: ExecutorJsonEntryConfig;
Expand All @@ -1200,7 +1201,9 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(
readPluginPackageJson(
nodeModule,
this.projects,
this.root ? [this.root, __dirname] : [__dirname]
this.root
? [this.root, __dirname, ...extraRequirePaths]
: [__dirname, ...extraRequirePaths]
);
const executorsFile = packageJson.executors ?? packageJson.builders;

Expand All @@ -1210,9 +1213,8 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(
);
}

const executorsFilePath = require.resolve(
join(dirname(packageJsonPath), executorsFile)
);
const basePath = dirname(packageJsonPath);
const executorsFilePath = require.resolve(join(basePath, executorsFile));
const executorsJson = readJsonFile<ExecutorsJson>(executorsFilePath);
const executorConfig =
executorsJson.builders?.[builder] ?? executorsJson.executors?.[builder];
Expand All @@ -1224,7 +1226,7 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(
if (typeof executorConfig === 'string') {
// Angular CLI can have a builder pointing to another package:builder
const [packageName, executorName] = executorConfig.split(':');
return this.readExecutorsJson(packageName, executorName);
return this.readExecutorsJson(packageName, executorName, [basePath]);
}

return { executorsFilePath, executorConfig, isNgCompat: true };
Expand Down
22 changes: 15 additions & 7 deletions packages/nx/src/command-line/run/executor-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ function readExecutorJson(
nodeModule: string,
executor: string,
root: string,
projects: Record<string, ProjectConfiguration>
projects: Record<string, ProjectConfiguration>,
extraRequirePaths: string[] = []
): {
executorsFilePath: string;
executorConfig: {
Expand All @@ -114,8 +115,14 @@ function readExecutorJson(
nodeModule,
projects,
root
? [root, __dirname, process.cwd(), ...getNxRequirePaths()]
: [__dirname, process.cwd(), ...getNxRequirePaths()]
? [
root,
__dirname,
process.cwd(),
...getNxRequirePaths(),
...extraRequirePaths,
]
: [__dirname, process.cwd(), ...getNxRequirePaths(), ...extraRequirePaths]
);
const executorsFile = packageJson.executors ?? packageJson.builders;

Expand All @@ -125,9 +132,8 @@ function readExecutorJson(
);
}

const executorsFilePath = require.resolve(
join(dirname(packageJsonPath), executorsFile)
);
const basePath = dirname(packageJsonPath);
const executorsFilePath = require.resolve(join(basePath, executorsFile));
const executorsJson = readJsonFile<ExecutorsJson>(executorsFilePath);
const executorConfig =
executorsJson.executors?.[executor] || executorsJson.builders?.[executor];
Expand All @@ -139,7 +145,9 @@ function readExecutorJson(
if (typeof executorConfig === 'string') {
// Angular CLI can have a builder pointing to another package:builder
const [packageName, executorName] = executorConfig.split(':');
return readExecutorJson(packageName, executorName, root, projects);
return readExecutorJson(packageName, executorName, root, projects, [
basePath,
]);
}
const isNgCompat = !executorsJson.executors?.[executor];
return { executorsFilePath, executorConfig, isNgCompat };
Expand Down
33 changes: 26 additions & 7 deletions packages/nx/src/utils/plugins/plugin-capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export async function listPluginCapabilities(
...Object.keys(plugin.executors).map(
(name) =>
`${chalk.bold(name)} : ${resolveExecutorDescription(
pluginName,
plugin.executors[name],
projects
)}`
Expand All @@ -204,20 +205,38 @@ export async function listPluginCapabilities(
}

function resolveExecutorDescription(
pluginName: string,
executorJsonEntry: ExecutorsJsonEntry,
projects: Record<string, ProjectConfiguration>
projects: Record<string, ProjectConfiguration>,
requirePaths = getNxRequirePaths(workspaceRoot)
) {
try {
if (typeof executorJsonEntry === 'string') {
// it points to another executor, resolve it
const [pkgName, executor] = executorJsonEntry.split(':');
// read the package.json of the parent plugin
const { path: packageJsonPath } = readPluginPackageJson(
pluginName,
projects,
requirePaths
);
// accumulate the require paths to resolve nested packages
const cummulativeRequirePaths = [
...requirePaths,
dirname(packageJsonPath),
];
const collection = loadExecutorsCollection(
workspaceRoot,
pkgName,
projects
projects,
cummulativeRequirePaths
);

return resolveExecutorDescription(collection[executor], projects);
return resolveExecutorDescription(
pkgName,
collection[executor],
projects,
cummulativeRequirePaths
);
}

return executorJsonEntry.description;
Expand All @@ -227,14 +246,14 @@ function resolveExecutorDescription(
}

function loadExecutorsCollection(
workspaceRoot: string,
pluginName: string,
projects: Record<string, ProjectConfiguration>
projects: Record<string, ProjectConfiguration>,
requirePaths: string[]
): { [name: string]: ExecutorsJsonEntry } {
const { json: packageJson, path: packageJsonPath } = readPluginPackageJson(
pluginName,
projects,
getNxRequirePaths(workspaceRoot)
requirePaths
);

return {
Expand Down

0 comments on commit dc9e8b2

Please sign in to comment.