Skip to content

Commit

Permalink
feat(core): update create-nx-plugin to generate cli library
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongemi committed Apr 19, 2023
1 parent 338dc64 commit 86dd385
Show file tree
Hide file tree
Showing 42 changed files with 849 additions and 92 deletions.
8 changes: 8 additions & 0 deletions docs/generated/manifests/menus.json
Original file line number Diff line number Diff line change
Expand Up @@ -5595,6 +5595,14 @@
"isExternal": false,
"disableCollapsible": false
},
{
"id": "create-package",
"path": "/packages/nx-plugin/generators/create-package",
"name": "create-package",
"children": [],
"isExternal": false,
"disableCollapsible": false
},
{
"id": "e2e-project",
"path": "/packages/nx-plugin/generators/e2e-project",
Expand Down
9 changes: 9 additions & 0 deletions docs/generated/manifests/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,15 @@
"path": "/packages/nx-plugin/generators/plugin",
"type": "generator"
},
"/packages/nx-plugin/generators/create-package": {
"description": "Create a framework package that uses Nx CLI",
"file": "generated/packages/nx-plugin/generators/create-package.json",
"hidden": false,
"name": "create-package",
"originalFilePath": "/packages/nx-plugin/src/generators/create-package/schema.json",
"path": "/packages/nx-plugin/generators/create-package",
"type": "generator"
},
"/packages/nx-plugin/generators/e2e-project": {
"description": "Create a E2E application for a Nx Plugin.",
"file": "generated/packages/nx-plugin/generators/e2e-project.json",
Expand Down
9 changes: 9 additions & 0 deletions docs/generated/packages-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,15 @@
"path": "nx-plugin/generators/plugin",
"type": "generator"
},
{
"description": "Create a framework package that uses Nx CLI",
"file": "generated/packages/nx-plugin/generators/create-package.json",
"hidden": false,
"name": "create-package",
"originalFilePath": "/packages/nx-plugin/src/generators/create-package/schema.json",
"path": "nx-plugin/generators/create-package",
"type": "generator"
},
{
"description": "Create a E2E application for a Nx Plugin.",
"file": "generated/packages/nx-plugin/generators/e2e-project.json",
Expand Down
84 changes: 84 additions & 0 deletions docs/generated/packages/nx-plugin/generators/create-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"name": "create-package",
"factory": "./src/generators/create-package/create-package",
"schema": {
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxPluginCreatePackage",
"title": "Create a framework package",
"description": "Create a framework package that uses Nx CLI.",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The package name of cli, e.g. `create-framework-package`. Note this must be a valid NPM name to be published.",
"$default": { "$source": "argv", "index": 0 },
"x-priority": "important"
},
"project": {
"type": "string",
"description": "The name of the generator project.",
"alias": "p",
"$default": { "$source": "projectName" },
"x-prompt": "What is the name of the project for the generator?",
"x-priority": "important"
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"description": "Test runner to use for unit tests.",
"default": "jest"
},
"directory": {
"type": "string",
"description": "A directory where the app is placed."
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": ["eslint"],
"default": "eslint"
},
"tags": {
"type": "string",
"description": "Add tags to the library (used for linting).",
"alias": "t"
},
"skipFormat": {
"description": "Skip formatting files.",
"type": "boolean",
"default": false,
"x-priority": "internal"
},
"skipTsConfig": {
"type": "boolean",
"default": false,
"description": "Do not update tsconfig.json for development experience.",
"x-priority": "internal"
},
"setParserOptionsProject": {
"type": "boolean",
"description": "Whether or not to configure the ESLint `parserOptions.project` option. We do not do this by default for lint performance reasons.",
"default": false
},
"compiler": {
"type": "string",
"enum": ["tsc", "swc"],
"default": "tsc",
"description": "The compiler used by the build and test targets."
},
"importPath": {
"type": "string",
"description": "How the plugin will be published, like `create-framework-app`. Note this must be a valid NPM name. Will use name if not provided."
}
},
"required": ["name", "project"],
"presets": []
},
"description": "Create a framework package that uses Nx CLI",
"implementation": "/packages/nx-plugin/src/generators/create-package/create-package.ts",
"aliases": [],
"hidden": false,
"path": "/packages/nx-plugin/src/generators/create-package/schema.json",
"type": "generator"
}
5 changes: 5 additions & 0 deletions docs/generated/packages/nx-plugin/generators/preset.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
"type": "string",
"description": "Plugin name",
"aliases": ["name"]
},
"cliName": {
"type": "string",
"description": "Name of cli command to create workspace with plugin",
"aliases": ["name"]
}
},
"required": ["pluginName"],
Expand Down
1 change: 1 addition & 0 deletions docs/generated/packages/workspace/generators/preset.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"default": false
}
},
"required": ["preset", "name"],
"presets": []
},
"description": "Create application in an empty workspace.",
Expand Down
28 changes: 27 additions & 1 deletion e2e/nx-plugin/src/nx-plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
createFile,
expectTestsPass,
getPackageManagerCommand,
killPorts,
newProject,
readJson,
readProjectConfig,
Expand Down Expand Up @@ -410,4 +409,31 @@ describe('Nx Plugin', () => {
expect(pluginProject.tags).toEqual(['e2etag', 'e2ePackage']);
}, 90000);
});

it('should be able to generate a create-package plugin ', async () => {
const plugin = uniq('plugin');
const createAppName = `create-${plugin}-app`;
runCLI(`generate @nrwl/nx-plugin:plugin ${plugin}`);
runCLI(
`generate @nrwl/nx-plugin:create-package ${createAppName} --project=${plugin}`
);

const buildResults = runCLI(`build ${createAppName}`);
expect(buildResults).toContain('Done compiling TypeScript files');

checkFilesExist(
`libs/${plugin}/src/generators/preset`,
`libs/${createAppName}`,
`dist/libs/${createAppName}/bin/index.js`
);
});

it('should throw an error when run create-package for an invalid plugin ', async () => {
const plugin = uniq('plugin');
expect(() =>
runCLI(
`generate @nrwl/nx-plugin:create-package ${plugin} --project=invalid-plugin`
)
).toThrow();
});
});
10 changes: 8 additions & 2 deletions e2e/workspace-create/src/create-nx-plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('create-nx-plugin', () => {

runCLI(`build ${pluginName}`);

checkFilesExist(`dist/package.json`);
checkFilesExist(`dist/package.json`, `dist/src/index.js`);

runCLI(
`generate @nrwl/nx-plugin:generator ${generatorName} --project=${pluginName}`
Expand All @@ -45,7 +45,13 @@ describe('create-nx-plugin', () => {
checkFilesExist(
`dist/package.json`,
`dist/generators.json`,
`dist/executors.json`
`dist/executors.json`,
`dist/src/index.js`
);

runCLI(`build create-${pluginName}-package`);
checkFilesExist(`dist/create-${pluginName}-package/bin/index.js`);

expect(() => runCLI(`e2e e2e`)).not.toThrow();
});
});
59 changes: 32 additions & 27 deletions packages/create-nx-plugin/bin/create-nx-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,34 +43,34 @@ export const yargsDecorator = {

const nxVersion = require('../package.json').version;

function determinePluginName(parsedArgs: CreateNxPluginArguments) {
async function determinePluginName(
parsedArgs: CreateNxPluginArguments
): Promise<string> {
if (parsedArgs.pluginName) {
return Promise.resolve(parsedArgs.pluginName);
}

return enquirer
.prompt([
{
name: 'pluginName',
message: `Plugin name `,
type: 'input',
validate: (s) => (s.length ? true : 'Name cannot be empty'),
},
])
.then((a: { pluginName: string }) => {
if (!a.pluginName) {
output.error({
title: 'Invalid name',
bodyLines: [`Name cannot be empty`],
});
process.exit(1);
}
return a.pluginName;
const results = await enquirer.prompt<{ pluginName: string }>([
{
name: 'pluginName',
message: `Plugin name `,
type: 'input',
validate: (s_1) => (s_1.length ? true : 'Name cannot be empty'),
},
]);
if (!results.pluginName) {
output.error({
title: 'Invalid name',
bodyLines: [`Name cannot be empty`],
});
process.exit(1);
}
return results.pluginName;
}

interface CreateNxPluginArguments {
pluginName: string;
cliName?: string;
packageManager: PackageManager;
ci: CI;
allPrompts: boolean;
Expand All @@ -89,11 +89,16 @@ export const commandsObject: yargs.Argv<CreateNxPluginArguments> = yargs
'Create a new Nx plugin workspace',
(yargs) =>
withOptions(
yargs.positional('pluginName', {
describe: chalk.dim`Plugin name`,
type: 'string',
alias: ['name'],
}),
yargs
.positional('pluginName', {
describe: chalk.dim`Plugin name`,
type: 'string',
alias: ['name'],
})
.option('cliName', {
describe: 'Name of the CLI package to create workspace with plugin',
type: 'string',
}),
withNxCloud,
withCI,
withAllPrompts,
Expand Down Expand Up @@ -164,19 +169,19 @@ async function normalizeArgsMiddleware(
argv: yargs.Arguments<CreateNxPluginArguments>
): Promise<void> {
try {
const name = await determinePluginName(argv);
const pluginName = await determinePluginName(argv);
const packageManager = await determinePackageManager(argv);
const defaultBase = await determineDefaultBase(argv);
const nxCloud = await determineNxCloud(argv);
const ci = await determineCI(argv, nxCloud);

Object.assign(argv, {
name,
pluginName,
nxCloud,
packageManager,
defaultBase,
ci,
});
} as Partial<CreateNxPluginArguments & CreateWorkspaceOptions>);
} catch (e) {
console.error(e);
process.exit(1);
Expand Down
1 change: 1 addition & 0 deletions packages/create-nx-workspace/bin/create-nx-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ async function normalizeArgsMiddleware(
} else if (monorepoStyle === 'node-standalone') {
preset = Preset.NodeStandalone;
} else {
// when choose integrated monorepo, further prompt for preset
preset = await determinePreset(argv);
}
} else if (argv.preset === 'react') {
Expand Down
2 changes: 0 additions & 2 deletions packages/create-nx-workspace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
"bugs": {
"url": "https://github.com/nrwl/nx/issues"
},
"main": "./index.js",
"typings": "./index.d.ts",
"homepage": "https://nx.dev",
"dependencies": {
"chalk": "^4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/create-nx-workspace/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"build-base": {
"executor": "@nrwl/js:tsc",
"options": {
"main": "packages/create-nx-workspace/bin/create-nx-workspace.ts",
"main": "packages/create-nx-workspace/index.ts",
"assets": [
{
"input": "packages/create-nx-workspace",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PackageManager } from './utils/package-manager';
import { CI } from './utils/ci/ci-list';

export interface CreateWorkspaceOptions {
name: string; // Workspace name (e.g. org name)
Expand Down
2 changes: 1 addition & 1 deletion packages/create-nx-workspace/src/create-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function createWorkspace<T extends CreateWorkspaceOptions>(
nxCloud && nxCloudInstallRes?.code === 0
);
}
if (!skipGit) {
if (!skipGit && commit) {
try {
await initializeGitRepo(directory, { defaultBase, commit });
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import { isKnownPreset } from './preset';
/**
* This function is used to check if a preset is a third party preset.
* @param preset
* @returns null if the preset is a known Nx preset or preset does not exist, the normalized preset otherwise.
* @returns null if the preset is a known Nx preset or preset does not exist, the package name of preset otherwise.
*/
export async function getThirdPartyPreset(
preset?: string
): Promise<string | null> {
if (preset && !isKnownPreset(preset)) {
// extract the package name from the preset
const packageName = preset.match(/.+@/)
? preset[0] + preset.substring(1).split('@')[0]
: preset;
const validateResult = validateNpmPackage(packageName);
if (validateResult.validForNewPackages) {
return Promise.resolve(preset);
return Promise.resolve(packageName);
} else {
//! Error here
output.error({
Expand Down
2 changes: 1 addition & 1 deletion packages/js/src/utils/typescript/add-tslib-dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { addDependenciesToPackageJson, Tree } from '@nx/devkit';
import { tsLibVersion } from '../versions';

export function addTsLibDependencies(tree: Tree) {
addDependenciesToPackageJson(
return addDependenciesToPackageJson(
tree,
{
tslib: tsLibVersion,
Expand Down
Loading

0 comments on commit 86dd385

Please sign in to comment.