UNPKG

@serpent/common-cli

Version:

通用的 cli 相关的函数

535 lines (484 loc) 15.8 kB
import fs$3 from 'fs'; import path$4 from 'path'; import assert from 'assert'; import { g as getDefaultExportFromCjs } from './_commonjsHelpers-7d1333e8.mjs'; import { a as existsExports } from './exists-d3d14d46.mjs'; import require$$1 from '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 = 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__*/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__*/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__*/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__*/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__*/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; } export { findupDir as a, findupPackage as b, findupPackageRoot as c, ensureFile as d, ensureDir as e, findupFile as f, exists as g, existsFile as h, existsNotFile as i, assertFile as j, existsDir as k, existsNotDir as l, mkdirp as m, assertDir as n, ospath as o, toOSPath as p, toPosixPath as q, rm as r, stat as s, tryStat as t, toWin32Path as u, mkdirp$2 as v, walk as w };