From b5230bbbd7222cf231dc90e984e817ede7408a9a Mon Sep 17 00:00:00 2001 From: Adrian Dimech Date: Thu, 20 Jul 2023 14:10:40 +1000 Subject: [PATCH] fix(core): ensure output paths returned are unique It is possible for users to define multiple duplicate outputs. This is leading to fs related issues like `ENOTEMPTY: directory not empty, rmdir`. The reason this occurs is that the src will tried to be copied to the cached directory in parallel for all output paths and is the reason why these errors are seen sporadically. By ensuring output paths are unique, we only ever copy one path which resolves this issue. fixes #17277, ##16337 --- packages/nx/src/tasks-runner/utils.ts | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/nx/src/tasks-runner/utils.ts b/packages/nx/src/tasks-runner/utils.ts index 5bfafa13291593..0a60466226d97d 100644 --- a/packages/nx/src/tasks-runner/utils.ts +++ b/packages/nx/src/tasks-runner/utils.ts @@ -209,19 +209,22 @@ export function getOutputsForTargetAndConfiguration( if (targetConfiguration?.outputs) { validateOutputs(targetConfiguration.outputs); - return targetConfiguration.outputs - .map((output: string) => { - return interpolate(output, { - projectRoot: node.data.root, - projectName: node.name, - project: { ...node.data, name: node.name }, // this is legacy - options, - }); - }) - .filter( - (output) => - !!output && !output.match(/{(projectRoot|workspaceRoot|(options.*))}/) - ); + const result = new Set(); + for (const output of targetConfiguration.outputs) { + const interpolatedOutput = interpolate(output, { + projectRoot: node.data.root, + projectName: node.name, + project: { ...node.data, name: node.name }, // this is legacy + options, + }); + if ( + !!interpolatedOutput && + !interpolatedOutput.match(/{(projectRoot|workspaceRoot|(options.*))}/) + ) { + result.add(interpolatedOutput); + } + } + return Array.from(result); } // Keep backwards compatibility in case `outputs` doesn't exist