#!/usr/bin/env node // we can't import from '@nrwl/workspace' because it will require typescript // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries import { output } from '@nrwl/workspace/src/utils/output'; import { dirSync } from 'tmp'; import { writeFileSync, readFileSync, removeSync } from 'fs-extra'; import * as path from 'path'; import { execSync } from 'child_process'; import * as inquirer from 'inquirer'; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore 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'], }); 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 updateWorkspace(workspaceName: string) { const nxJsonPath = path.join(workspaceName, 'nx.json'); const nxJson = JSON.parse(readFileSync(nxJsonPath).toString('UTF-8')); nxJson['workspaceLayout'] = { appsDir: 'e2e', libsDir: 'packages', }; writeFileSync(nxJsonPath, JSON.stringify(nxJson, undefined, 2)); removeSync(path.join(workspaceName, 'apps')); removeSync(path.join(workspaceName, 'libs')); } 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 `); } 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); updateWorkspace(workspaceName); createNxPlugin(workspaceName, pluginName); commitChanges(workspaceName); showNxWarning(workspaceName); }); });