Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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.
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),
};
}
#!/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