#!/usr/bin/env node // we can import from '@nrwl/workspace' because it will require typescript import { output } from '@nrwl/workspace/src/utils/output'; import { dirSync } from 'tmp'; import { writeFileSync } from 'fs-extra'; import * as path from 'path'; import { execSync } from 'child_process'; import * as inquirer from 'inquirer'; import yargsParser = require('yargs-parser'); import { determinePackageManager, showNxWarning } from './shared'; const tsVersion = 'TYPESCRIPT_VERSION'; const cliVersion = 'NX_VERSION'; const nxVersion = 'NX_VERSION'; const prettierVersion = 'PRETTIER_VERSION'; const parsedArgs = yargsParser(process.argv, { string: ['pluginName'], alias: { pluginName: 'plugin-name', }, boolean: ['help'], }); if (parsedArgs.help) { showHelp(); process.exit(0); } const packageManager = determinePackageManager(); determineWorkspaceName(parsedArgs).then((workspaceName) => { return determinePluginName(parsedArgs).then((pluginName) => { const tmpDir = createSandbox(packageManager); createWorkspace(tmpDir, packageManager, parsedArgs, workspaceName); createNxPlugin(workspaceName, pluginName); commitChanges(workspaceName); showNxWarning(workspaceName); }); }); function createSandbox(packageManager: string) { console.log(`Creating a sandbox with Nx...`); const tmpDir = dirSync().name; writeFileSync( path.join(tmpDir, 'package.json'), JSON.stringify({ dependencies: { '@nrwl/workspace': nxVersion, '@nrwl/tao': cliVersion, typescript: tsVersion, prettier: prettierVersion, }, license: 'MIT', }) ); execSync(`${packageManager} install --silent`, { cwd: tmpDir, stdio: [0, 1, 2], }); return tmpDir; } function createWorkspace( tmpDir: string, packageManager: string, parsedArgs: any, name: string ) { const args = [ name, ...process.argv.slice(parsedArgs._[2] ? 3 : 2).map((a) => `"${a}"`), ].join(' '); console.log(`new ${args} --preset=empty --collection=@nrwl/workspace`); execSync( `"${path.join( tmpDir, 'node_modules', '.bin', 'tao' )}" new ${args} --preset=empty --collection=@nrwl/workspace`, { stdio: [0, 1, 2], } ); execSync(`${packageManager} add -D @nrwl/nx-plugin@${nxVersion}`, { cwd: name, stdio: [0, 1, 2], }); } function createNxPlugin(workspaceName, pluginName) { console.log(`nx generate @nrwl/nx-plugin:plugin ${pluginName}`); execSync( `node ./node_modules/@nrwl/cli/bin/nx.js generate @nrwl/nx-plugin:plugin ${pluginName}`, { cwd: workspaceName, stdio: [0, 1, 2], } ); } function commitChanges(workspaceName) { execSync('git add .', { cwd: workspaceName, stdio: 'ignore', }); execSync('git commit --amend --no-edit', { cwd: workspaceName, stdio: 'ignore', }); } function determineWorkspaceName(parsedArgs: any): Promise { const workspaceName: string = parsedArgs._[2]; if (workspaceName) { return Promise.resolve(workspaceName); } return inquirer .prompt([ { name: 'WorkspaceName', message: `Workspace name (e.g., org name) `, type: 'string', }, ]) .then((a) => { if (!a.WorkspaceName) { output.error({ title: 'Invalid workspace name', bodyLines: [`Workspace name cannot be empty`], }); process.exit(1); } return a.WorkspaceName; }); } function determinePluginName(parsedArgs) { if (parsedArgs.pluginName) { return Promise.resolve(parsedArgs.pluginName); } return inquirer .prompt([ { name: 'PluginName', message: `Plugin name `, type: 'string', }, ]) .then((a) => { if (!a.PluginName) { output.error({ title: 'Invalid name', bodyLines: [`Name cannot be empty`], }); process.exit(1); } return a.PluginName; }); } function showHelp() { console.log(` Usage: [options] Create a new Nx workspace Args: name workspace name (e.g., org name) Options: pluginName the name of the plugin to be created `); }