From 4467e86023303c5d29402c2a1c40330e31458b2b Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Sat, 28 Mar 2020 13:15:55 -0700 Subject: [PATCH] feat: add a script to scaffold and bootstrap a new package --- bin/create-package.js | 148 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 bin/create-package.js diff --git a/bin/create-package.js b/bin/create-package.js new file mode 100644 index 000000000000..4900399e4597 --- /dev/null +++ b/bin/create-package.js @@ -0,0 +1,148 @@ +#!/usr/bin/env node +// Copyright IBM Corp. 2018. All Rights Reserved. +// Node module: loopback-next +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +/** + * This is an internal script to add a new package to `packages` or `extensions` + * of the `loopback-next` monorepo. + * + * The script does the following steps: + * + * 1. Determine the location and package name. + * + * The first argument can be one of the following: + * - package-name + * - @loopback/package-name + * - extensions/package-name + * - packages/package-name + * + * If the location is not specified, it tries to guess by the current directory + * and falls back to `extensions`. + * + * 2. Run `lb4 extension` to scaffold the project without `npm install`. If + * `--yes` or `-y` is provide by the command, interactive prompts are skipped. + * + * 3. Tidy up the project + * - Remove unused files + * - Rename `tsconfig.json` to `tsconfig.build.json` + * - Improve `package.json` + * + * 4. Run `lerna boostrap` on the newly added package to set up dependencies + */ +'use strict'; + +const build = require('../packages/build'); +const path = require('path'); +const cwd = process.cwd(); +const fs = require('fs-extra'); + +let name = process.argv[2]; +if (name == null) { + console.error( + 'Usage: %s <[location]/package-name> [--yes]', + path.relative(cwd, process.argv[1]), + ); + process.exit(1); +} + +let location = undefined; + +// Check if the name is in the form of `/` +for (const loc of ['packages', 'extensions']) { + if (name.startsWith(`${loc}/`)) { + name = name.substring(`${loc}/`.length); + location = loc; + break; + } +} + +const rootPath = path.resolve(__dirname, '..'); +if (location == null) { + // Location not specified, try to infer it from the current directory + location = path.relative(rootPath, cwd); + if (location !== 'packages' && location !== 'extensions') { + location = 'extensions'; + } +} + +process.chdir(path.join(rootPath, location)); +console.log('Adding project %s/%s...', location, name); +const projectDir = `${location}/${name}`; + +// Run `lb4 extension` +const args = [ + 'extension', + `@loopback/${name}`, + '--outdir', + name, + '--no-vscode', + '--no-eslint', + '--no-prettier', + '--skip-install', +]; + +if (process.argv.includes('--yes') || process.argv.includes('-y')) { + args.push('--yes'); +} + +const child = build.runCLI( + path.join(rootPath, 'packages/cli/bin/cli-main'), + args, +); + +child.on('exit', code => { + if (code === 0) { + tidyupProject(); + process.chdir(rootPath); + // Run `npx lerna bootstrap --scope @loopback/` + build.runShell( + 'npx', + ['lerna', 'bootstrap', '--scope', `@loopback/${name}`], + { + cwd: rootPath, + }, + ); + } +}); + +function tidyupProject() { + process.chdir(path.join(rootPath, projectDir)); + // Update package.json + let pkg = fs.readJsonSync('package.json'); + pkg = { + ...pkg, + version: '0.0.1', + author: 'IBM Corp.', + 'copyright.owner': 'IBM Corp.', + license: 'MIT', + publishConfig: { + access: 'public', + }, + repository: { + type: 'git', + url: 'https://github.com/strongloop/loopback-next.git', + directory: projectDir, + }, + }; + fs.writeJsonSync('package.json', pkg); + + // Move tsconfig.json to tsconfig.build.json + fs.moveSync('tsconfig.json', 'tsconfig.build.json'); + + // Remove unused files + build.clean([ + 'node', + '../build/bin/run-clean.js', + 'DEVELOPING.md', + '.vscode', + '.eslintignore', + '.eslintrc.js', + '.prettierignore', + '.prettierrc', + '.gitignore', + '.mocharc.json', + '.yo-rc.json', + ]); +}