react/scripts/devtools/utils.js

129 lines
2.9 KiB
JavaScript

'use strict';
const chalk = require('chalk');
const {exec} = require('child-process-promise');
const {existsSync, mkdirSync} = require('fs');
const {readJsonSync, writeJsonSync} = require('fs-extra');
const inquirer = require('inquirer');
const {join} = require('path');
const createLogger = require('progress-estimator');
const {
BUILD_METADATA_TEMP_DIRECTORY,
NPM_PACKAGES,
} = require('./configuration');
const logger = createLogger({
storagePath: join(__dirname, '.progress-estimator'),
});
async function checkNPMPermissions() {
const currentUser = await execRead('npm whoami');
const failedProjects = [];
const checkProject = async project => {
const owners = (await execRead(`npm owner ls ${project}`))
.split('\n')
.filter(owner => owner)
.map(owner => owner.split(' ')[0]);
if (!owners.includes(currentUser)) {
failedProjects.push(project);
}
};
await logger(
Promise.all(NPM_PACKAGES.map(checkProject)),
`Checking NPM permissions for ${chalk.bold(currentUser)}.`,
{estimate: 2500}
);
console.log('');
if (failedProjects.length) {
console.error(chalk.red.bold('Insufficient NPM permissions'));
console.error('');
console.error(
chalk.red(
`NPM user {underline ${currentUser}} is not an owner for: ${chalk.bold(
failedProjects.join(', ')
)}`
)
);
console.error(
chalk.red(
'Please contact a React team member to be added to the above project(s).'
)
);
process.exit(1);
}
}
function clear() {
console.clear();
}
async function confirm(message, exitFunction) {
console.log('');
const {confirmation} = await inquirer.prompt({
name: 'confirmation',
type: 'confirm',
message,
});
console.log('');
if (!confirmation) {
if (typeof exitFunction === 'function') {
exitFunction();
}
process.exit(0);
}
}
async function confirmContinue(exitFunction) {
await confirm('Continue the release?', exitFunction);
}
async function execRead(command, options) {
const {stdout} = await exec(command, options);
return stdout.trim();
}
function readSavedBuildMetadata() {
const path = join(BUILD_METADATA_TEMP_DIRECTORY, 'metadata');
if (!existsSync(path)) {
console.error(chalk.red('Expected to find build metadata at:'));
console.error(chalk.dim(` ${path}`));
process.exit(1);
}
const {archivePath, buildID} = readJsonSync(path);
return {archivePath, buildID};
}
function saveBuildMetadata({archivePath, buildID}) {
const path = join(BUILD_METADATA_TEMP_DIRECTORY, 'metadata');
if (!existsSync(BUILD_METADATA_TEMP_DIRECTORY)) {
mkdirSync(BUILD_METADATA_TEMP_DIRECTORY);
}
writeJsonSync(path, {archivePath, buildID}, {spaces: 2});
}
module.exports = {
checkNPMPermissions,
clear,
confirm,
confirmContinue,
execRead,
logger,
readSavedBuildMetadata,
saveBuildMetadata,
};