UNPKG

nx

Version:

Smart, Fast and Extensible Build System

262 lines • 10.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.unparse = exports.isCacheableTask = exports.shouldStreamOutput = exports.getSerializedArgsForTask = exports.getPrintableCommandArgsForTask = exports.getCliPath = exports.calculateReverseDeps = exports.removeTasksFromTaskGraph = exports.getCustomHasher = exports.getExecutorForTask = exports.getExecutorNameForTask = exports.interpolate = exports.getOutputsForTargetAndConfiguration = exports.getOutputs = exports.getDependencyConfigs = exports.getCommandAsString = void 0; const flat_1 = require("flat"); const output_1 = require("../utils/output"); const project_graph_utils_1 = require("../utils/project-graph-utils"); const fs_1 = require("fs"); const path_1 = require("path"); const nx_plugin_1 = require("../utils/nx-plugin"); const package_manager_1 = require("../utils/package-manager"); const workspace_root_1 = require("../utils/workspace-root"); const fileutils_1 = require("nx/src/utils/fileutils"); const path_2 = require("nx/src/utils/path"); function getCommandAsString(task) { const execCommand = (0, package_manager_1.getPackageManagerCommand)().exec; const args = getPrintableCommandArgsForTask(task); return [execCommand, 'nx', ...args].join(' ').trim(); } exports.getCommandAsString = getCommandAsString; function getDependencyConfigs({ project, target }, defaultDependencyConfigs, projectGraph) { var _a, _b, _c, _d; // DependencyConfigs configured in workspace.json override configurations at the root. const dependencyConfigs = expandDependencyConfigSyntaxSugar((_d = (_c = (_b = (_a = projectGraph.nodes[project].data) === null || _a === void 0 ? void 0 : _a.targets[target]) === null || _b === void 0 ? void 0 : _b.dependsOn) !== null && _c !== void 0 ? _c : defaultDependencyConfigs[target]) !== null && _d !== void 0 ? _d : []); for (const dependencyConfig of dependencyConfigs) { if (dependencyConfig.projects !== 'dependencies' && dependencyConfig.projects !== 'self') { output_1.output.error({ title: `dependsOn is improperly configured for ${project}:${target}`, bodyLines: [ `dependsOn.projects is "${dependencyConfig.projects}" but should be "self" or "dependencies"`, ], }); process.exit(1); } } return dependencyConfigs; } exports.getDependencyConfigs = getDependencyConfigs; function expandDependencyConfigSyntaxSugar(deps) { return deps.map((d) => { if (typeof d === 'string') { if (d.startsWith('^')) { return { projects: 'dependencies', target: d.substring(1) }; } else { return { projects: 'self', target: d }; } } else { return d; } }); } function getOutputs(p, task) { return getOutputsForTargetAndConfiguration(task, p[task.target.project]); } exports.getOutputs = getOutputs; /** * Returns the list of outputs that will be cached. * @param task target + overrides * @param node ProjectGraphProjectNode object that the task runs against */ function getOutputsForTargetAndConfiguration(task, node) { var _a; const { target, configuration } = task.target; const targets = node.data.targets[target]; const options = Object.assign(Object.assign(Object.assign({}, targets.options), (_a = targets === null || targets === void 0 ? void 0 : targets.configurations) === null || _a === void 0 ? void 0 : _a[configuration]), task.overrides); if (targets === null || targets === void 0 ? void 0 : targets.outputs) { return targets.outputs .map((output) => { const interpolated = interpolate(output, { workspaceRoot: '', projectRoot: node.data.root, projectName: node.data.name, project: Object.assign(Object.assign({}, node.data), { name: node.data.name }), options, }); return (0, fileutils_1.isRelativePath)(interpolated) ? (0, path_2.joinPathFragments)(node.data.root, interpolated) : interpolated; }) .filter((output) => !!output); } // Keep backwards compatibility in case `outputs` doesn't exist if (options.outputPath) { return Array.isArray(options.outputPath) ? options.outputPath : [options.outputPath]; } else if (target === 'build' || target === 'prepare') { return [ `dist/${node.data.root}`, `${node.data.root}/dist`, `${node.data.root}/build`, `${node.data.root}/public`, ]; } else { return []; } } exports.getOutputsForTargetAndConfiguration = getOutputsForTargetAndConfiguration; function interpolate(template, data) { return template.replace(/{([\s\S]+?)}/g, (match) => { let value = data; let path = match.slice(1, -1).trim().split('.'); for (let idx = 0; idx < path.length; idx++) { if (!value[path[idx]]) { return; } value = value[path[idx]]; } return value; }); } exports.interpolate = interpolate; function getExecutorNameForTask(task, nxJson, projectGraph) { const project = projectGraph.nodes[task.target.project].data; const projectRoot = (0, path_1.join)(workspace_root_1.workspaceRoot, project.root); if ((0, fs_1.existsSync)((0, path_1.join)(projectRoot, 'package.json'))) { project.targets = (0, project_graph_utils_1.mergeNpmScriptsWithTargets)(projectRoot, project.targets); } project.targets = (0, nx_plugin_1.mergePluginTargetsWithNxTargets)(project.root, project.targets, (0, nx_plugin_1.loadNxPlugins)(nxJson.plugins)); if (!project.targets[task.target.target]) { throw new Error(`Cannot find configuration for task ${task.target.project}:${task.target.target}`); } return project.targets[task.target.target].executor; } exports.getExecutorNameForTask = getExecutorNameForTask; function getExecutorForTask(task, workspace, projectGraph, nxJson) { const executor = getExecutorNameForTask(task, nxJson, projectGraph); const [nodeModule, executorName] = executor.split(':'); return workspace.readExecutor(nodeModule, executorName); } exports.getExecutorForTask = getExecutorForTask; function getCustomHasher(task, workspace, nxJson, projectGraph) { const factory = getExecutorForTask(task, workspace, projectGraph, nxJson).hasherFactory; return factory ? factory() : null; } exports.getCustomHasher = getCustomHasher; function removeTasksFromTaskGraph(graph, ids) { const tasks = {}; const dependencies = {}; const removedSet = new Set(ids); for (let taskId of Object.keys(graph.tasks)) { if (!removedSet.has(taskId)) { tasks[taskId] = graph.tasks[taskId]; dependencies[taskId] = graph.dependencies[taskId].filter((depTaskId) => !removedSet.has(depTaskId)); } } return { tasks, dependencies: dependencies, roots: Object.keys(dependencies).filter((k) => dependencies[k].length === 0), }; } exports.removeTasksFromTaskGraph = removeTasksFromTaskGraph; function calculateReverseDeps(taskGraph) { const reverseTaskDeps = {}; Object.keys(taskGraph.tasks).forEach((t) => { reverseTaskDeps[t] = []; }); Object.keys(taskGraph.dependencies).forEach((taskId) => { taskGraph.dependencies[taskId].forEach((d) => { reverseTaskDeps[d].push(taskId); }); }); return reverseTaskDeps; } exports.calculateReverseDeps = calculateReverseDeps; function getCliPath() { return require.resolve(`../../bin/run-executor.js`); } exports.getCliPath = getCliPath; function getPrintableCommandArgsForTask(task) { const args = task.overrides['__overrides_unparsed__']; const target = task.target.target.includes(':') ? `"${task.target.target}"` : task.target.target; const config = task.target.configuration ? `:${task.target.configuration}` : ''; return ['run', `${task.target.project}:${target}${config}`, ...args]; } exports.getPrintableCommandArgsForTask = getPrintableCommandArgsForTask; function getSerializedArgsForTask(task, isVerbose) { const overrides = Object.assign({}, task.overrides); delete overrides['verbose']; return [ JSON.stringify({ targetDescription: task.target, overrides: overrides, isVerbose: isVerbose, }), ]; } exports.getSerializedArgsForTask = getSerializedArgsForTask; function shouldStreamOutput(task, initiatingProject, options) { if (process.env.NX_STREAM_OUTPUT === 'true') return true; if (longRunningTask(task)) return true; if (task.target.project === initiatingProject) return true; return false; } exports.shouldStreamOutput = shouldStreamOutput; function isCacheableTask(task, options) { const cacheable = options.cacheableOperations || options.cacheableTargets; return (cacheable && cacheable.indexOf(task.target.target) > -1 && !longRunningTask(task)); } exports.isCacheableTask = isCacheableTask; function longRunningTask(task) { const t = task.target.target; return ((!!task.overrides['watch'] && task.overrides['watch'] !== 'false') || t.endsWith(':watch') || t.endsWith('-watch') || t === 'serve' || t === 'dev' || t === 'start'); } // TODO: vsavkin remove when nx-cloud doesn't depend on it function unparse(options) { const unparsed = []; for (const key of Object.keys(options)) { const value = options[key]; unparseOption(key, value, unparsed); } return unparsed; } exports.unparse = unparse; function unparseOption(key, value, unparsed) { if (value === true) { unparsed.push(`--${key}`); } else if (value === false) { unparsed.push(`--no-${key}`); } else if (Array.isArray(value)) { value.forEach((item) => unparseOption(key, item, unparsed)); } else if (Object.prototype.toString.call(value) === '[object Object]') { const flattened = (0, flat_1.flatten)(value, { safe: true }); for (const flattenedKey in flattened) { unparseOption(`${key}.${flattenedKey}`, flattened[flattenedKey], unparsed); } } else if (typeof value === 'string' && stringShouldBeWrappedIntoQuotes(value)) { const sanitized = value.replace(/"/g, String.raw `\"`); unparsed.push(`--${key}="${sanitized}"`); } else if (value != null) { unparsed.push(`--${key}=${value}`); } } function stringShouldBeWrappedIntoQuotes(str) { return str.includes(' ') || str.includes('{') || str.includes('"'); } //# sourceMappingURL=utils.js.map