UNPKG

npm-link-up

Version:

Use this package to link your projects together for local development.

152 lines (151 loc) 5.66 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); const fs = require("fs"); const logging_1 = require("../../logging"); const chalk_1 = require("chalk"); const cmd_line_opts_1 = require("../run/cmd-line-opts"); const dashdash = require('dashdash'); const async = require("async"); const utils_1 = require("../../utils"); const treeify = require('treeify'); const allowUnknown = process.argv.indexOf('--allow-unknown') > 0; let opts, globalConf, parser = dashdash.createParser({ options: cmd_line_opts_1.default, allowUnknown }); try { opts = parser.parse(process.argv); } catch (e) { logging_1.default.error(chalk_1.default.magenta('CLI parsing error:'), chalk_1.default.magentaBright.bold(e.message)); process.exit(1); } if (opts.help) { let help = parser.help({ includeEnv: true }).trimRight(); console.log('usage: nlu run [OPTIONS]\n' + 'options:\n' + help); process.exit(0); } const cwd = process.cwd(); let { nluFilePath } = utils_1.handleConfigCLIOpt(cwd, opts); const searchRoot = process.cwd(); logging_1.default.info('Searching for symlinked packages in this directory:', searchRoot, '\n'); const queue = async.queue((task, cb) => task(cb), 8); let key = `${path.basename(searchRoot)} (root)`; const treeObj = { [key]: {} }; const ignore = new Set(['.git', '.idea', '.r2g', 'dist', 'build', '.vscode']); const searchDir = (dir, node, cb) => { const handleSymbolicLink = (itemPath, name, cb) => { fs.stat(itemPath, (err, stats) => { if (err) { logging_1.default.warning(err); return cb(null); } if (!stats.isDirectory()) { logging_1.default.warning('Symbolic link in node_modules points to a non-directory:', itemPath); return cb(null); } fs.realpath(itemPath, (err, p) => { if (err) { logging_1.default.warning(err); return cb(null); } node[name] = chalk_1.default.bold('❖ ') + chalk_1.default.underline(p) + ' '; cb(null); }); }); }; const handleOrg = (orgDir, orgName, cb) => { fs.readdir(orgDir, (err, items) => { if (err) { logging_1.default.warning(err.message); return cb(null); } async.eachLimit(items, 8, (v, cb) => { const pth = path.resolve(orgDir, v); fs.lstat(pth, (err, stats) => { if (err) { logging_1.default.warning(err.message); return cb(null); } if (stats.isSymbolicLink()) { return handleSymbolicLink(pth, orgName + '/' + v, cb); } cb(null); }); }, cb); }); }; queue.push(callback => { fs.readdir(dir, (err, items) => { callback(null); if (err) { logging_1.default.warning(err.message); return cb(null); } const searchable = items.filter(v => !ignore.has(v)); async.eachLimit(searchable, 8, (v, cb) => { const itemPath = path.resolve(dir + '/' + v); const parentDir = path.basename(path.dirname(itemPath)); const nodeModulesIsParent = parentDir === 'node_modules'; fs.lstat(itemPath, (err, stats) => { if (err) { logging_1.default.warning(err.message); return cb(null); } if (stats.isFile()) { return cb(null); } if (nodeModulesIsParent) { if (stats.isSymbolicLink()) { return handleSymbolicLink(itemPath, v, cb); } if (stats.isDirectory() && v.startsWith('@')) { return handleOrg(itemPath, v, cb); } return cb(null); } if (stats.isDirectory()) { return searchDir(itemPath, node[v] = {}, cb); } delete node[v]; cb(null); }); }, cb); }); }); }; const cleanTree = (treeObj) => { (function recurse(node, parent, key, hasNodeModules, list) { if (hasNodeModules) { for (let v of list) { v.hasNodeModules = true; } } const children = Object.keys(node); const x = { hasNodeModules: false }; for (let v of children) { if (node[v] && typeof node[v] === 'object') { recurse(node[v], node, v, hasNodeModules || v === 'node_modules', list.concat(x)); } } if (x.hasNodeModules === false) { if (parent && key && key !== 'node_modules') { delete parent[key]; } } })(treeObj, null, null, false, []); }; searchDir(searchRoot, treeObj[key], err => { if (err) { throw err; } cleanTree(treeObj); const treeString = treeify.asTree(treeObj, true); const formattedStr = String(treeString).split('\n').map(function (line) { return '\t' + line; }); console.log(chalk_1.default.white(formattedStr.join('\n'))); process.exit(0); });