@ant-design/tools
Version:
tools for ant design
137 lines (134 loc) • 4.35 kB
JavaScript
import { getProjectPath } from "../utils/projectHelper";
import { join } from 'path';
import chalk from 'chalk';
import fetch from 'node-fetch';
import readline from 'readline';
import minimist from 'minimist';
import Arborist from '@npmcli/arborist';
import packlist from 'npm-packlist';
const argv = minimist(process.argv.slice(2));
// Added interface to replace "any"
function getMajorVersion(version, specificVersion) {
if (specificVersion) {
return `@${specificVersion}`;
}
const match = version && version.match(/^\d+/);
if (match) {
return `@${match[0]}.x`;
}
return '';
}
function getVersionFromURL(url, name) {
const affix = url.slice(url.indexOf(name) + name.length + 1);
return affix.slice(0, affix.indexOf('/'));
}
export default function (packageName, packageVersion, done) {
const mergedVersion = getMajorVersion(packageVersion, argv.version);
console.log(chalk.cyan(`Fetching latest version file list...${packageName}${mergedVersion}`));
function getLatestVersionFileList() {
return fetch(`https://unpkg.com/${packageName}${mergedVersion}/?meta`).then(res => {
const version = getVersionFromURL(res.url, packageName);
return res.json().then(json => ({
version,
...json
}));
}).then(({
version,
files: pkgFiles
}) => {
function flattenPath(files, fileList = []) {
(files || []).forEach(({
path,
files: subFiles
}) => {
const realPath = argv.path ? join(argv.path, path) : path;
fileList.push(realPath);
flattenPath(subFiles, fileList);
});
return fileList;
}
return {
version,
fileList: flattenPath(pkgFiles)
};
});
}
function getLocalVersionFileList() {
const arborist = new Arborist({
path: getProjectPath()
});
return arborist.loadActual().then(packlist);
}
Promise.all([getLocalVersionFileList(), getLatestVersionFileList()]).then(([localFiles, {
version,
fileList
}]) => {
const localSet = new Set(localFiles);
const remoteSet = new Set(fileList);
const missingFiles = [];
const addedFiles = [];
const allFiles = new Set([...fileList, ...localFiles]);
allFiles.forEach(filePath => {
if (!localSet.has(filePath)) {
missingFiles.push(filePath);
} else if (!remoteSet.has(filePath)) {
addedFiles.push(filePath);
}
});
return {
missingFiles,
addedFiles,
version
};
}).then(({
missingFiles,
addedFiles,
version
}) => {
if (addedFiles.length) {
console.log(chalk.yellow(`⚠️ Some file added in current build (last version: ${version}):`));
addedFiles.forEach(filePath => {
console.log(` + ${filePath}`);
});
// Separator
console.log();
console.log(chalk.gray(`-`.repeat(process.stdout.columns || 64)));
console.log();
}
if (missingFiles.length) {
console.log(chalk.red(`⚠️ Some file missing in current build (last version: ${version}):`));
missingFiles.forEach(filePath => {
console.log(` - ${filePath}`);
});
}
const total = missingFiles.length + addedFiles.length;
if (total) {
return Promise.reject(new Error(`Please double confirm with files. ${missingFiles.length} missing, ${addedFiles.length} added.`));
}
console.log(chalk.green('✅ Nothing missing compare to latest version:'), chalk.gray(version));
return 0;
}).then(() => done()).catch(err => {
console.error(err);
console.log(chalk.yellow('\nNeed confirm for file diff:'));
function userConfirm() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(['Type "YES" to confirm it is safe.', 'Type "NO" to exit process.', ''].join('\n'), answer => {
rl.close();
if (answer === 'YES') {
console.log(chalk.green('✅ Confirm it is OK.'));
done();
} else if (answer === 'NO') {
console.log(chalk.red('🚫 Aha! Catch you!'));
done(new Error('User cancel the process.'));
} else {
console.log(chalk.yellow('Invalidate input. Type again!'));
userConfirm();
}
});
}
userConfirm();
});
}