@serpent/common-cli
Version:
通用的 cli 相关的函数
160 lines (156 loc) • 6.32 kB
JavaScript
;
var Module = require('module');
var path = require('path');
var assert = require('assert');
var context = require('./context-e98d804e.cjs');
var readJsonFile = require('./readJsonFile-f1989956.cjs');
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
/** package.json 中的 name 的正则 */
var PROJECT_NAME_REGEXP = /(?:@([\w-]+)\/)?([\w-]+)/;
/** package.json 中的 name 的正则(匹配字符串的开始和结束) */
var PROJECT_NAME_REGEXP_FULL = /^(?:@([\w-]+)\/)?([\w-]+)$/;
/** package.json 中的 name 的正则(匹配字符串的开始) */
var PROJECT_NAME_REGEXP_START = /^(?:@([\w-]+)\/)?([\w-]+)/;
/** package.json 中的 name 的正则(匹配字符串的结束) */
var PROJECT_NAME_REGEXP_END = /(?:@([\w-]+)\/)?([\w-]+)$/;
/**
* 获取项目的根目录
*
* @param refAbsoluteFilePath 用于定位项目根目录的一个绝对路径,如果不传,默认使用 process.cwd
*/
function tryGetProjectRootDir(refAbsoluteFilePath) {
var refPath = refAbsoluteFilePath || process.cwd();
try {
// 移除后面 node_modules 目录 (会导致全局安装后执行 postinstall 时找不到根目录)
// const pkg = findup.pkg(refPath.replace(/[\\\/]node_modules(\b|[\\\/].*)$/, ''))
var pkg = context.findupPackage(refPath);
return path.dirname(pkg);
}
catch (e) {
return;
}
}
/**
* 判断指定的路径是否是一个项目(是否包含 package.json 文件)的根目录
*/
function isProjectRootDir(absDir) {
return context.existsFile(path.join(absDir, 'package.json'));
}
/** 确保指定的路径是项目根目录 */
function assertProjectRootDir(absDir, message) {
assert.ok(isProjectRootDir(absDir), message || "path ".concat(absDir, " is not a valid project root directory"));
}
/**
* 根据相对路径,获取其绝对路径(只能获取文件的,无法获取文件夹的)
*
* @param relativeProjectFilePath 相对于项目根目录的路径
* @param refAbsoluteFilePath 用于定位项目根目录的一个绝对路径,如果不传,默认使用 process.cwd
*
*/
function tryGetProjectFile(relativeProjectFilePath, refAbsoluteFilePath) {
return tryGetProjectPath(relativeProjectFilePath, refAbsoluteFilePath, context.existsFile);
}
/**
* 根据相对路径,获取其绝对路径(只能获取文件夹的,无法获取文件的)
*
* @param relativeProjectFilePath 相对于项目根目录的路径
* @param refAbsoluteFilePath 用于定位项目根目录的一个绝对路径,如果不传,默认使用 process.cwd
*
*/
function tryGetProjectDir(relativeProjectFilePath, refAbsoluteFilePath) {
return tryGetProjectPath(relativeProjectFilePath, refAbsoluteFilePath, context.existsDir);
}
function tryGetProjectPath(relativeProjectFilePath, refAbsoluteFilePath, fn) {
if (fn === void 0) { fn = context.exists; }
var rootDir = tryGetProjectRootDir(refAbsoluteFilePath);
if (rootDir) {
var file = path.join(rootDir, context.toOSPath(relativeProjectFilePath));
if (fn(file))
return file;
}
return;
}
/**
* 解析项目安装时可能会用的名称
* @param installName 项目名称,可以带有版本号,如:`vue`、`vue@^1`、`jquery@1.0.0`、`@serpent/foo@latest`
* @returns
* - `parseProjectInstallName("@serpent/foo@latest") => { scope: 'serpent', name: 'foo', tag: 'latest', range: '' }`
* - `parseProjectInstallName("foo@^1") => { scope: '', name: 'foo', tag: '', range: '^1' }`
* - `parseProjectInstallName("foo@*") => { scope: '', name: 'foo', tag: '', range: '' }`
*/
function parseProjectInstallName(installName) {
var _a, _b, _c;
var scope = '';
var range = '';
var tag = '';
var name = '';
var newName = installName;
var error = function () {
throw new Error("\"".concat(installName, "\" is not a valid project name"));
};
if (newName[0] === '@') {
_a = newName.substr(1).split('/'), scope = _a[0], newName = _a[1];
if (!scope || !newName)
error();
}
_b = newName.split('@'), name = _b[0], _c = _b[1], range = _c === void 0 ? '' : _c;
if (!name || !PROJECT_NAME_REGEXP_FULL.test(name))
error();
// range 还要支持 "*"
if (range && range !== '*' && /^[a-zA-Z][-\w]*$/.test(range)) {
tag = range;
range = '';
}
return {
scope: scope,
range: range,
tag: tag,
name: name,
};
}
/**
* 根据项目根目录,获取到 package.json 中指定的 bin 文件所在的绝对路径
*/
function tryGetProjectBinFile(rootDir, binKey) {
var bin = '';
var file = '';
try {
var pkg = readJsonFile.tryReadJsonFile(path.join(rootDir, 'package.json'));
bin = pkg.bin;
}
catch (e) { }
if (bin && typeof bin === 'string') {
file = path.resolve(rootDir, bin);
}
else if (typeof bin === 'object') {
if (binKey) {
if (bin[binKey]) {
file = path.resolve(rootDir, bin[binKey]);
}
}
else {
var binKeys = Object.keys(bin);
if (binKeys.length === 1) {
file = path.resolve(rootDir, bin[binKeys[0]]);
}
}
}
if (file) {
try {
return Module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cjs/project-7917b261.cjs', document.baseURI).href))).resolve(file);
}
catch (e) { }
}
return;
}
exports.PROJECT_NAME_REGEXP = PROJECT_NAME_REGEXP;
exports.PROJECT_NAME_REGEXP_END = PROJECT_NAME_REGEXP_END;
exports.PROJECT_NAME_REGEXP_FULL = PROJECT_NAME_REGEXP_FULL;
exports.PROJECT_NAME_REGEXP_START = PROJECT_NAME_REGEXP_START;
exports.assertProjectRootDir = assertProjectRootDir;
exports.isProjectRootDir = isProjectRootDir;
exports.parseProjectInstallName = parseProjectInstallName;
exports.tryGetProjectBinFile = tryGetProjectBinFile;
exports.tryGetProjectDir = tryGetProjectDir;
exports.tryGetProjectFile = tryGetProjectFile;
exports.tryGetProjectRootDir = tryGetProjectRootDir;