UNPKG

@appium/docutils

Version:

Documentation generation utilities for Appium and related projects

217 lines 8.26 kB
"use strict"; /** * Functions which touch the filesystem * @module */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.readMkDocsYml = exports.findPython = exports.findMike = exports.isMkDocsInstalled = exports.readJson = exports.readPackageJson = exports.findMkDocsYml = exports.stringifyJson = exports.stringifyYaml = void 0; exports.findInPkgDir = findInPkgDir; exports.writeFileString = writeFileString; exports.requirePython = requirePython; const support_1 = require("@appium/support"); const lodash_1 = __importDefault(require("lodash")); const node_path_1 = __importDefault(require("node:path")); const pkg_dir_1 = __importDefault(require("pkg-dir")); const read_pkg_1 = __importDefault(require("read-pkg")); const yaml_1 = __importDefault(require("yaml")); const constants_1 = require("./constants"); const error_1 = require("./error"); const logger_1 = require("./logger"); const teen_process_1 = require("teen_process"); const log = (0, logger_1.getLogger)('fs'); /** * Finds path to closest `package.json` * * Caches result */ const findPkgDir = lodash_1.default.memoize(pkg_dir_1.default); /** * Stringifies a thing into a YAML * @param value Something to yamlify * @returns Some nice YAML 4 u */ exports.stringifyYaml = lodash_1.default.partialRight(yaml_1.default.stringify, { indent: 2 }, undefined); /** * Pretty-stringifies a JSON value * @param value Something to stringify * @returns JSON string */ exports.stringifyJson = lodash_1.default.partialRight(JSON.stringify, 2, undefined); /** * Reads a YAML file, parses it and caches the result */ const readYaml = lodash_1.default.memoize(async (filepath) => yaml_1.default.parse(await support_1.fs.readFile(filepath, 'utf8'), { prettyErrors: false, logLevel: 'silent', })); /** * Finds a file from `cwd`. Searches up to the package root (dir containing `package.json`). * * @param filename Filename to look for * @param cwd Dir it should be in * @returns */ async function findInPkgDir(filename, cwd = process.cwd()) { const pkgDir = await findPkgDir(cwd); if (!pkgDir) { return; } return node_path_1.default.join(pkgDir, filename); } /** * Finds an `mkdocs.yml`, expected to be a sibling of `package.json` * * Caches the result. * @param cwd - Current working directory * @returns Path to `mkdocs.yml` */ exports.findMkDocsYml = lodash_1.default.memoize(lodash_1.default.partial(findInPkgDir, constants_1.NAME_MKDOCS_YML)); async function _readPkgJson(cwd, normalize) { const pkgDir = await findPkgDir(cwd); if (!pkgDir) { throw new error_1.DocutilsError(`Could not find a ${constants_1.NAME_PACKAGE_JSON} near ${cwd}; please create it before using this utility`); } const pkgPath = node_path_1.default.join(pkgDir, constants_1.NAME_PACKAGE_JSON); log.debug('Found `package.json` at %s', pkgPath); if (normalize) { const pkg = await (0, read_pkg_1.default)({ cwd: pkgDir, normalize }); return { pkg, pkgPath }; } else { const pkg = await (0, read_pkg_1.default)({ cwd: pkgDir }); return { pkg, pkgPath }; } } /** * Given a directory to start from, reads a `package.json` file and returns its path and contents */ exports.readPackageJson = lodash_1.default.memoize(_readPkgJson); /** * Reads a JSON file and parses it */ exports.readJson = lodash_1.default.memoize(async (filepath) => JSON.parse(await support_1.fs.readFile(filepath, 'utf8'))); /** * Writes contents to a file. Any JSON objects are stringified * @param filepath - Path to file * @param content - File contents */ function writeFileString(filepath, content) { const data = lodash_1.default.isString(content) ? content : JSON.stringify(content, undefined, 2); return support_1.fs.writeFile(filepath, data, { encoding: 'utf8', }); } /** * `which` with memoization */ const cachedWhich = lodash_1.default.memoize(support_1.fs.which); /** * Finds `python` executable */ const whichPython = lodash_1.default.partial(cachedWhich, constants_1.NAME_PYTHON, { nothrow: true }); /** * Finds `python3` executable */ const whichPython3 = lodash_1.default.partial(cachedWhich, `${constants_1.NAME_PYTHON}3`, { nothrow: true }); /** * Check if `mkdocs` is installed */ exports.isMkDocsInstalled = lodash_1.default.memoize(async () => { // see if it's in PATH const mkDocsPath = await cachedWhich(constants_1.NAME_MKDOCS, { nothrow: true }); if (mkDocsPath) { return true; } // if it isn't, it should be invokable via `python -m` const pythonPath = await (0, exports.findPython)(); if (!pythonPath) { return false; } try { await (0, teen_process_1.exec)(pythonPath, ['-m', constants_1.NAME_MKDOCS]); return true; } catch { return false; } }); /** * `mike` cannot be invoked via `python -m`, so we need to find the script. */ exports.findMike = lodash_1.default.partial(async () => { // see if it's in PATH let mikePath = await cachedWhich(constants_1.NAME_MIKE, { nothrow: true }); if (mikePath) { return mikePath; } // if it isn't, it may be in a user dir const pythonPath = await (0, exports.findPython)(); if (!pythonPath) { return; } try { // the user dir can be found this way. // usually it's something like ~/.local const { stdout } = await (0, teen_process_1.exec)(pythonPath, ['-m', 'site', '--user-base']); if (stdout) { mikePath = node_path_1.default.join(stdout.trim(), 'bin', 'mike'); if (await support_1.fs.isExecutable(mikePath)) { return mikePath; } } } catch { } }); /** * Finds the `python3` or `python` executable in the user's `PATH`. * * `python3` is preferred over `python`, since the latter could be Python 2. */ exports.findPython = lodash_1.default.memoize(async () => (await whichPython3()) ?? (await whichPython())); /** * Check if a path to Python exists, otherwise raise DocutilsError */ async function requirePython(pythonPath) { const foundPythonPath = pythonPath ?? (await (0, exports.findPython)()); if (!foundPythonPath) { throw new error_1.DocutilsError(constants_1.MESSAGE_PYTHON_MISSING); } return foundPythonPath; } /** * Reads an `mkdocs.yml` file, merges inherited configs, and returns the result. The result is cached. * * **IMPORTANT**: The paths of `site_dir` and `docs_dir` are resolved to absolute paths, since they * are expressed as relative paths, and each inherited config file can live in different paths. * @param filepath Patgh to an `mkdocs.yml` file * @returns Parsed `mkdocs.yml` file */ exports.readMkDocsYml = lodash_1.default.memoize(async (filepath, cwd = process.cwd()) => { let mkDocsYml = (await readYaml(filepath)); if (mkDocsYml.site_dir) { mkDocsYml.site_dir = node_path_1.default.resolve(cwd, node_path_1.default.dirname(filepath), mkDocsYml.site_dir); } if (mkDocsYml.INHERIT) { let inheritPath = node_path_1.default.resolve(node_path_1.default.dirname(filepath), mkDocsYml.INHERIT); while (inheritPath) { const inheritYml = (await readYaml(inheritPath)); if (inheritYml.site_dir) { inheritYml.site_dir = node_path_1.default.resolve(node_path_1.default.dirname(inheritPath), inheritYml.site_dir); log.debug('Resolved site_dir to %s', inheritYml.site_dir); } if (inheritYml.docs_dir) { inheritYml.docs_dir = node_path_1.default.resolve(node_path_1.default.dirname(inheritPath), inheritYml.docs_dir); log.debug('Resolved docs_dir to %s', inheritYml.docs_dir); } mkDocsYml = lodash_1.default.defaultsDeep(mkDocsYml, inheritYml); inheritPath = inheritYml.INHERIT ? node_path_1.default.resolve(node_path_1.default.dirname(inheritPath), inheritYml.INHERIT) : undefined; } } return mkDocsYml; }); //# sourceMappingURL=fs.js.map