Created
September 27, 2020 22:51
-
-
Save ThisIsMissEm/9c853fd9282787dfa306552d323d168e to your computer and use it in GitHub Desktop.
entrypoint.js is the entrypoint for the CLI and lives in bin/ and is tied to a scripts entry. bootstrap.js figures out the conditions under which we are executing, and extracts the argv variables from the command run in the terminal, so you can pass them to your cli.js file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import path from 'path'; | |
const debug = require('debug')('cli:bootstrap'); | |
debug({ | |
npm_lifecycle_script: process.env.npm_lifecycle_script, | |
npm_config_argv: process.env.npm_config_argv, | |
npm_config_username: process.env.npm_config_username, | |
}); | |
/* | |
A quick explanation of what all this code actually does: | |
We have a postinstall script, that we wish to run when you do a "general install", | |
i.e., run `$ yarn` or `$ npm install`, however, yarn isn't like npm in how it | |
executes the postinstall script, instead, yarn executes postinstall when adding | |
packages to your project, which means if you're working on the script, add a | |
dependency, and then try to install it with `$ yarn add --dev something`, then | |
your script will try to execute, typescript will fail to compile, and everything | |
goes tits up and your package doesn't end up installed because postinstall crashed. | |
So essentially all this code below tries to figure out if you're calling the CLI | |
directly, or from npm/yarn, if from a package manager, then it tries to figure out | |
if we're actually doing a general install and not trying to add or remove a package | |
from the project. | |
*/ | |
interface BootstrapSuccess { | |
runner: string; | |
argv: string[]; | |
} | |
interface BootstrapFailure { | |
reason: 'CI' | 'BY_PASS_POSTINSTALL'; | |
} | |
type BootstrapResult = BootstrapSuccess | BootstrapFailure; | |
export default function bootstrap(): BootstrapResult { | |
let runner = path.relative(process.cwd(), process.argv[1]); | |
if (process.env.npm_lifecycle_script && process.env.npm_config_user_agent) { | |
runner = /yarn/.test(process.env.npm_config_user_agent) ? 'yarn' : 'npm'; | |
} | |
let fromGeneralInstall = false; | |
let packageManagerArgs = []; | |
try { | |
packageManagerArgs = JSON.parse(process.env.npm_config_argv!); | |
} catch (err) { | |
// ignored | |
} | |
if (runner === 'yarn') { | |
// Only: | |
// $ yarn | |
// $ yarn install | |
// Not: | |
// $ yarn add | |
// $ yarn remove | |
// $ yarn install --production | |
// $ yarn --production | |
fromGeneralInstall = | |
// $ yarn | |
packageManagerArgs.cooked.length === 0 || | |
// $ yarn install | |
(packageManagerArgs.cooked[0] === 'install' && | |
packageManagerArgs.cooked.length === 1 && | |
(packageManagerArgs.original.length === 0 || | |
packageManagerArgs.original[0] === 'install')); | |
} | |
if (runner === 'npm') { | |
// only: | |
// $ npm install | |
// $ npm i | |
fromGeneralInstall = | |
(packageManagerArgs[0] === 'install' || packageManagerArgs[0] === 'i') && | |
packageManagerArgs.length === 1; | |
} | |
debug({ | |
fromGeneralInstall, | |
runner, | |
packageManagerArgs, | |
argv: process.argv, | |
}); | |
// Short-circuit under certain conditions if doing --postinstall: | |
if (process.argv.includes('--postinstall')) { | |
if (!fromGeneralInstall) { | |
debug('Not running postinstall, not from general install'); | |
return { reason: 'BY_PASS_POSTINSTALL' }; | |
} | |
if (process.env.CI === 'true') { | |
debug('Not running postinstall on CI'); | |
return { reason: 'CI' }; | |
} | |
} | |
return { | |
runner, | |
argv: process.argv.slice(2), | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const bootstrap = require('../dist/bootstrap.js').default; | |
const { reason, runner, argv } = bootstrap(); | |
if (reason === 'CI' || reason === 'BY_PASS_POSTINSTALL') { | |
process.exit(0); | |
} | |
// dist/cli is just a module exporting a `run` function: | |
// export function run(runner: string, argv: string[]): Promise<void> | |
require('../dist/cli.js') | |
.run(runner, argv) | |
.then( | |
() => { | |
process.exit(0); | |
}, | |
() => { | |
process.exit(1); | |
}, | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment