feat(nx-plugin): use helper to determine project name and root in project generators (#18739)
This commit is contained in:
parent
1b0439b55c
commit
016c89fed6
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "create-package",
|
"name": "create-package",
|
||||||
"factory": "./src/generators/create-package/create-package",
|
"factory": "./src/generators/create-package/create-package#createPackageGeneratorInternal",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
@ -35,6 +35,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A directory where the app is placed."
|
"description": "A directory where the app is placed."
|
||||||
},
|
},
|
||||||
|
"projectNameAndRootFormat": {
|
||||||
|
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["as-provided", "derived"]
|
||||||
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"description": "The tool to use for running lint checks.",
|
"description": "The tool to use for running lint checks.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -70,7 +75,7 @@
|
|||||||
"presets": []
|
"presets": []
|
||||||
},
|
},
|
||||||
"description": "Create a package which can be used by npx to create a new workspace",
|
"description": "Create a package which can be used by npx to create a new workspace",
|
||||||
"implementation": "/packages/plugin/src/generators/create-package/create-package.ts",
|
"implementation": "/packages/plugin/src/generators/create-package/create-package#createPackageGeneratorInternal.ts",
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"path": "/packages/plugin/src/generators/create-package/schema.json",
|
"path": "/packages/plugin/src/generators/create-package/schema.json",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "e2e-project",
|
"name": "e2e-project",
|
||||||
"factory": "./src/generators/e2e-project/e2e",
|
"factory": "./src/generators/e2e-project/e2e#e2eProjectGeneratorInternal",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
@ -24,6 +24,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "the directory where the plugin is placed."
|
"description": "the directory where the plugin is placed."
|
||||||
},
|
},
|
||||||
|
"projectNameAndRootFormat": {
|
||||||
|
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["as-provided", "derived"]
|
||||||
|
},
|
||||||
"pluginOutputPath": {
|
"pluginOutputPath": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "the output path of the plugin after it builds.",
|
"description": "the output path of the plugin after it builds.",
|
||||||
@ -52,7 +57,7 @@
|
|||||||
"presets": []
|
"presets": []
|
||||||
},
|
},
|
||||||
"description": "Create a E2E application for a Nx Plugin.",
|
"description": "Create a E2E application for a Nx Plugin.",
|
||||||
"implementation": "/packages/plugin/src/generators/e2e-project/e2e.ts",
|
"implementation": "/packages/plugin/src/generators/e2e-project/e2e#e2eProjectGeneratorInternal.ts",
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"path": "/packages/plugin/src/generators/e2e-project/schema.json",
|
"path": "/packages/plugin/src/generators/e2e-project/schema.json",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "plugin",
|
"name": "plugin",
|
||||||
"factory": "./src/generators/plugin/plugin",
|
"factory": "./src/generators/plugin/plugin#pluginGeneratorInternal",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
@ -20,12 +20,18 @@
|
|||||||
"description": "Plugin name",
|
"description": "Plugin name",
|
||||||
"$default": { "$source": "argv", "index": 0 },
|
"$default": { "$source": "argv", "index": 0 },
|
||||||
"x-prompt": "What name would you like to use for the plugin?",
|
"x-prompt": "What name would you like to use for the plugin?",
|
||||||
"x-priority": "important"
|
"x-priority": "important",
|
||||||
|
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$"
|
||||||
},
|
},
|
||||||
"directory": {
|
"directory": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A directory where the plugin is placed."
|
"description": "A directory where the plugin is placed."
|
||||||
},
|
},
|
||||||
|
"projectNameAndRootFormat": {
|
||||||
|
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["as-provided", "derived"]
|
||||||
|
},
|
||||||
"importPath": {
|
"importPath": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "How the plugin will be published, like `@myorg/my-awesome-plugin`. Note this must be a valid NPM name.",
|
"description": "How the plugin will be published, like `@myorg/my-awesome-plugin`. Note this must be a valid NPM name.",
|
||||||
@ -98,7 +104,7 @@
|
|||||||
"presets": []
|
"presets": []
|
||||||
},
|
},
|
||||||
"description": "Create a Nx Plugin.",
|
"description": "Create a Nx Plugin.",
|
||||||
"implementation": "/packages/plugin/src/generators/plugin/plugin.ts",
|
"implementation": "/packages/plugin/src/generators/plugin/plugin#pluginGeneratorInternal.ts",
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"path": "/packages/plugin/src/generators/plugin/schema.json",
|
"path": "/packages/plugin/src/generators/plugin/schema.json",
|
||||||
|
|||||||
@ -434,4 +434,43 @@ describe('Nx Plugin', () => {
|
|||||||
)
|
)
|
||||||
).toThrow();
|
).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support the new name and root format', async () => {
|
||||||
|
const plugin = uniq('plugin');
|
||||||
|
const createAppName = `create-${plugin}-app`;
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nx/plugin:plugin ${plugin} --e2eTestRunner jest --publishable --project-name-and-root-format=as-provided`
|
||||||
|
);
|
||||||
|
|
||||||
|
// check files are generated without the layout directory ("libs/") and
|
||||||
|
// using the project name as the directory when no directory is provided
|
||||||
|
checkFilesExist(`${plugin}/src/index.ts`);
|
||||||
|
// check build works
|
||||||
|
expect(runCLI(`build ${plugin}`)).toContain(
|
||||||
|
`Successfully ran target build for project ${plugin}`
|
||||||
|
);
|
||||||
|
// check tests pass
|
||||||
|
const appTestResult = runCLI(`test ${plugin}`);
|
||||||
|
expect(appTestResult).toContain(
|
||||||
|
`Successfully ran target test for project ${plugin}`
|
||||||
|
);
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nx/plugin:create-package ${createAppName} --project=${plugin} --e2eProject=${plugin}-e2e --project-name-and-root-format=as-provided`
|
||||||
|
);
|
||||||
|
|
||||||
|
// check files are generated without the layout directory ("libs/") and
|
||||||
|
// using the project name as the directory when no directory is provided
|
||||||
|
checkFilesExist(`${plugin}/src/generators/preset`, `${createAppName}`);
|
||||||
|
// check build works
|
||||||
|
expect(runCLI(`build ${createAppName}`)).toContain(
|
||||||
|
`Successfully ran target build for project ${createAppName}`
|
||||||
|
);
|
||||||
|
// check tests pass
|
||||||
|
const libTestResult = runCLI(`test ${createAppName}`);
|
||||||
|
expect(libTestResult).toContain(
|
||||||
|
`Successfully ran target test for project ${createAppName}`
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,17 +4,17 @@
|
|||||||
"extends": ["@nx/workspace"],
|
"extends": ["@nx/workspace"],
|
||||||
"generators": {
|
"generators": {
|
||||||
"plugin": {
|
"plugin": {
|
||||||
"factory": "./src/generators/plugin/plugin",
|
"factory": "./src/generators/plugin/plugin#pluginGeneratorInternal",
|
||||||
"schema": "./src/generators/plugin/schema.json",
|
"schema": "./src/generators/plugin/schema.json",
|
||||||
"description": "Create a Nx Plugin."
|
"description": "Create a Nx Plugin."
|
||||||
},
|
},
|
||||||
"create-package": {
|
"create-package": {
|
||||||
"factory": "./src/generators/create-package/create-package",
|
"factory": "./src/generators/create-package/create-package#createPackageGeneratorInternal",
|
||||||
"schema": "./src/generators/create-package/schema.json",
|
"schema": "./src/generators/create-package/schema.json",
|
||||||
"description": "Create a package which can be used by npx to create a new workspace"
|
"description": "Create a package which can be used by npx to create a new workspace"
|
||||||
},
|
},
|
||||||
"e2e-project": {
|
"e2e-project": {
|
||||||
"factory": "./src/generators/e2e-project/e2e",
|
"factory": "./src/generators/e2e-project/e2e#e2eProjectGeneratorInternal",
|
||||||
"schema": "./src/generators/e2e-project/schema.json",
|
"schema": "./src/generators/e2e-project/schema.json",
|
||||||
"description": "Create a E2E application for a Nx Plugin."
|
"description": "Create a E2E application for a Nx Plugin."
|
||||||
},
|
},
|
||||||
|
|||||||
@ -26,10 +26,20 @@ import { join } from 'path';
|
|||||||
export async function createPackageGenerator(
|
export async function createPackageGenerator(
|
||||||
host: Tree,
|
host: Tree,
|
||||||
schema: CreatePackageSchema
|
schema: CreatePackageSchema
|
||||||
|
) {
|
||||||
|
return await createPackageGeneratorInternal(host, {
|
||||||
|
projectNameAndRootFormat: 'derived',
|
||||||
|
...schema,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createPackageGeneratorInternal(
|
||||||
|
host: Tree,
|
||||||
|
schema: CreatePackageSchema
|
||||||
) {
|
) {
|
||||||
const tasks: GeneratorCallback[] = [];
|
const tasks: GeneratorCallback[] = [];
|
||||||
|
|
||||||
const options = normalizeSchema(host, schema);
|
const options = await normalizeSchema(host, schema);
|
||||||
const pluginPackageName = await addPresetGenerator(host, options);
|
const pluginPackageName = await addPresetGenerator(host, options);
|
||||||
|
|
||||||
const installTask = addDependenciesToPackageJson(
|
const installTask = addDependenciesToPackageJson(
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-directory-utils';
|
||||||
import type { Linter } from '@nx/linter';
|
import type { Linter } from '@nx/linter';
|
||||||
|
|
||||||
export interface CreatePackageSchema {
|
export interface CreatePackageSchema {
|
||||||
@ -6,6 +7,7 @@ export interface CreatePackageSchema {
|
|||||||
|
|
||||||
// options to create cli package, passed to js library generator
|
// options to create cli package, passed to js library generator
|
||||||
directory?: string;
|
directory?: string;
|
||||||
|
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
||||||
skipFormat: boolean;
|
skipFormat: boolean;
|
||||||
tags?: string;
|
tags?: string;
|
||||||
unitTestRunner: 'jest' | 'none';
|
unitTestRunner: 'jest' | 'none';
|
||||||
|
|||||||
@ -37,6 +37,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A directory where the app is placed."
|
"description": "A directory where the app is placed."
|
||||||
},
|
},
|
||||||
|
"projectNameAndRootFormat": {
|
||||||
|
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["as-provided", "derived"]
|
||||||
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"description": "The tool to use for running lint checks.",
|
"description": "The tool to use for running lint checks.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@ -1,42 +1,36 @@
|
|||||||
import {
|
import { Tree } from '@nx/devkit';
|
||||||
extractLayoutDirectory,
|
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||||
getWorkspaceLayout,
|
|
||||||
joinPathFragments,
|
|
||||||
names,
|
|
||||||
Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { CreatePackageSchema } from '../schema';
|
import { CreatePackageSchema } from '../schema';
|
||||||
|
|
||||||
export interface NormalizedSchema extends CreatePackageSchema {
|
export interface NormalizedSchema extends CreatePackageSchema {
|
||||||
bundler: 'swc' | 'tsc';
|
bundler: 'swc' | 'tsc';
|
||||||
libsDir: string;
|
|
||||||
projectName: string;
|
projectName: string;
|
||||||
projectRoot: string;
|
projectRoot: string;
|
||||||
projectDirectory: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeSchema(
|
export async function normalizeSchema(
|
||||||
host: Tree,
|
host: Tree,
|
||||||
schema: CreatePackageSchema
|
schema: CreatePackageSchema
|
||||||
): NormalizedSchema {
|
): Promise<NormalizedSchema> {
|
||||||
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
|
const {
|
||||||
schema.directory
|
projectName,
|
||||||
);
|
names: projectNames,
|
||||||
const { libsDir: defaultLibsDir } = getWorkspaceLayout(host);
|
projectRoot,
|
||||||
const libsDir = layoutDirectory ?? defaultLibsDir;
|
projectNameAndRootFormat,
|
||||||
const name = names(schema.name).fileName;
|
} = await determineProjectNameAndRootOptions(host, {
|
||||||
const fullProjectDirectory = projectDirectory
|
name: schema.name,
|
||||||
? `${names(projectDirectory).fileName}/${name}`
|
projectType: 'library',
|
||||||
: name;
|
directory: schema.directory,
|
||||||
const projectName = fullProjectDirectory.replace(new RegExp('/', 'g'), '-');
|
projectNameAndRootFormat: schema.projectNameAndRootFormat,
|
||||||
const projectRoot = joinPathFragments(libsDir, fullProjectDirectory);
|
callingGenerator: '@nx/plugin:create-package',
|
||||||
|
});
|
||||||
|
schema.projectNameAndRootFormat = projectNameAndRootFormat;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...schema,
|
...schema,
|
||||||
bundler: schema.compiler ?? 'tsc',
|
bundler: schema.compiler ?? 'tsc',
|
||||||
libsDir,
|
|
||||||
projectName,
|
projectName,
|
||||||
projectRoot,
|
projectRoot,
|
||||||
name,
|
name: projectNames.projectSimpleName,
|
||||||
projectDirectory: fullProjectDirectory,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,13 +16,13 @@ import {
|
|||||||
runTasksInSerial,
|
runTasksInSerial,
|
||||||
updateProjectConfiguration,
|
updateProjectConfiguration,
|
||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
|
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||||
import { addPropertyToJestConfig, configurationGenerator } from '@nx/jest';
|
import { addPropertyToJestConfig, configurationGenerator } from '@nx/jest';
|
||||||
import { getRelativePathToRootTsConfig } from '@nx/js';
|
import { getRelativePathToRootTsConfig } from '@nx/js';
|
||||||
import { setupVerdaccio } from '@nx/js/src/generators/setup-verdaccio/generator';
|
import { setupVerdaccio } from '@nx/js/src/generators/setup-verdaccio/generator';
|
||||||
import { addLocalRegistryScripts } from '@nx/js/src/utils/add-local-registry-scripts';
|
import { addLocalRegistryScripts } from '@nx/js/src/utils/add-local-registry-scripts';
|
||||||
import { join } from 'path';
|
|
||||||
import { Linter, lintProjectGenerator } from '@nx/linter';
|
import { Linter, lintProjectGenerator } from '@nx/linter';
|
||||||
|
import { join } from 'path';
|
||||||
import type { Schema } from './schema';
|
import type { Schema } from './schema';
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
interface NormalizedSchema extends Schema {
|
||||||
@ -32,20 +32,42 @@ interface NormalizedSchema extends Schema {
|
|||||||
linter: Linter;
|
linter: Linter;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
|
async function normalizeOptions(
|
||||||
|
host: Tree,
|
||||||
|
options: Schema
|
||||||
|
): Promise<NormalizedSchema> {
|
||||||
|
const projectName = options.rootProject ? 'e2e' : `${options.pluginName}-e2e`;
|
||||||
|
|
||||||
|
let projectRoot: string;
|
||||||
|
if (options.projectNameAndRootFormat === 'as-provided') {
|
||||||
|
const projectNameAndRootOptions = await determineProjectNameAndRootOptions(
|
||||||
|
host,
|
||||||
|
{
|
||||||
|
name: projectName,
|
||||||
|
projectType: 'application',
|
||||||
|
directory:
|
||||||
|
options.rootProject || !options.projectDirectory
|
||||||
|
? projectName
|
||||||
|
: `${options.projectDirectory}-e2e`,
|
||||||
|
projectNameAndRootFormat: `as-provided`,
|
||||||
|
callingGenerator: '@nx/plugin:e2e-project',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
projectRoot = projectNameAndRootOptions.projectRoot;
|
||||||
|
} else {
|
||||||
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
|
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
|
||||||
options.projectDirectory
|
options.projectDirectory
|
||||||
);
|
);
|
||||||
const { appsDir: defaultAppsDir } = getWorkspaceLayout(host);
|
const { appsDir: defaultAppsDir } = getWorkspaceLayout(host);
|
||||||
const appsDir = layoutDirectory ?? defaultAppsDir;
|
const appsDir = layoutDirectory ?? defaultAppsDir;
|
||||||
|
|
||||||
const projectName = options.rootProject ? 'e2e' : `${options.pluginName}-e2e`;
|
projectRoot = options.rootProject
|
||||||
const projectRoot =
|
|
||||||
projectDirectory && !options.rootProject
|
|
||||||
? joinPathFragments(appsDir, `${projectDirectory}-e2e`)
|
|
||||||
: options.rootProject
|
|
||||||
? projectName
|
? projectName
|
||||||
|
: projectDirectory
|
||||||
|
? joinPathFragments(appsDir, `${projectDirectory}-e2e`)
|
||||||
: joinPathFragments(appsDir, projectName);
|
: joinPathFragments(appsDir, projectName);
|
||||||
|
}
|
||||||
|
|
||||||
const pluginPropertyName = names(options.pluginName).propertyName;
|
const pluginPropertyName = names(options.pluginName).propertyName;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -158,10 +180,17 @@ async function addLintingToApplication(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function e2eProjectGenerator(host: Tree, schema: Schema) {
|
export async function e2eProjectGenerator(host: Tree, schema: Schema) {
|
||||||
|
return await e2eProjectGeneratorInternal(host, {
|
||||||
|
projectNameAndRootFormat: 'derived',
|
||||||
|
...schema,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function e2eProjectGeneratorInternal(host: Tree, schema: Schema) {
|
||||||
const tasks: GeneratorCallback[] = [];
|
const tasks: GeneratorCallback[] = [];
|
||||||
|
|
||||||
validatePlugin(host, schema.pluginName);
|
validatePlugin(host, schema.pluginName);
|
||||||
const options = normalizeOptions(host, schema);
|
const options = await normalizeOptions(host, schema);
|
||||||
addFiles(host, options);
|
addFiles(host, options);
|
||||||
tasks.push(
|
tasks.push(
|
||||||
await setupVerdaccio(host, {
|
await setupVerdaccio(host, {
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import { Linter } from '@nx/linter';
|
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-directory-utils';
|
||||||
|
import type { Linter } from '@nx/linter';
|
||||||
|
|
||||||
export interface Schema {
|
export interface Schema {
|
||||||
pluginName: string;
|
pluginName: string;
|
||||||
npmPackageName: string;
|
npmPackageName: string;
|
||||||
projectDirectory?: string;
|
projectDirectory?: string;
|
||||||
|
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
||||||
pluginOutputPath?: string;
|
pluginOutputPath?: string;
|
||||||
jestConfig?: string;
|
jestConfig?: string;
|
||||||
linter?: Linter;
|
linter?: Linter;
|
||||||
|
|||||||
@ -21,6 +21,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "the directory where the plugin is placed."
|
"description": "the directory where the plugin is placed."
|
||||||
},
|
},
|
||||||
|
"projectNameAndRootFormat": {
|
||||||
|
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["as-provided", "derived"]
|
||||||
|
},
|
||||||
"pluginOutputPath": {
|
"pluginOutputPath": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "the output path of the plugin after it builds.",
|
"description": "the output path of the plugin after it builds.",
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
formatFiles,
|
formatFiles,
|
||||||
generateFiles,
|
generateFiles,
|
||||||
GeneratorCallback,
|
GeneratorCallback,
|
||||||
|
joinPathFragments,
|
||||||
normalizePath,
|
normalizePath,
|
||||||
readProjectConfiguration,
|
readProjectConfiguration,
|
||||||
runTasksInSerial,
|
runTasksInSerial,
|
||||||
@ -74,7 +75,14 @@ function updatePluginConfig(host: Tree, options: NormalizedSchema) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function pluginGenerator(host: Tree, schema: Schema) {
|
export async function pluginGenerator(host: Tree, schema: Schema) {
|
||||||
const options = normalizeOptions(host, schema);
|
return await pluginGeneratorInternal(host, {
|
||||||
|
projectNameAndRootFormat: 'derived',
|
||||||
|
...schema,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function pluginGeneratorInternal(host: Tree, schema: Schema) {
|
||||||
|
const options = await normalizeOptions(host, schema);
|
||||||
const tasks: GeneratorCallback[] = [];
|
const tasks: GeneratorCallback[] = [];
|
||||||
|
|
||||||
tasks.push(
|
tasks.push(
|
||||||
@ -119,10 +127,14 @@ export async function pluginGenerator(host: Tree, schema: Schema) {
|
|||||||
await e2eProjectGenerator(host, {
|
await e2eProjectGenerator(host, {
|
||||||
pluginName: options.name,
|
pluginName: options.name,
|
||||||
projectDirectory: options.projectDirectory,
|
projectDirectory: options.projectDirectory,
|
||||||
pluginOutputPath: `dist/${options.libsDir}/${options.projectDirectory}`,
|
pluginOutputPath: joinPathFragments(
|
||||||
|
'dist',
|
||||||
|
options.rootProject ? options.name : options.projectRoot
|
||||||
|
),
|
||||||
npmPackageName: options.npmPackageName,
|
npmPackageName: options.npmPackageName,
|
||||||
skipFormat: true,
|
skipFormat: true,
|
||||||
rootProject: options.rootProject,
|
rootProject: options.rootProject,
|
||||||
|
projectNameAndRootFormat: options.projectNameAndRootFormat,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { Linter } from '@nx/linter';
|
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-directory-utils';
|
||||||
|
import type { Linter } from '@nx/linter';
|
||||||
|
|
||||||
export interface Schema {
|
export interface Schema {
|
||||||
name: string;
|
name: string;
|
||||||
directory?: string;
|
directory?: string;
|
||||||
|
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
||||||
importPath?: string;
|
importPath?: string;
|
||||||
skipTsConfig?: boolean; // default is false
|
skipTsConfig?: boolean; // default is false
|
||||||
skipFormat?: boolean; // default is false
|
skipFormat?: boolean; // default is false
|
||||||
|
|||||||
@ -20,12 +20,18 @@
|
|||||||
"index": 0
|
"index": 0
|
||||||
},
|
},
|
||||||
"x-prompt": "What name would you like to use for the plugin?",
|
"x-prompt": "What name would you like to use for the plugin?",
|
||||||
"x-priority": "important"
|
"x-priority": "important",
|
||||||
|
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$"
|
||||||
},
|
},
|
||||||
"directory": {
|
"directory": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A directory where the plugin is placed."
|
"description": "A directory where the plugin is placed."
|
||||||
},
|
},
|
||||||
|
"projectNameAndRootFormat": {
|
||||||
|
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["as-provided", "derived"]
|
||||||
|
},
|
||||||
"importPath": {
|
"importPath": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "How the plugin will be published, like `@myorg/my-awesome-plugin`. Note this must be a valid NPM name.",
|
"description": "How the plugin will be published, like `@myorg/my-awesome-plugin`. Note this must be a valid NPM name.",
|
||||||
|
|||||||
@ -1,17 +1,10 @@
|
|||||||
import {
|
import { Tree, extractLayoutDirectory, getWorkspaceLayout } from '@nx/devkit';
|
||||||
extractLayoutDirectory,
|
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||||
getWorkspaceLayout,
|
|
||||||
joinPathFragments,
|
|
||||||
names,
|
|
||||||
Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { Schema } from '../schema';
|
import { Schema } from '../schema';
|
||||||
import { getImportPath } from '@nx/js/src/utils/get-import-path';
|
|
||||||
|
|
||||||
export interface NormalizedSchema extends Schema {
|
export interface NormalizedSchema extends Schema {
|
||||||
name: string;
|
name: string;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
libsDir: string;
|
|
||||||
projectRoot: string;
|
projectRoot: string;
|
||||||
projectDirectory: string;
|
projectDirectory: string;
|
||||||
parsedTags: string[];
|
parsedTags: string[];
|
||||||
@ -19,44 +12,50 @@ export interface NormalizedSchema extends Schema {
|
|||||||
bundler: 'swc' | 'tsc';
|
bundler: 'swc' | 'tsc';
|
||||||
publishable: boolean;
|
publishable: boolean;
|
||||||
}
|
}
|
||||||
export function normalizeOptions(
|
export async function normalizeOptions(
|
||||||
host: Tree,
|
host: Tree,
|
||||||
options: Schema
|
options: Schema
|
||||||
): NormalizedSchema {
|
): Promise<NormalizedSchema> {
|
||||||
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
|
const {
|
||||||
options.directory
|
projectName,
|
||||||
);
|
projectRoot,
|
||||||
const { libsDir: defaultLibsDir } = getWorkspaceLayout(host);
|
importPath: npmPackageName,
|
||||||
const libsDir = layoutDirectory ?? defaultLibsDir;
|
projectNameAndRootFormat,
|
||||||
const name = names(options.name).fileName;
|
} = await determineProjectNameAndRootOptions(host, {
|
||||||
const fullProjectDirectory = projectDirectory
|
name: options.name,
|
||||||
? `${names(projectDirectory).fileName}/${name}`
|
projectType: 'library',
|
||||||
: options.rootProject
|
directory: options.directory,
|
||||||
? '.'
|
importPath: options.importPath,
|
||||||
: name;
|
projectNameAndRootFormat: options.projectNameAndRootFormat,
|
||||||
|
rootProject: options.rootProject,
|
||||||
|
callingGenerator: '@nx/plugin:plugin',
|
||||||
|
});
|
||||||
|
options.projectNameAndRootFormat = projectNameAndRootFormat;
|
||||||
|
options.rootProject = projectRoot === '.';
|
||||||
|
|
||||||
const projectName = options.rootProject
|
let projectDirectory = projectRoot;
|
||||||
? name
|
if (options.projectNameAndRootFormat === 'derived') {
|
||||||
: fullProjectDirectory.replace(new RegExp('/', 'g'), '-');
|
let { layoutDirectory } = extractLayoutDirectory(options.directory);
|
||||||
const fileName = projectName;
|
if (!layoutDirectory) {
|
||||||
const projectRoot = options.rootProject
|
const { libsDir } = getWorkspaceLayout(host);
|
||||||
? fullProjectDirectory
|
layoutDirectory = libsDir;
|
||||||
: joinPathFragments(libsDir, fullProjectDirectory);
|
}
|
||||||
|
if (projectRoot.startsWith(`${layoutDirectory}/`)) {
|
||||||
|
projectDirectory = projectRoot.replace(`${layoutDirectory}/`, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const parsedTags = options.tags
|
const parsedTags = options.tags
|
||||||
? options.tags.split(',').map((s) => s.trim())
|
? options.tags.split(',').map((s) => s.trim())
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const npmPackageName = options.importPath || getImportPath(host, name);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...options,
|
...options,
|
||||||
bundler: options.compiler ?? 'tsc',
|
bundler: options.compiler ?? 'tsc',
|
||||||
fileName,
|
fileName: projectName,
|
||||||
libsDir,
|
|
||||||
name: projectName,
|
name: projectName,
|
||||||
projectRoot,
|
projectRoot,
|
||||||
projectDirectory: fullProjectDirectory,
|
projectDirectory,
|
||||||
parsedTags,
|
parsedTags,
|
||||||
npmPackageName,
|
npmPackageName,
|
||||||
publishable: options.publishable ?? false,
|
publishable: options.publishable ?? false,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user