diff --git a/docs/generated/devkit/PluginConfiguration.md b/docs/generated/devkit/PluginConfiguration.md index 72289e36c7..64b7b8baf8 100644 --- a/docs/generated/devkit/PluginConfiguration.md +++ b/docs/generated/devkit/PluginConfiguration.md @@ -1,3 +1,3 @@ # Type alias: PluginConfiguration -Ƭ **PluginConfiguration**: `string` \| \{ `options?`: `unknown` ; `plugin`: `string` } +Ƭ **PluginConfiguration**: `string` \| \{ `exclude?`: `string`[] ; `include?`: `string`[] ; `options?`: `unknown` ; `plugin`: `string` } diff --git a/packages/nx/schemas/nx-schema.json b/packages/nx/schemas/nx-schema.json index e724264420..1eb695b298 100644 --- a/packages/nx/schemas/nx-schema.json +++ b/packages/nx/schemas/nx-schema.json @@ -270,7 +270,9 @@ { "type": "array", "description": "The projects that the targets belong to.", - "items": { "type": "string" } + "items": { + "type": "string" + } } ] }, @@ -294,8 +296,12 @@ "required": ["input"], "not": { "anyOf": [ - { "required": ["projects"] }, - { "required": ["dependencies"] } + { + "required": ["projects"] + }, + { + "required": ["dependencies"] + } ] } } @@ -327,7 +333,9 @@ "properties": { "externalDependencies": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "description": "The list of external dependencies that our target depends on for `nx:run-commands` and community plugins." } }, @@ -495,8 +503,12 @@ "required": ["target"], "not": { "anyOf": [ - { "required": ["projects"] }, - { "required": ["dependencies"] } + { + "required": ["projects"] + }, + { + "required": ["dependencies"] + } ] } } @@ -529,6 +541,20 @@ "options": { "type": "object", "description": "The options passed to the plugin when creating nodes and dependencies" + }, + "include": { + "type": "array", + "description": "File patterns which are included by the plugin", + "items": { + "type": "string" + } + }, + "exclude": { + "type": "array", + "description": "File patterns which are excluded by the plugin", + "items": { + "type": "string" + } } } } diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index 9139c7ba4f..7a4e7f7497 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -438,7 +438,12 @@ export interface NxJsonConfiguration { export type PluginConfiguration = | string - | { plugin: string; options?: unknown }; + | { + plugin: string; + options?: unknown; + include?: string[]; + exclude?: string[]; + }; export function readNxJson(root: string = workspaceRoot): NxJsonConfiguration { const nxJson = join(root, 'nx.json'); diff --git a/packages/nx/src/project-graph/utils/project-configuration-utils.ts b/packages/nx/src/project-graph/utils/project-configuration-utils.ts index fc95a21768..22b2d38a15 100644 --- a/packages/nx/src/project-graph/utils/project-configuration-utils.ts +++ b/packages/nx/src/project-graph/utils/project-configuration-utils.ts @@ -307,7 +307,7 @@ export function createProjectConfigurations( const errors: Array = []; // We iterate over plugins first - this ensures that plugins specified first take precedence. - for (const { plugin, options } of plugins) { + for (const { plugin, options, include, exclude } of plugins) { const [pattern, createNodes] = plugin.createNodes ?? []; const pluginResults: Array< CreateNodesResultWithContext | Promise @@ -318,10 +318,31 @@ export function createProjectConfigurations( continue; } - const matchingConfigFiles: string[] = workspaceFiles.filter( - minimatch.filter(pattern, { dot: true }) - ); + const matchingConfigFiles: string[] = []; + for (const file of workspaceFiles) { + if (minimatch(file, pattern, { dot: true })) { + if (include) { + const included = include.some((includedPattern) => + minimatch(file, includedPattern, { dot: true }) + ); + if (!included) { + continue; + } + } + + if (exclude) { + const excluded = include.some((excludedPattern) => + minimatch(file, excludedPattern, { dot: true }) + ); + if (excluded) { + continue; + } + } + + matchingConfigFiles.push(file); + } + } for (const file of matchingConfigFiles) { performance.mark(`${plugin.name}:createNodes:${file} - start`); try { diff --git a/packages/nx/src/utils/nx-plugin.ts b/packages/nx/src/utils/nx-plugin.ts index 8080feee96..1ab2faa9c1 100644 --- a/packages/nx/src/utils/nx-plugin.ts +++ b/packages/nx/src/utils/nx-plugin.ts @@ -156,6 +156,8 @@ export type NxPlugin = NxPluginV1 | NxPluginV2; export type LoadedNxPlugin = { plugin: NxPluginV2 & Pick; options?: unknown; + include?: string[]; + exclude?: string[]; }; // Short lived cache (cleared between cmd runs) @@ -225,8 +227,22 @@ export async function loadNxPluginAsync( ? pluginConfiguration : { plugin: pluginConfiguration, options: undefined }; let pluginModule = nxPluginCache.get(moduleName); + + const include = + typeof pluginConfiguration === 'object' + ? pluginConfiguration.include + : undefined; + const exclude = + typeof pluginConfiguration === 'object' + ? pluginConfiguration.exclude + : undefined; if (pluginModule) { - return { plugin: pluginModule, options }; + return { + plugin: pluginModule, + options, + include, + exclude, + }; } performance.mark(`Load Nx Plugin: ${moduleName} - start`); let { pluginPath, name } = await getPluginPathAndName( @@ -246,7 +262,12 @@ export async function loadNxPluginAsync( `Load Nx Plugin: ${moduleName} - start`, `Load Nx Plugin: ${moduleName} - end` ); - return { plugin, options }; + return { + plugin, + options, + include, + exclude, + }; } export async function loadNxPlugins(