<!-- 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` --> ## Current Behavior <!-- This is the behavior we have today --> `forEachExecutorOptions` will not run the callback if `target.options` is undefined. This means that even if a target exists with an executor, the target is not being processed if it does not have `options`. ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> Run the callback anyway even if `target.options` is undefined ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import {
|
|
getProjects,
|
|
ProjectConfiguration,
|
|
ProjectGraph,
|
|
Tree,
|
|
} from 'nx/src/devkit-exports';
|
|
|
|
type CallBack<T> = (
|
|
currentValue: T,
|
|
project: string,
|
|
target: string,
|
|
configuration?: string
|
|
) => void;
|
|
|
|
/**
|
|
* Calls a function for each different options that an executor is configured with
|
|
*/
|
|
export function forEachExecutorOptions<Options>(
|
|
tree: Tree,
|
|
/**
|
|
* Name of the executor to update options for
|
|
*/
|
|
executorName: string,
|
|
/**
|
|
* Callback that is called for each options configured for a builder
|
|
*/
|
|
callback: CallBack<Options>
|
|
): void {
|
|
forEachProjectConfig(getProjects(tree), executorName, callback);
|
|
}
|
|
|
|
/**
|
|
* Calls a function for each different options that an executor is configured with via the project graph
|
|
* this is helpful when you need to get the expaned configuration options from the nx.json
|
|
**/
|
|
export function forEachExecutorOptionsInGraph<Options>(
|
|
graph: ProjectGraph,
|
|
executorName: string,
|
|
callback: CallBack<Options>
|
|
): void {
|
|
const projects = new Map<string, ProjectConfiguration>();
|
|
Object.values(graph.nodes).forEach((p) => projects.set(p.name, p.data));
|
|
|
|
forEachProjectConfig<Options>(projects, executorName, callback);
|
|
}
|
|
|
|
function forEachProjectConfig<Options>(
|
|
projects: Map<string, ProjectConfiguration>,
|
|
executorName: string,
|
|
callback: CallBack<Options>
|
|
): void {
|
|
for (const [projectName, project] of projects) {
|
|
for (const [targetName, target] of Object.entries(project.targets || {})) {
|
|
if (executorName !== target.executor) {
|
|
continue;
|
|
}
|
|
|
|
callback(target.options ?? {}, projectName, targetName);
|
|
|
|
if (!target.configurations) {
|
|
continue;
|
|
}
|
|
Object.entries(target.configurations).forEach(([configName, options]) => {
|
|
callback(options, projectName, targetName, configName);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: add a method for updating options
|