main
js 128 lines 2.91 KB
Raw
1 'use strict';
2
3 const chalk = require('chalk');
4 const {exec} = require('child-process-promise');
5 const {existsSync, mkdirSync} = require('fs');
6 const {readJsonSync, writeJsonSync} = require('fs-extra');
7 const inquirer = require('inquirer');
8 const {join} = require('path');
9 const createLogger = require('progress-estimator');
10 const {
11 BUILD_METADATA_TEMP_DIRECTORY,
12 NPM_PACKAGES,
13 } = require('./configuration');
14
15 const logger = createLogger({
16 storagePath: join(__dirname, '.progress-estimator'),
17 });
18
19 async function checkNPMPermissions() {
20 const currentUser = await execRead('npm whoami');
21 const failedProjects = [];
22
23 const checkProject = async project => {
24 const owners = (await execRead(`npm owner ls ${project}`))
25 .split('\n')
26 .filter(owner => owner)
27 .map(owner => owner.split(' ')[0]);
28
29 if (!owners.includes(currentUser)) {
30 failedProjects.push(project);
31 }
32 };
33
34 await logger(
35 Promise.all(NPM_PACKAGES.map(checkProject)),
36 `Checking NPM permissions for ${chalk.bold(currentUser)}.`,
37 {estimate: 2500}
38 );
39
40 console.log('');
41
42 if (failedProjects.length) {
43 console.error(chalk.red.bold('Insufficient NPM permissions'));
44 console.error('');
45 console.error(
46 chalk.red(
47 `NPM user {underline ${currentUser}} is not an owner for: ${chalk.bold(
48 failedProjects.join(', ')
49 )}`
50 )
51 );
52 console.error(
53 chalk.red(
54 'Please contact a React team member to be added to the above project(s).'
55 )
56 );
57 process.exit(1);
58 }
59 }
60
61 function clear() {
62 console.clear();
63 }
64
65 async function confirm(message, exitFunction) {
66 console.log('');
67
68 const {confirmation} = await inquirer.prompt({
69 name: 'confirmation',
70 type: 'confirm',
71 message,
72 });
73
74 console.log('');
75
76 if (!confirmation) {
77 if (typeof exitFunction === 'function') {
78 exitFunction();
79 }
80
81 process.exit(0);
82 }
83 }
84
85 async function confirmContinue(exitFunction) {
86 await confirm('Continue the release?', exitFunction);
87 }
88
89 async function execRead(command, options) {
90 const {stdout} = await exec(command, options);
91
92 return stdout.trim();
93 }
94
95 function readSavedBuildMetadata() {
96 const path = join(BUILD_METADATA_TEMP_DIRECTORY, 'metadata');
97
98 if (!existsSync(path)) {
99 console.error(chalk.red('Expected to find build metadata at:'));
100 console.error(chalk.dim(` ${path}`));
101 process.exit(1);
102 }
103
104 const {archivePath, currentCommitHash} = readJsonSync(path);
105
106 return {archivePath, currentCommitHash};
107 }
108
109 function saveBuildMetadata({archivePath, currentCommitHash}) {
110 const path = join(BUILD_METADATA_TEMP_DIRECTORY, 'metadata');
111
112 if (!existsSync(BUILD_METADATA_TEMP_DIRECTORY)) {
113 mkdirSync(BUILD_METADATA_TEMP_DIRECTORY);
114 }
115
116 writeJsonSync(path, {archivePath, currentCommitHash}, {spaces: 2});
117 }
118
119 module.exports = {
120 checkNPMPermissions,
121 clear,
122 confirm,
123 confirmContinue,
124 execRead,
125 logger,
126 readSavedBuildMetadata,
127 saveBuildMetadata,
128 };