@shuyun-ep-team/scripts
Version:
为项目提供相应的脚本,使其减少繁琐的配置。
258 lines • 11.3 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const semver_1 = __importDefault(require("semver"));
const inquirer_1 = __importDefault(require("inquirer"));
const cross_spawn_1 = __importDefault(require("cross-spawn"));
const chalk_1 = __importDefault(require("../../tools/chalk"));
const sync_tnpm_1 = __importDefault(require("../sync-tnpm"));
const npm_1 = require("../utils/npm");
function genPackageVersion(distTags) {
return __awaiter(this, void 0, void 0, function* () {
const { latest, beta, alpha } = distTags;
const betaVersion = semver_1.default.gte(latest, beta) ? latest : beta;
const alphaVersion = semver_1.default.gte(latest, alpha) ? latest : alpha;
const prePublishTags = {
major: semver_1.default.inc(latest, 'major'),
minor: semver_1.default.inc(latest, 'minor'),
patch: semver_1.default.inc(latest, 'patch'),
beta: semver_1.default.inc(betaVersion, 'prerelease', 'beta'),
alpha: semver_1.default.inc(alphaVersion, 'prerelease', 'alpha'),
custom: ''
};
const { publishType } = yield inquirer_1.default.prompt([
{
type: 'list',
name: 'publishType',
message: '请选择发布版本类型: ',
default: 'patch',
choices: [
{
name: `做不兼容的 API 修改(${chalk_1.default.gray(`v${prePublishTags.major}`)})`,
value: 'major'
},
{
name: `做了向下兼容的功能性新增(${chalk_1.default.gray(`v${prePublishTags.minor})`)}`,
value: 'minor'
},
{
name: `做了向下兼容的问题修正(${chalk_1.default.gray(`v${prePublishTags.patch})`)}`,
value: 'patch'
},
{
name: `测试版 Beta(${chalk_1.default.gray(`v${prePublishTags.beta}`)})`,
value: 'beta'
},
{
name: `先行版 Alpha(${chalk_1.default.gray(`v${prePublishTags.alpha}`)})`,
value: 'alpha'
},
{ name: '自定义版本', value: 'custom' }
]
}
]);
if (publishType === 'custom') {
const { version } = yield inquirer_1.default.prompt([
{
type: 'input',
name: 'version',
message: '请输入自定义版本'
}
]);
if (semver_1.default.valid(version) === null) {
console.error(chalk_1.default.red(`输入自定义版本 ${version} 无效!`));
process.exit(1);
}
prePublishTags.custom = version;
}
return prePublishTags[publishType];
});
}
function getPackageDistTags(packageName) {
return __awaiter(this, void 0, void 0, function* () {
try {
const { stdout = '', stderr = '' } = cross_spawn_1.default.sync('npm', ['dist-tags', 'ls', packageName], {
encoding: 'utf-8'
});
const initTags = { latest: '0.0.0', beta: '0.0.0', alpha: '0.0.0' };
if (stderr) {
if (/npm ERR! code E404/g.test(stderr)) {
const { first } = yield inquirer_1.default.prompt([
{
type: 'confirm',
name: 'first',
message: '是否为第一次发版 ?'
}
]);
if (first) {
return initTags;
}
process.exit(1);
}
else {
throw new Error(stderr);
}
}
const matchArray = stdout.match(/(.+?):\s*(.*)/gu);
if (matchArray) {
return matchArray
.map(str => {
const [type, v] = str.split(':');
return { [type.trim()]: v.trim() };
})
.reduce((a, b) => Object.assign(a, b), initTags);
}
return initTags;
}
catch (error) {
throw new Error(error);
}
});
}
function publishToNpm(version, dir = '.') {
return __awaiter(this, void 0, void 0, function* () {
const prerelease = semver_1.default.prerelease(version);
const publishArgs = ['publish', dir, '--access', 'public'];
const versionArgs = ['version'];
if (prerelease !== null) {
versionArgs.push('prerelease', `--preid=${prerelease.join('.')}`);
publishArgs.push('--tag', prerelease[0]);
}
else {
versionArgs.push(version);
}
cross_spawn_1.default.sync('npm', versionArgs, { stdio: 'inherit', encoding: 'utf-8' });
cross_spawn_1.default.sync('npm', publishArgs, { stdio: 'inherit', encoding: 'utf-8' });
});
}
function updatePackageVersion(version) {
return __awaiter(this, void 0, void 0, function* () {
const pkg = require(`${process.cwd()}/package.json`);
pkg.version = version;
fs_extra_1.default.writeFileSync(`${process.cwd()}/package.json`, JSON.stringify(pkg, null, 2), {
encoding: 'utf-8'
});
});
}
function checkPublishAssets(dist) {
const pkgPath = path_1.default.join(process.cwd(), dist, 'package.json');
return fs_extra_1.default.existsSync(pkgPath);
}
function removePackageRedundantConfig(dist) {
const pkgPath = path_1.default.join(process.cwd(), dist, 'package.json');
const pkg = require(pkgPath);
Reflect.set(pkg, 'scripts', {});
fs_extra_1.default.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, {
encoding: 'utf-8'
});
}
function chainApply(items, defaultParams = []) {
return Promise.resolve(items.reduce((chain, current) => chain
.then((chainResult) => __awaiter(this, void 0, void 0, function* () {
chainResult.push(yield current(chainResult));
return Promise.resolve(chainResult);
}))
.catch(err => {
throw new Error(err);
}), Promise.resolve(defaultParams)));
}
exports.default = (config) => __awaiter(void 0, void 0, void 0, function* () {
try {
const { name, pre = [], post = [], autoProcessPackageJson = true, isPrerelease, dist = '.' } = config;
const context = process.cwd();
const release = !isPrerelease;
const result = npm_1.checkPackageName(name);
if (result.validForNewPackages === false && result.validForOldPackages === false) {
throw new Error(`npm package name ${chalk_1.default.green(name)} invalid`);
}
if (release === false) {
checkPublishEnv(name);
}
console.log(`正在执行 ${chalk_1.default.bgBlack.green(name)} 发布...`);
console.log(`进入执行目录:${chalk_1.default.green(context)}`);
console.log('获取当前项目版本信息:');
const distTags = yield getPackageDistTags(name);
const infoLog = Object.entries(distTags)
.map(([key, v]) => `${chalk_1.default.green(key)}: ${v}`)
.join('\n ');
console.log(`
version:
${infoLog}
`);
console.log('设置发布版本');
const version = (yield genPackageVersion(distTags));
console.log(`将发布版本号为:${chalk_1.default.green(`v${version}`)}`);
console.log('执行设定前置任务...');
yield chainApply(pre, [version]);
console.log('发布目录资源监测');
if (!checkPublishAssets(dist)) {
if (autoProcessPackageJson) {
fs_extra_1.default.ensureDirSync(path_1.default.join(context, dist));
fs_extra_1.default.copySync(path_1.default.join(context, 'package.json'), path_1.default.join(context, dist, 'package.json'));
}
else {
throw new Error(`发布目录 ${chalk_1.default.green(dist)} 中缺少 package.json 文件`);
}
}
removePackageRedundantConfig(dist);
if (!isPrerelease) {
console.log('执行发布...');
yield publishToNpm(version, dist);
console.log('同步至淘宝镜像');
yield sync_tnpm_1.default(name);
}
if (autoProcessPackageJson) {
updatePackageVersion(version);
}
console.log('执行设定后置任务...');
yield chainApply(post, [version]);
console.log(`✨ ${chalk_1.default.green(`${isPrerelease ? '预' : ''}发布完成!`)}`);
}
catch (error) {
console.error(error.message);
}
});
function checkPublishEnv(name) {
return __awaiter(this, void 0, void 0, function* () {
const registry = yield npm_1.getRegistry();
const isNpmRegistry = npm_1.checkNpmRegistry(registry);
console.log('检测当前发布环境:');
console.log(`${chalk_1.default.green('NPM 源地址:')}${registry}`);
if (isNpmRegistry) {
const username = getNPMLoginUsername();
console.log(chalk_1.default.green('NPM 账户:'), username);
const maintainers = npm_1.getPackageMaintainers(name);
if (maintainers.findIndex(item => (item === null || item === void 0 ? void 0 : item.user) === username) < 0) {
throw new Error('当前登陆账户不在本仓库维护人名列表中!!!');
}
return;
}
throw new Error(`${chalk_1.default.red('请切换 NPM 安装源为:')}${npm_1.NPMRegistry}
for example:
$ ${chalk_1.default.green('npm')} config set registry ${npm_1.NPMRegistry}
`);
});
}
function getNPMLoginUsername() {
const username = npm_1.getUsername();
if (username === null) {
console.log('请登录NPM账户...');
npm_1.npmLogin();
getNPMLoginUsername();
}
return username;
}
//# sourceMappingURL=index.js.map