diff --git a/internal/linker/index.js b/internal/linker/index.js index c4d6a6f6..eded701d 100755 --- a/internal/linker/index.js +++ b/internal/linker/index.js @@ -1,524 +1,166 @@ -/* THIS FILE GENERATED FROM .ts; see BUILD.bazel */ /* clang-format off */"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; +"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.main = exports.reduceModules = void 0; +exports.tryCreateSymlink = exports.getProposedSymlinks = exports.inferRunfilesDirFromPath = void 0; const fs = require("fs"); const path = require("path"); -const { runfiles: _defaultRunfiles, _BAZEL_OUT_REGEX } = require('../runfiles/index.js'); +// Run Bazel with --define=VERBOSE_LOGS=1 to enable this logging const VERBOSE_LOGS = !!process.env['VERBOSE_LOGS']; -function log_verbose(...m) { - if (VERBOSE_LOGS) - console.error('[link_node_modules.js]', ...m); -} -function log_error(error) { - console.error('[link_node_modules.js] An error has been reported:', error, error.stack); -} -function mkdirp(p) { - return __awaiter(this, void 0, void 0, function* () { - if (p && !(yield exists(p))) { - yield mkdirp(path.dirname(p)); - log_verbose(`creating directory ${p} in ${process.cwd()}`); - try { - yield fs.promises.mkdir(p); - } - catch (e) { - if (e.code !== 'EEXIST') { - throw e; - } - } - } - }); -} -function gracefulLstat(path) { - return __awaiter(this, void 0, void 0, function* () { - try { - return yield fs.promises.lstat(path); - } - catch (e) { - if (e.code === 'ENOENT') { - return null; - } - throw e; - } - }); -} -function gracefulReadlink(path) { - try { - return fs.readlinkSync(path); - } - catch (e) { - if (e.code === 'ENOENT') { - return null; - } - throw e; +function log(...m) { + if (VERBOSE_LOGS) { + console.error(loggingPrefix, ...m); } } -function gracefulReaddir(path) { - return __awaiter(this, void 0, void 0, function* () { - try { - return yield fs.promises.readdir(path); - } - catch (e) { - if (e.code === 'ENOENT') { - return []; - } - throw e; - } - }); -} -function unlink(moduleName) { - return __awaiter(this, void 0, void 0, function* () { - const stat = yield gracefulLstat(moduleName); - if (stat === null) { - return; - } - log_verbose(`unlink( ${moduleName} )`); - if (stat.isDirectory()) { - yield deleteDirectory(moduleName); - } - else { - log_verbose("Deleting file: ", moduleName); - yield fs.promises.unlink(moduleName); - } - }); -} -function deleteDirectory(p) { - return __awaiter(this, void 0, void 0, function* () { - log_verbose("Deleting children of", p); - for (let entry of yield gracefulReaddir(p)) { - const childPath = path.join(p, entry); - const stat = yield gracefulLstat(childPath); - if (stat === null) { - log_verbose(`File does not exist, but is listed as directory entry: ${childPath}`); - continue; - } - if (stat.isDirectory()) { - yield deleteDirectory(childPath); - } - else { - log_verbose("Deleting file", childPath); - yield fs.promises.unlink(childPath); - } - } - log_verbose("Cleaning up dir", p); - yield fs.promises.rmdir(p); - }); -} -function symlink(target, p) { - return __awaiter(this, void 0, void 0, function* () { - if (!path.isAbsolute(target)) { - target = path.resolve(process.cwd(), target); - } - log_verbose(`creating symlink ${p} -> ${target}`); - try { - yield fs.promises.symlink(target, p, 'junction'); - return true; - } - catch (e) { - if (e.code !== 'EEXIST') { - throw e; - } - if (VERBOSE_LOGS) { - if (!(yield exists(p))) { - log_verbose('ERROR\n***\nLooks like we created a bad symlink:' + - `\n pwd ${process.cwd()}\n target ${target}\n path ${p}\n***`); - } - } - return false; - } - }); -} -function resolveWorkspaceNodeModules(workspace, startCwd, isExecroot, execroot, runfiles) { - return __awaiter(this, void 0, void 0, function* () { - const targetManifestPath = `${workspace}/node_modules`; - if (isExecroot) { - return `${execroot}/external/${targetManifestPath}`; - } - if (!execroot) { - return path.resolve(`${startCwd}/../${targetManifestPath}`); - } - const fromManifest = runfiles.lookupDirectory(targetManifestPath); - if (fromManifest) { - return fromManifest; - } - else { - const maybe = path.resolve(`${execroot}/external/${targetManifestPath}`); - if (yield exists(maybe)) { - return maybe; - } - return path.resolve(`${startCwd}/../${targetManifestPath}`); - } - }); -} -function exists(p) { - return __awaiter(this, void 0, void 0, function* () { - return ((yield gracefulLstat(p)) !== null); - }); -} -function existsSync(p) { - if (!p) { - return false; +function fatal(context, errors) { + console.error(loggingPrefix, 'Error(s) were reported.'); + console.error(loggingPrefix, 'Context:', context); + for (const error of errors) { + console.error(error); } - try { - fs.lstatSync(p); - return true; + console.error(loggingPrefix, 'Exiting'); + process.exit(1); +} +// NOTE Trailing '/' not included in matcher to cover all scenarios (e.g. RUNFILES_DIR environment variable) +const runfilesPathMatcher = '.runfiles'; +const nodeModulesDir = 'node_modules'; +const loggingPrefix = '[node_modules-linker]'; +/** + * Infers a runfiles directory from the given path, throwing on failure. + * @param maybeRunfilesSource Path to inspect. + */ +function inferRunfilesDirFromPath(maybeRunfilesSource) { + while (maybeRunfilesSource !== '/') { + if (maybeRunfilesSource.endsWith(runfilesPathMatcher)) { + return maybeRunfilesSource + '/'; + } + maybeRunfilesSource = path.dirname(maybeRunfilesSource); } - catch (e) { - if (e.code === 'ENOENT') { - return false; - } - throw e; - } -} -function reduceModules(modules) { - return buildModuleHierarchy(Object.keys(modules).sort(), modules, '/').children || []; -} -exports.reduceModules = reduceModules; -function buildModuleHierarchy(moduleNames, modules, elementPath) { - let element = { - name: elementPath.slice(0, -1), - link: modules[elementPath.slice(0, -1)], - children: [], - }; - for (let i = 0; i < moduleNames.length;) { - const moduleName = moduleNames[i]; - const next = moduleName.indexOf('/', elementPath.length + 1); - const moduleGroup = (next === -1) ? (moduleName + '/') : moduleName.slice(0, next + 1); - if (next === -1) { - i++; - } - const siblings = []; - while (i < moduleNames.length && moduleNames[i].startsWith(moduleGroup)) { - siblings.push(moduleNames[i++]); - } - let childElement = buildModuleHierarchy(siblings, modules, moduleGroup); - for (let cur = childElement; (cur = liftElement(childElement)) !== childElement;) { - childElement = cur; - } - element.children.push(childElement); + throw new Error('Path does not contain a runfiles parent directory.'); +} +exports.inferRunfilesDirFromPath = inferRunfilesDirFromPath; +/** + * Gets the symlinks required to satisfy `node_modules` linking requirements. + * @param modulesManifest Modules manifest to read `node_modules` roots from. + * @param runfilesDirPath Runfiles directory symlinks should operate within. + */ +function getProposedSymlinks(modulesManifest, runfilesDirPath) { + const symlinks = []; + let relativeMountParent; + for (relativeMountParent in modulesManifest.roots) { + const repositoryName = modulesManifest.roots[relativeMountParent]; + const filePath = path.join(runfilesDirPath, modulesManifest.workspace, relativeMountParent, nodeModulesDir); + const targetPath = path.join(runfilesDirPath, repositoryName, nodeModulesDir); + symlinks.push([filePath, targetPath]); } - if (!element.link) { - delete element.link; + return symlinks; +} +exports.getProposedSymlinks = getProposedSymlinks; +/** + * @todo Replace with `error.cause` once on NodeJS >=16.9 + */ +function ensureErrorInstance(err) { + return err instanceof Error + ? err + : new Error(`Non-error thrown, value was "${err ?? 'NULL_OR_UNDEFINED'}"`); +} +function tryRun(func) { + try { + return func(); } - if (!element.children || element.children.length === 0) { - delete element.children; + catch (err) { + return ensureErrorInstance(err); } - return element; } -function liftElement(element) { - let { name, link, children } = element; - if (!children || !children.length) { - return element; +function definedOrThrow(value, throwReason) { + if (value == null) { + throw new Error(throwReason); } - if (link && allElementsAlignUnder(name, link, children)) { - return { name, link }; + return value; +} +/** + * Creates symlink using a "try-else-check" approach to safeguard against concurrent creation. + * On failure the (assumed to exist) symlink is inspected, an error is thrown if the target path + * differs. + */ +function tryCreateSymlink(filePath, targetPath) { + log(`attempting to create symlink "${filePath}" -> "${targetPath}"`); + // Ensure parent directories exist, e.g. for @renderer_node_modules//rollup/bin:rollup + fs.mkdirSync(path.join(filePath, '..'), { recursive: true }); + const symlinkResult = tryRun(() => fs.symlinkSync(targetPath, filePath)); + if (symlinkResult instanceof Error) { + // Attempt failed, link likely already exists + const readlinkResult = tryRun(() => fs.readlinkSync(filePath)); + if (readlinkResult instanceof Error) { + // Very bad state, time to abort + fatal('symlink creation', [symlinkResult, readlinkResult]); + } + // Ensure symlink target matches requirements, or bail + if (readlinkResult !== targetPath) { + throw new Error(`Invalid symlink target path "${readlinkResult}" detected, wanted "${targetPath}" for symlink at "${filePath}"`); + } + log('symlink already exists'); } - return element; -} -function allElementsAlignUnder(parentName, parentLink, elements) { - for (const { name, link, children } of elements) { - if (!link || children) { - return false; - } - if (!isDirectChildPath(parentName, name)) { - return false; - } - if (!isDirectChildLink(parentLink, link)) { - return false; - } - if (!isNameLinkPathTopAligned(name, link)) { - return false; - } - } - return true; -} -function isDirectChildPath(parent, child) { - return parent === path.dirname(child); -} -function isDirectChildLink(parentLink, childLink) { - return parentLink === path.dirname(childLink); } -function isNameLinkPathTopAligned(namePath, linkPath) { - return path.basename(namePath) === path.basename(linkPath); -} -function visitDirectoryPreserveLinks(dirPath, visit) { - return __awaiter(this, void 0, void 0, function* () { - for (const entry of yield fs.promises.readdir(dirPath)) { - const childPath = path.join(dirPath, entry); - const stat = yield gracefulLstat(childPath); - if (stat === null) { - continue; - } - if (stat.isDirectory()) { - yield visitDirectoryPreserveLinks(childPath, visit); - } - else { - yield visit(childPath, stat); - } - } +exports.tryCreateSymlink = tryCreateSymlink; +const removeNulls = (value) => value != null; +function main() { + log('Linking started'); + // Collect potential runfiles dir sources + // Sometimes cwd is under runfiles + const cwd = process.cwd(); + log('cwd:', cwd); + // Runfiles environment variables are the preferred reference point, but can fail + log('RUNFILES_DIR environment variable:', process.env.RUNFILES_DIR ?? '(unset)'); + log('RUNFILES environment variable:', process.env.RUNFILES ?? '(unset)'); + const envRunfilesCanidates = [ + process.env.RUNFILES_DIR, + process.env.RUNFILES, + ].filter(removeNulls).map(runfilesDir => { + const adjustedRunfilesDir = fs.realpathSync(runfilesDir); + if (runfilesDir !== adjustedRunfilesDir) { + log(`Symlink dereferenced from runfiles path. Was "${runfilesDir}" now "${adjustedRunfilesDir}"`); + return adjustedRunfilesDir; + } + return runfilesDir; }); -} -function findExecroot(startCwd) { - if (existsSync(`${startCwd}/bazel-out`)) { - return startCwd; - } - const bazelOutMatch = startCwd.match(_BAZEL_OUT_REGEX); - return bazelOutMatch ? startCwd.slice(0, bazelOutMatch.index) : undefined; -} -function main(args, runfiles) { - return __awaiter(this, void 0, void 0, function* () { - if (!args || args.length < 1) - throw new Error('requires one argument: modulesManifest path'); - const [modulesManifest] = args; - log_verbose('manifest file:', modulesManifest); - let { workspace, bin, roots, module_sets } = JSON.parse(fs.readFileSync(modulesManifest)); - log_verbose('manifest contents:', JSON.stringify({ workspace, bin, roots, module_sets }, null, 2)); - roots = roots || {}; - module_sets = module_sets || {}; - const startCwd = process.cwd().replace(/\\/g, '/'); - log_verbose('startCwd:', startCwd); - const execroot = findExecroot(startCwd); - log_verbose('execroot:', execroot ? execroot : 'not found'); - const isExecroot = startCwd == execroot; - log_verbose('isExecroot:', isExecroot.toString()); - if (!isExecroot && execroot) { - process.chdir(execroot); - log_verbose('changed directory to execroot', execroot); - } - function symlinkWithUnlink(target, p, stats = null) { - return __awaiter(this, void 0, void 0, function* () { - if (!path.isAbsolute(target)) { - target = path.resolve(process.cwd(), target); - } - if (stats === null) { - stats = yield gracefulLstat(p); - } - if (runfiles.manifest && execroot && stats !== null && stats.isSymbolicLink()) { - const symlinkPathRaw = gracefulReadlink(p); - if (symlinkPathRaw !== null) { - const symlinkPath = symlinkPathRaw.replace(/\\/g, '/'); - if (path.relative(symlinkPath, target) != '' && - !path.relative(execroot, symlinkPath).startsWith('..')) { - log_verbose(`Out-of-date symlink for ${p} to ${symlinkPath} detected. Target should be ${target}. Unlinking.`); - yield unlink(p); - } - else { - log_verbose(`The symlink at ${p} no longer exists, so no need to unlink it.`); - } - } - } - return symlink(target, p); - }); - } - for (const packagePath of Object.keys(roots)) { - const workspace = roots[packagePath]; - if (workspace) { - const workspaceNodeModules = yield resolveWorkspaceNodeModules(workspace, startCwd, isExecroot, execroot, runfiles); - log_verbose(`resolved ${workspace} workspace node modules path to ${workspaceNodeModules}`); - if (packagePath) { - if (yield exists(workspaceNodeModules)) { - yield mkdirp(packagePath); - yield symlinkWithUnlink(workspaceNodeModules, `${packagePath}/node_modules`); - if (!isExecroot) { - const runfilesPackagePath = `${startCwd}/${packagePath}`; - if (yield exists(runfilesPackagePath)) { - yield symlinkWithUnlink(`${packagePath}/node_modules`, `${runfilesPackagePath}/node_modules`); - } - } - const packagePathBin = `${bin}/${packagePath}`; - if (yield exists(packagePathBin)) { - yield symlinkWithUnlink(`${packagePath}/node_modules`, `${packagePathBin}/node_modules`); - } - } - else { - log_verbose(`no npm workspace node_modules folder under ${packagePath} to link to; creating node_modules directories in ${process.cwd()} for ${packagePath} 1p deps`); - yield mkdirp(`${packagePath}/node_modules`); - if (!isExecroot) { - const runfilesPackagePath = `${startCwd}/${packagePath}`; - yield mkdirp(`${runfilesPackagePath}/node_modules`); - yield symlinkWithUnlink(`${packagePath}/node_modules`, `${runfilesPackagePath}/node_modules`); - } - const packagePathBin = `${bin}/${packagePath}`; - yield mkdirp(`${packagePathBin}/node_modules`); - yield symlinkWithUnlink(`${packagePath}/node_modules`, `${packagePathBin}/node_modules`); - } - } - else { - if (yield exists(workspaceNodeModules)) { - yield symlinkWithUnlink(workspaceNodeModules, `node_modules`); - } - else { - log_verbose(`no root npm workspace node_modules folder to link to; creating node_modules directory in ${process.cwd()}`); - yield mkdirp('node_modules'); - } - } + // Infer runfiles dir + const runfilesDirPath = (() => { + for (const maybeRunfilesSource of [...envRunfilesCanidates, cwd]) { + try { + log(`Attempting to infer runfiles directory from "${maybeRunfilesSource}"`); + return inferRunfilesDirFromPath(maybeRunfilesSource); } - else { - if (packagePath) { - log_verbose(`no 3p deps at ${packagePath}; creating node_modules directories in ${process.cwd()} for ${packagePath} 1p deps`); - yield mkdirp(`${packagePath}/node_modules`); - if (!isExecroot) { - const runfilesPackagePath = `${startCwd}/${packagePath}`; - yield mkdirp(`${runfilesPackagePath}/node_modules`); - yield symlinkWithUnlink(`${packagePath}/node_modules`, `${runfilesPackagePath}/node_modules`); - } - const packagePathBin = `${bin}/${packagePath}`; - yield mkdirp(`${packagePathBin}/node_modules`); - yield symlinkWithUnlink(`${packagePath}/node_modules`, `${packagePathBin}/node_modules`); - } - else { - log_verbose(`no 3p deps at root; creating node_modules directory in ${process.cwd()} for root 1p deps`); - yield mkdirp('node_modules'); - } + catch (err) { + log(`Could not resolve runfiles directory from "${maybeRunfilesSource}"`, ensureErrorInstance(err).message); } } - function isLeftoverDirectoryFromLinker(stats, modulePath) { - return __awaiter(this, void 0, void 0, function* () { - if (runfiles.manifest === undefined) { - return false; - } - if (!stats.isDirectory()) { - return false; - } - let isLeftoverFromPreviousLink = true; - yield visitDirectoryPreserveLinks(modulePath, (childPath, childStats) => __awaiter(this, void 0, void 0, function* () { - if (!childStats.isSymbolicLink()) { - isLeftoverFromPreviousLink = false; - } - })); - return isLeftoverFromPreviousLink; - }); - } - function createSymlinkAndPreserveContents(stats, modulePath, target) { - return __awaiter(this, void 0, void 0, function* () { - const tmpPath = `${modulePath}__linker_tmp`; - log_verbose(`createSymlinkAndPreserveContents( ${modulePath} )`); - yield symlink(target, tmpPath); - yield visitDirectoryPreserveLinks(modulePath, (childPath, stat) => __awaiter(this, void 0, void 0, function* () { - if (stat.isSymbolicLink()) { - const targetPath = path.join(tmpPath, path.relative(modulePath, childPath)); - log_verbose(`Cloning symlink into temporary created link ( ${childPath} )`); - yield mkdirp(path.dirname(targetPath)); - yield symlink(targetPath, yield fs.promises.realpath(childPath)); - } - })); - log_verbose(`Removing existing module so that new link can take place ( ${modulePath} )`); - yield unlink(modulePath); - yield fs.promises.rename(tmpPath, modulePath); - }); - } - function linkModules(package_path, m) { - return __awaiter(this, void 0, void 0, function* () { - const symlinkIn = package_path ? `${package_path}/node_modules` : 'node_modules'; - if (path.dirname(m.name)) { - yield mkdirp(`${symlinkIn}/${path.dirname(m.name)}`); - } - if (m.link) { - const modulePath = m.link; - let target; - if (isExecroot) { - target = `${startCwd}/${modulePath}`; - } - if (!isExecroot || !existsSync(target)) { - let runfilesPath = modulePath; - if (runfilesPath.startsWith(`${bin}/`)) { - runfilesPath = runfilesPath.slice(bin.length + 1); - } - else if (runfilesPath === bin) { - runfilesPath = ''; - } - const externalPrefix = 'external/'; - if (runfilesPath.startsWith(externalPrefix)) { - runfilesPath = runfilesPath.slice(externalPrefix.length); - } - else { - runfilesPath = `${workspace}/${runfilesPath}`; - } - try { - target = runfiles.resolve(runfilesPath); - if (runfiles.manifest && modulePath.startsWith(`${bin}/`)) { - if (!target.match(_BAZEL_OUT_REGEX)) { - const e = new Error(`could not resolve module ${runfilesPath} in output tree`); - e.code = 'MODULE_NOT_FOUND'; - throw e; - } - } - } - catch (err) { - target = undefined; - log_verbose(`runfiles resolve failed for module '${m.name}': ${err.message}`); - } - } - if (target && !path.isAbsolute(target)) { - target = path.resolve(process.cwd(), target); - } - const symlinkFile = `${symlinkIn}/${m.name}`; - const stats = yield gracefulLstat(symlinkFile); - const isLeftOver = (stats !== null && (yield isLeftoverDirectoryFromLinker(stats, symlinkFile))); - if (target && (yield exists(target))) { - if (stats !== null && isLeftOver) { - yield createSymlinkAndPreserveContents(stats, symlinkFile, target); - } - else { - yield symlinkWithUnlink(target, symlinkFile, stats); - } - } - else { - if (!target) { - log_verbose(`no symlink target found for module ${m.name}`); - } - else { - log_verbose(`potential target ${target} does not exists for module ${m.name}`); - } - if (isLeftOver) { - yield unlink(symlinkFile); - } - } - } - if (m.children) { - yield Promise.all(m.children.map(m => linkModules(package_path, m))); - } - }); - } - const links = []; - for (const package_path of Object.keys(module_sets)) { - const modules = module_sets[package_path]; - log_verbose(`modules for package path '${package_path}':\n${JSON.stringify(modules, null, 2)}`); - const moduleHierarchy = reduceModules(modules); - log_verbose(`mapping hierarchy for package path '${package_path}':\n${JSON.stringify(moduleHierarchy)}`); - links.push(...moduleHierarchy.map(m => linkModules(package_path, m))); - } - let code = 0; - yield Promise.all(links).catch(e => { - log_error(e); - code = 1; - }); - return code; - }); + throw new Error('Could not resolve runfiles directory from any data sources.'); + })(); + log('Resolved runfiles path:', runfilesDirPath); + // Get required links from modules manifest + const modulesManifestPath = definedOrThrow(process.argv[2], 'argv[2] is required to locate modules manifest but is missing.'); + log('Modules manifest path:', modulesManifestPath); + const modulesManifestContent = fs.readFileSync(modulesManifestPath, 'utf-8'); + const modulesManifest = JSON.parse(modulesManifestContent); + log('Modules manifest contents:', JSON.stringify(modulesManifest, null, 2)); + // Create links + log('Inferring symlink paths...'); + const symlinks = getProposedSymlinks(modulesManifest, runfilesDirPath); + for (const [filePath, targetPath] of symlinks) { + tryCreateSymlink(filePath, targetPath); + } + // RBE HACK Advertise links + log('Saving symlink paths...'); + if (!process.env.NM_SYMLINKS) { + throw new Error(); + } + fs.writeFileSync(process.env.NM_SYMLINKS, JSON.stringify(symlinks), 'utf-8'); + log('Linking finished'); } -exports.main = main; if (require.main === module) { - if (Number(process.versions.node.split('.')[0]) < 10) { - console.error(`ERROR: rules_nodejs linker requires Node v10 or greater, but is running on ${process.versions.node}`); - console.error('Note that earlier Node versions are no longer in long-term-support, see'); - console.error('https://nodejs.org/en/about/releases/'); - process.exit(1); + try { + main(); + } + catch (err) { + fatal('unhandled exception', [ensureErrorInstance(err)]); } - (() => __awaiter(void 0, void 0, void 0, function* () { - try { - process.exitCode = yield main(process.argv.slice(2), _defaultRunfiles); - } - catch (e) { - log_error(e); - process.exitCode = 1; - } - }))(); } diff --git a/internal/linker/link_node_modules.bzl b/internal/linker/link_node_modules.bzl index 5d30429c..ea04f182 100755 --- a/internal/linker/link_node_modules.bzl +++ b/internal/linker/link_node_modules.bzl @@ -101,24 +101,6 @@ def write_node_modules_manifest(ctx, extra_data = [], mnemonic = None, link_work _debug(ctx.var, "Linking %s: %s" % (k, v)) mappings[k] = v - # Convert mappings to a module sets (modules per package package_path) - # { - # "package_path": { - # "package_name": "source_path", - # ... - # }, - # ... - # } - module_sets = {} - for k, v in mappings.items(): - map_key_split = k.split(":") - package_name = map_key_split[0] - package_path = map_key_split[1] if len(map_key_split) > 1 else "" - source_path = v[1] - if package_path not in module_sets: - module_sets[package_path] = {} - module_sets[package_path][package_name] = source_path - # Write the result to a file, and use the magic node option --bazel_node_modules_manifest # The launcher.sh will peel off this argument and pass it to the linker rather than the program. prefix = ctx.label.name @@ -126,8 +108,6 @@ def write_node_modules_manifest(ctx, extra_data = [], mnemonic = None, link_work prefix += "_%s" % mnemonic modules_manifest = ctx.actions.declare_file("_%s.module_mappings.json" % prefix) content = { - "bin": ctx.bin_dir.path, - "module_sets": module_sets, "roots": node_modules_roots, "workspace": ctx.workspace_name, } diff --git a/internal/node/node.bzl b/internal/node/node.bzl index a2dd51dc..0f638a77 100755 --- a/internal/node/node.bzl +++ b/internal/node/node.bzl @@ -196,6 +196,7 @@ def _nodejs_binary_impl(ctx): # Provide the target name as an environment variable avaiable to all actions for the # runfiles helpers to use. env_vars = "export BAZEL_TARGET=%s\n" % ctx.label + env_vars += """export NM_SYMLINKS="$(mktemp -d)/nm-symlinks.json"\n""" # Add all env vars from the ctx attr for [key, value] in ctx.attr.env.items():