Skip to content

Commit

Permalink
fix: simplify portion of linker and fix case where runfiles node_modu…
Browse files Browse the repository at this point in the history
…les symlinks are missing under bazel run
  • Loading branch information
gregmagolan authored and alexeagle committed Oct 26, 2021
1 parent ac5502c commit 8c1f26c
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 139 deletions.
82 changes: 28 additions & 54 deletions internal/linker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,63 +320,37 @@ function main(args, runfiles) {
}
for (const packagePath of Object.keys(roots)) {
const workspace = roots[packagePath];
if (workspace) {
const workspaceNodeModules = yield resolveWorkspaceNodeModules(workspace, startCwd, isExecroot, execroot, runfiles);
let workspaceNodeModules = yield resolveWorkspaceNodeModules(workspace, startCwd, isExecroot, execroot, runfiles);
if (yield exists(workspaceNodeModules)) {
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');
}
}
}
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');
workspaceNodeModules = undefined;
}
if (packagePath) {
yield mkdirp(packagePath);
}
const execrootNodeModules = path.posix.join(packagePath, `node_modules`);
if (workspaceNodeModules) {
yield symlinkWithUnlink(workspaceNodeModules, execrootNodeModules);
}
else {
yield mkdirp(execrootNodeModules);
}
const packagePathBin = path.posix.join(bin, packagePath);
yield mkdirp(`${packagePathBin}`);
yield symlinkWithUnlink(execrootNodeModules, `${packagePathBin}/node_modules`);
if (!isExecroot) {
const runfilesPackagePath = path.posix.join(startCwd, packagePath);
yield mkdirp(`${runfilesPackagePath}`);
yield symlinkWithUnlink(execrootNodeModules, `${runfilesPackagePath}/node_modules`);
}
if (process.env['RUNFILES']) {
const stat = yield gracefulLstat(process.env['RUNFILES']);
if (stat && stat.isDirectory()) {
const runfilesPackagePath = path.posix.join(process.env['RUNFILES'], packagePath);
yield mkdirp(`${runfilesPackagePath}`);
yield symlinkWithUnlink(execrootNodeModules, `${runfilesPackagePath}/node_modules`);
}
}
}
Expand Down
131 changes: 46 additions & 85 deletions internal/linker/link_node_modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,94 +472,55 @@ export async function main(args: string[], runfiles: Runfiles) {
// lined to node_modules folders at the root or in sub-directories
for (const packagePath of Object.keys(roots)) {
const workspace = roots[packagePath];
if (workspace) {
const workspaceNodeModules = await resolveWorkspaceNodeModules(
workspace, startCwd, isExecroot, execroot, runfiles);
let workspaceNodeModules: string | undefined = await resolveWorkspaceNodeModules(
workspace, startCwd, isExecroot, execroot, runfiles);
if (await exists(workspaceNodeModules)) {
log_verbose(`resolved ${workspace} workspace node modules path to ${workspaceNodeModules}`);
} else {
// There are no third party node_modules to symlink to
workspaceNodeModules = undefined;
}

if (packagePath) {
// sub-directory node_modules
if (await exists(workspaceNodeModules)) {
// in some cases packagePath may not exist in sandbox if there are no source deps
// and only generated file deps. we create it so that we that we can link to
// packagePath/node_modules since packagePathBin/node_modules is a symlink to
// packagePath/node_modules and is unguarded in launcher.sh as we allow symlinks to fall
// through to from output tree to source tree to prevent resolving the same npm package to
// multiple locations on disk
await mkdirp(packagePath);
await symlinkWithUnlink(workspaceNodeModules, `${packagePath}/node_modules`);
if (!isExecroot) {
// Under runfiles, we symlink into the package in runfiles as well.
// When inside the sandbox, the execroot location will not exist to symlink to.
const runfilesPackagePath = `${startCwd}/${packagePath}`;
if (await exists(runfilesPackagePath)) {
await symlinkWithUnlink(
`${packagePath}/node_modules`, `${runfilesPackagePath}/node_modules`);
}
}
const packagePathBin = `${bin}/${packagePath}`;
if (await exists(packagePathBin)) {
// if bin path exists, symlink bin/package/node_modules -> package/node_modules
// NB: this location is unguarded in launcher.sh to allow symlinks to fall-throught
// package/node_modules to prevent resolving the same npm package to multiple locations
// on disk
await symlinkWithUnlink(
`${packagePath}/node_modules`, `${packagePathBin}/node_modules`);
}
} else {
// Special case if there no target to symlink to for the root workspace, create a
// root node_modules folder for 1st party deps
log_verbose(`no npm workspace node_modules folder under ${
packagePath} to link to; creating node_modules directories in ${process.cwd()} for ${
packagePath} 1p deps`);
await mkdirp(`${packagePath}/node_modules`);
if (!isExecroot) {
// Under runfiles, we symlink into the package in runfiles as well.
// When inside the sandbox, the execroot location will not exist to symlink to.
const runfilesPackagePath = `${startCwd}/${packagePath}`;
await mkdirp(`${runfilesPackagePath}/node_modules`);
await symlinkWithUnlink(
`${packagePath}/node_modules`, `${runfilesPackagePath}/node_modules`);
}
const packagePathBin = `${bin}/${packagePath}`;
await mkdirp(`${packagePathBin}/node_modules`);
await symlinkWithUnlink(`${packagePath}/node_modules`, `${packagePathBin}/node_modules`);
}
} else {
// root node_modules
if (await exists(workspaceNodeModules)) {
await symlinkWithUnlink(workspaceNodeModules, `node_modules`);
} else {
// Special case if there no target to symlink to for the root workspace, create a
// root node_modules folder for 1st party deps
log_verbose(
`no root npm workspace node_modules folder to link to; creating node_modules directory in ${
process.cwd()}`);
await mkdirp('node_modules');
}
}
if (packagePath) {
// In some cases packagePath may not exist in sandbox if there are no source deps
// and only generated file deps. we create it so that we that we can link to
// packagePath/node_modules since packagePathBin/node_modules is a symlink to
// packagePath/node_modules and is unguarded in launcher.sh as we allow symlinks to fall
// through to from output tree to source tree to prevent resolving the same npm package to
// multiple locations on disk
await mkdirp(packagePath);
}

// There are third party modules at this package path
const execrootNodeModules = path.posix.join(packagePath, `node_modules`);

if (workspaceNodeModules) {
// Execroot symlink -> external workspace node_modules
await symlinkWithUnlink(workspaceNodeModules, execrootNodeModules);
} else {
if (packagePath) {
// Special case if there for first party node_modules at root only
log_verbose(`no 3p deps at ${packagePath}; creating node_modules directories in ${
process.cwd()} for ${packagePath} 1p deps`);
await mkdirp(`${packagePath}/node_modules`);
if (!isExecroot) {
// Under runfiles, we symlink into the package in runfiles as well.
// When inside the sandbox, the execroot location will not exist to symlink to.
const runfilesPackagePath = `${startCwd}/${packagePath}`;
await mkdirp(`${runfilesPackagePath}/node_modules`);
await symlinkWithUnlink(
`${packagePath}/node_modules`, `${runfilesPackagePath}/node_modules`);
}
const packagePathBin = `${bin}/${packagePath}`;
await mkdirp(`${packagePathBin}/node_modules`);
await symlinkWithUnlink(`${packagePath}/node_modules`, `${packagePathBin}/node_modules`);
} else {
// Special case if there for first party node_modules at root only
log_verbose(`no 3p deps at root; creating node_modules directory in ${
process.cwd()} for root 1p deps`);
await mkdirp('node_modules');
// Create an execroot node_modules directory since there are no third party node_modules to symlink to
await mkdirp(execrootNodeModules);
}

// Bin symlink -> execroot node_modules
const packagePathBin = path.posix.join(bin, packagePath);
await mkdirp(`${packagePathBin}`);
await symlinkWithUnlink(execrootNodeModules, `${packagePathBin}/node_modules`);

// Start CWD symlink -> execroot node_modules
if (!isExecroot) {
const runfilesPackagePath = path.posix.join(startCwd, packagePath);
await mkdirp(`${runfilesPackagePath}`);
await symlinkWithUnlink(execrootNodeModules, `${runfilesPackagePath}/node_modules`);
}

// RUNFILES symlink -> execroot node_modules
if (process.env['RUNFILES']) {
const stat = await gracefulLstat(process.env['RUNFILES']);
if (stat && stat.isDirectory()) {
const runfilesPackagePath = path.posix.join(process.env['RUNFILES'], packagePath);
await mkdirp(`${runfilesPackagePath}`);
await symlinkWithUnlink(execrootNodeModules, `${runfilesPackagePath}/node_modules`);
}
}
}
Expand Down

0 comments on commit 8c1f26c

Please sign in to comment.