@serpent/common-cli
Version:
通用的 cli 相关的函数
559 lines (507 loc) • 16.2 kB
JavaScript
;
var fs$3 = require('fs');
var path$4 = require('path');
var assert = require('assert');
var _commonjsHelpers = require('./_commonjsHelpers-ed042b00.cjs');
var exists$1 = require('./exists-4a19b288.cjs');
var require$$1 = require('os');
var findup = {exports: {}};
/**
* @module libs/fs/findup
* @createdAt 2016-06-30
*
* @copyright Copyright (c) 2016 Zhonglei Qiu
* @license Licensed under the MIT license.
*/
(function (module, exports) {
var fs = fs$3;
var path = path$4;
var exists = exists$1.existsExports;
/**
*
* 递归向上查找满足条件的文件夹
*
* @param {String} dir 起始查找目录
* @param {String|Function} iteratorSync 要查找到文件名,或者返回 Boolean 值的函数,
* 如果此参数是函数,那么它会接收到参数是当前递归所在的目录
* @param {Object} [options] 配置选项
*
* - allowTypes: {String|Array<String>} 要查找的文件所属类型, 参考 {@link module:libs/fs/exists} 函数的第二个参数
* - maxdepth: {Number} 递归的深度,1:表示只会查找当前文件夹下的文件,2:表示查找当前文件夹和上一个文件夹 ...
*
* @throws {Error} 如果没有找到任何满足条件的文件夹
* @return {String} 查找到的满足条件的文件夹路径
*
* @author Zhongle Qiu
* @since 2.0.0
*
*/
module.exports = function(dir, iteratorSync, options) {
dir = path.normalize(dir);
options = options || {};
if (typeof iteratorSync === 'string') {
var file = iteratorSync;
iteratorSync = function(dir) {
return exists(path.join(dir, file), options.allowTypes)
};
}
var currentDepth = 0;
while (dir !== path.resolve(dir, '..')) {
if (typeof options.maxdepth === 'number' && options.maxdepth >= 0 && currentDepth >= options.maxdepth) {
break
}
currentDepth++;
if (iteratorSync(dir)) return dir
dir = path.resolve(dir, '..');
}
throw new Error('Not found')
};
exports = module.exports;
function _find(root, file, allowTypes) {
if (file == null) {
file = root;
root = process.cwd();
}
var dir = exports(root, file, {allowTypes: allowTypes});
return path.resolve(path.join(dir, file))
}
/**
* 递归向上查找指定的文件
*
* @param {String} [root] 起始查找目录(如果没有指定,则从当前路径开始)
* @param {String} file 要查找的文件名
* @throws {Error} 如果没有找到满足条件的文件
* @return {String} 返回查到的文件路径
*
* @author Zhongle Qiu
* @since 1.5.0
*/
exports.file = function(root, file) {
return _find(root, file, 'File')
};
/**
* 递归向上查找指定的文件夹
*
* @param {String} [root] 起始查找目录(如果没有指定,则从当前路径开始)
* @param {String} dir 要查找的文件夹名
* @throws {Error} 如果没有找到满足条件的文件夹
* @return {String} 返回查到的文件夹路径
*
* @author Zhongle Qiu
* @since 1.5.0
*/
exports.dir = function(root, dir) {
return _find(root, dir, 'Directory')
};
/**
* 递归向上查找 package.json 文件
*
* @param {String} [root] 起始查找目录(如果没有指定,则从当前路径开始)
* @throws {Error} 如果没有找到 package.json 文件
* @return {String} 返回查到的 package.json 的路径
*
* @author Zhongle Qiu
* @since 1.5.0
*/
exports.pkg = function(root) {
return exports.file(root || process.cwd(), 'package.json')
};
/**
* 递归向上查找 .git 文件夹
*
* @param {String} [root] 起始查找目录(如果没有指定,则从当前路径开始)
* @throws {Error} 如果没有找到 .git 文件夹
* @return {String} 返回查到的 .git 文件夹的路径
*
* @author Zhongle Qiu
* @since 1.5.0
*/
exports.git = function(root) {
var dir = _find(root || process.cwd(), '.git', ['File', 'Directory']);
var stats = fs.statSync(dir);
if (!stats.isDirectory()) { // .git 可能是一个文件,而不是文件夹
return fs.readFileSync(dir, 'utf8').substring('gitdir: '.length).trim()
}
return dir
};
} (findup, findup.exports));
var findupExports = findup.exports;
var _findup = /*@__PURE__*/_commonjsHelpers.getDefaultExportFromCjs(findupExports);
/**
*
* @module libs/fs/mkdirp
* @createdAt 2016-08-05
*
* @copyright Copyright (c) 2016 Zhonglei Qiu
* @license Licensed under the MIT license.
*/
var fs$2 = fs$3;
var path$3 = path$4;
var o777 = parseInt('0777', 8);
/**
* 创建目录
*
* 如果上级目录不存在,也会创建,类似于 Linux 的 mkdirp
* @param {String} p 要创建的目录
* @param {Object|Number} opts 配置或者直接指定要创建的目录的
* @param {Number} opts.mode
* @param {Object} opts.fs
* @return {String}
*/
var mkdirp$1 = function mkdirp(p, opts, made) {
if (!opts || typeof opts !== 'object') {
opts = { mode: opts };
}
var mode = opts.mode;
var xfs = opts.fs || fs$2;
if (mode === undefined) {
mode = o777 & (~process.umask());
}
if (!made) made = null;
p = path$3.resolve(p);
try {
xfs.mkdirSync(p, mode);
made = made || p;
} catch (err0) {
switch (err0.code) {
case 'ENOENT':
/* istanbul ignore if */
if (path$3.dirname(p) === p) throw err0
made = mkdirp(path$3.dirname(p), opts, made);
mkdirp(p, opts, made);
break
// In the case of any other error, just see if there's a dir
// there already. If so, then hooray! If not, then something
// is borked.
default:
var stat;
try {
stat = xfs.statSync(p);
} catch (err1) {
/* istanbul ignore next */
throw err0
}
/* istanbul ignore else */
if (!stat.isDirectory()) throw err0
}
}
return made
};
var mkdirp$2 = /*@__PURE__*/_commonjsHelpers.getDefaultExportFromCjs(mkdirp$1);
/**
*
* @module libs/fs/ospath
* @createdAt 2017-07-14
*
* @copyright Copyright (c) 2017 Zhonglei Qiu
* @license Licensed under the MIT license.
* @see https://github.com/jprichardson/ospath/blob/1.2.2/index.js
*/
var path$2 = path$4;
var os = require$$1;
function data() {
switch (this.__platform || /* istanbul ignore next */ process.platform) {
case 'win32': return path$2.resolve(process.env.APPDATA)
case 'darwin': return path$2.resolve(path$2.join(home.call(this), 'Library/Application Support/'))
default: return process.env.XDG_CONFIG_HOME
? path$2.resolve(process.env.XDG_CONFIG_HOME)
: path$2.resolve(path$2.join(home.call(this), '.config/'))
}
}
function desktop() {
return path$2.join(home.call(this), 'Desktop')
}
function home() {
/* istanbul ignore else */
if ('homedir' in os) return os.homedir() // io.js >= 2.3
/* istanbul ignore next */
switch (this.__platform || process.platform) {
case 'win32': return path$2.resolve(process.env.USERPROFILE)
default: return path$2.resolve(process.env.HOME)
}
}
function tmp() {
switch (this.__platform || /* istanbul ignore next */ process.platform) {
case 'win32': return path$2.resolve(process.env.TEMP)
default: return path$2.resolve('/tmp')
}
}
var ospath$1 = {
__platform: process.platform,
data: data,
desktop: desktop,
home: home,
tmp: tmp
};
var ospath_1 = ospath$1;
var _ospath = /*@__PURE__*/_commonjsHelpers.getDefaultExportFromCjs(ospath_1);
/**
* 递归删除指定的文件夹或文件
*
* @module libs/fs/rm
* @createdAt 2016-08-05
*
* @copyright Copyright (c) 2016 Zhonglei Qiu
* @license Licensed under the MIT license.
*/
var fs$1 = fs$3;
var path$1 = path$4;
/**
* 递归遍历删除指定的文件或文件夹
* @param {String} file 要删除的文件的路径
*/
function rm$1(file) {
var stat;
try {
stat = fs$1.statSync(file);
} catch (e) {
/* istanbul ignore else */
if (e.message.indexOf('ENOENT') === 0) {
return false
}
/* istanbul ignore next */
throw e
}
if (stat.isDirectory()) {
return rmDir(file)
} else {
return rmFile(file)
}
}
function rmFile(file) {
return fs$1.unlinkSync(file)
}
function rmDir(dir) {
fs$1.readdirSync(dir).forEach(function(item) {
rm$1(path$1.join(dir, item));
});
return fs$1.rmdirSync(dir)
}
var rm_1 = rm$1;
var _rm = /*@__PURE__*/_commonjsHelpers.getDefaultExportFromCjs(rm_1);
var fs = fs$3;
var path = path$4;
function walk$1(rootDir, callback) {
fs.readdirSync(rootDir).forEach(function(fileName) {
var fileFullPath = path.join(rootDir, fileName);
var fileStat = fs.statSync(fileFullPath);
if (callback(rootDir, fileName, fileFullPath, fileStat) !== false) {
if (fileStat.isDirectory()) {
walk$1(fileFullPath, callback);
}
}
});
}
var walk_1 = walk$1;
var _walk = /*@__PURE__*/_commonjsHelpers.getDefaultExportFromCjs(walk_1);
/**
* 将文件路径转化成操作系统相关的路径
* @param filePath 文件路径
*/
function toOSPath(filePath, sep) {
if (sep === void 0) { sep = path$4.sep; }
return filePath.split(/[\\/]/).join(sep);
}
/**
* 将文件路径转化成 posix 系统相关的路径
* @param filePath 文件路径
*/
function toPosixPath(filePath) {
return toOSPath(filePath, path$4.posix.sep);
}
/**
* 将文件路径转化成 win32 系统相关的路径
* @param filePath 文件路径
*/
function toWin32Path(filePath) {
return toOSPath(filePath, path$4.win32.sep);
}
/** 向上递归查找指定的文件 */
function findupFile(name, refRootPath) {
var ref = refRootPath || process.cwd();
try {
return _findup.file(ref, name);
}
catch (e) {
throw new Error("can't found up file whose name is \"".concat(name, "\" from directory ").concat(ref, " "));
}
}
/** 向上递归查找指定名称的文件夹 */
function findupDir(name, refRootPath) {
var ref = refRootPath || process.cwd();
try {
return _findup.dir(ref, name);
}
catch (e) {
throw new Error("can't found up directory whose name is \"".concat(name, "\" from directory ").concat(ref, " "));
}
}
/**
* 向上递归查找有效的 package.json 文件
*
* @testing-library/user-event 项目在生成的 dist 文件下还有 package.json 目录,这种情况会避免返回错误的路径,
* 处理方法: 如果有 node_modules,则 package.json 目录前不应该出现三层结构,会根据层级结构优化
*/
function findupPackage(refRootPath) {
var ref = refRootPath || process.cwd();
try {
var result = _findup.pkg(ref);
var NM = 'node_modules';
// result 示例: xx/node_modules/@testing-library/user-event/dist/cjs
if (result.includes(NM)) {
var splitIndex = result.lastIndexOf(NM) + NM.length + 1;
// prefix 示例: xx/node_modules/
// suffix 示例: @testing-library/user-event/dist/cjs
var prefix = result.substring(0, splitIndex);
var suffix = result.substring(splitIndex);
var parts = suffix.split(/[/\\]/);
var tmp = void 0;
if (suffix[0] === '@') {
tmp = parts.length === 2 ? result : path$4.join(prefix, parts[0], parts[1]);
}
else {
tmp = parts.length === 1 ? result : path$4.join(prefix, parts[0]);
}
tmp = path$4.join(tmp, 'package.json');
return existsFile(tmp) ? tmp : result;
}
return result;
}
catch (e) {
throw new Error("can't found up \"package.json\" in directory ".concat(ref));
}
}
/** 向上递归查找包含 package.json 的目录 */
function findupPackageRoot(refRootPath) {
return path$4.dirname(findupPackage(refRootPath));
}
/** 递归删除指定路径上的内容 */
function rm(absPath) {
return _rm(absPath);
}
/** 遍历指定目录上的内容 */
function walk(absDir, callback) {
return _walk(absDir, callback);
}
var ospath = {
__platform: _ospath.__platform,
/**
* 获取系统存放数据的目录,优先读取 XDG_DATA_HOME 环境变量
*/
data: makeSystemDir('data', 'XDG_DATA_HOME'),
/**
* 获取系统桌面目录
*/
desktop: makeSystemDir('desktop'),
/**
* 获取系统的当前用户目录
*/
home: makeSystemDir('home'),
/**
* 获取系统的临时目录
*/
tmp: makeSystemDir('tmp'),
/**
* 获取系统的缓存目录,优先读取 XDG_CACHE_HOME 环境变量,其次 "$HOME/.cache"
*/
cache: makeCustomDir('.cache', 'XDG_CACHE_HOME'),
/**
* 获取系统的配置目录,优先读取 XDG_CONFIG_HOME 环境变量,其次 "$HOME/.config"
*/
config: makeCustomDir('.config', 'XDG_CONFIG_HOME'),
};
function makeCustomDir(custom, envKey) {
return function (subpath) { return getDir(envKey && process.env[envKey] || path$4.join(_ospath.home(), custom), subpath); };
}
function makeSystemDir(key, envKey) {
return function (subpath) { return getDir(envKey && process.env[envKey] || _ospath[key](), subpath); };
}
function getDir(root, subpath) {
return subpath ? path$4.resolve(root, toOSPath(subpath)) : root;
}
/** 递归创建文件夹 */
function mkdirp(absDir) {
return mkdirp$2(absDir);
}
/** 确保文件夹存在 */
function ensureDir(absDir) {
mkdirp(absDir);
}
/** 确保文件存在 */
function ensureFile(absPath) {
if (!existsFile(absPath)) {
ensureDir(path$4.dirname(absPath));
fs$3.writeFileSync(absPath, '');
}
}
/** 判断指定路径上是否存在内容 */
function exists(absPath) {
return !!tryStat(absPath);
}
/** 判断指定路径上是否存在文件 */
function existsFile(absFile) {
return tryStatExists(absFile, 'isFile');
}
/** 判断指定路径上是否存在非文件的内容 */
function existsNotFile(absPath) {
return tryStatExists(absPath, 'isFile', true);
}
/** 判断文件是否存在,不存在则抛出异常 */
function assertFile(absFile, message) {
assert.ok(existsFile(absFile), message || "file \"".concat(absFile, "\" is not exists"));
}
/** 判断指定路径上是否存在文件夹 */
function existsDir(absDir) {
return tryStatExists(absDir, 'isDirectory');
}
/** 判断指定路径上是否存在非文件夹的内容 */
function existsNotDir(absPath) {
return tryStatExists(absPath, 'isDirectory', true);
}
/** 判断文件是否存在,不存在则抛出异常 */
function assertDir(absDir, message) {
assert.ok(existsDir(absDir), message || "directory \"".concat(absDir, "\" is not exists"));
}
/** 获取文件的 stats 对象 */
function stat(absPath) {
return fs$3.statSync(absPath);
}
/** 尝试获取文件的 stats 对象,如果不存在返回 undefined */
function tryStat(absPath) {
try {
return stat(absPath);
}
catch (e) {
return;
}
}
function tryStatExists(absPath, fnKey, reverse) {
var stats = tryStat(absPath);
if (!stats)
return false;
var res = stats[fnKey]();
return reverse ? !res : res;
}
exports.assertDir = assertDir;
exports.assertFile = assertFile;
exports.ensureDir = ensureDir;
exports.ensureFile = ensureFile;
exports.exists = exists;
exports.existsDir = existsDir;
exports.existsFile = existsFile;
exports.existsNotDir = existsNotDir;
exports.existsNotFile = existsNotFile;
exports.findupDir = findupDir;
exports.findupFile = findupFile;
exports.findupPackage = findupPackage;
exports.findupPackageRoot = findupPackageRoot;
exports.mkdirp = mkdirp;
exports.mkdirp$1 = mkdirp$2;
exports.ospath = ospath;
exports.rm = rm;
exports.stat = stat;
exports.toOSPath = toOSPath;
exports.toPosixPath = toPosixPath;
exports.toWin32Path = toWin32Path;
exports.tryStat = tryStat;
exports.walk = walk;