Add option to install binaries of dependencies
This commit is contained in:
@@ -133,6 +133,11 @@ Some additional settings are available in `.yarnrc.yml`:
|
|||||||
|
|
||||||
- `isolatedNixBuilds`, see [ISOLATED_BUILDS.md](./ISOLATED_BUILDS.md).
|
- `isolatedNixBuilds`, see [ISOLATED_BUILDS.md](./ISOLATED_BUILDS.md).
|
||||||
|
|
||||||
|
- `installNixBinariesForDependencies` can be set to also install executables
|
||||||
|
for binaries defined by dependencies. This can be useful if these need to be
|
||||||
|
in `$PATH` for other tools, or if you're creating a workspace just to collect
|
||||||
|
command-line tools.
|
||||||
|
|
||||||
[niv]: https://github.com/nmattia/niv
|
[niv]: https://github.com/nmattia/niv
|
||||||
|
|
||||||
## Hacking
|
## Hacking
|
||||||
|
|||||||
+57
-36
@@ -1,6 +1,7 @@
|
|||||||
import { Command, Option } from "clipanion";
|
import { Command, Option } from "clipanion";
|
||||||
import { Filename, npath, ppath, xfs } from "@yarnpkg/fslib";
|
import { Filename, PortablePath, npath, ppath, xfs } from "@yarnpkg/fslib";
|
||||||
import { getPnpPath } from "@yarnpkg/plugin-pnp";
|
import { getPnpPath } from "@yarnpkg/plugin-pnp";
|
||||||
|
import { scriptUtils } from "@yarnpkg/core";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CommandContext,
|
CommandContext,
|
||||||
@@ -34,53 +35,73 @@ export default class InstallBinCommand extends Command<CommandContext> {
|
|||||||
const report = await StreamReport.start(
|
const report = await StreamReport.start(
|
||||||
{ configuration, stdout: this.context.stdout },
|
{ configuration, stdout: this.context.stdout },
|
||||||
async (report) => {
|
async (report) => {
|
||||||
if (!workspace || workspace.manifest.bin.size === 0) {
|
if (!workspace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodeLinker = configuration.get(`nodeLinker`);
|
const binDir = npath.toPortablePath(this.binDir);
|
||||||
if (!supportedLinkers.includes(nodeLinker)) {
|
|
||||||
nodeLinker = `node-modules`;
|
for (const [name, binaryFile] of workspace.manifest.bin) {
|
||||||
report.reportWarning(
|
const wrapperPath = ppath.join(binDir, name as Filename);
|
||||||
0,
|
const binaryPath = ppath.join(
|
||||||
`The nodeLinker ${nodeLinker} is not supported - executables may have trouble finding dependencies`
|
project.cwd,
|
||||||
|
npath.toPortablePath(binaryFile)
|
||||||
);
|
);
|
||||||
|
await this.writeWrapper(wrapperPath, binaryPath, {
|
||||||
|
configuration,
|
||||||
|
project,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const binDir = npath.toPortablePath(this.binDir);
|
if (configuration.get(`installNixBinariesForDependencies`)) {
|
||||||
const pnpPath = getPnpPath(project).cjs;
|
await project.resolveEverything({ report, lockfileOnly: true });
|
||||||
for (const [name, scriptInput] of workspace.manifest.bin) {
|
const binaries = await scriptUtils.getPackageAccessibleBinaries(
|
||||||
const binPath = ppath.join(binDir, name as Filename);
|
project.topLevelWorkspace.anchoredLocator,
|
||||||
const scriptPath = ppath.join(
|
{ project }
|
||||||
project.cwd,
|
|
||||||
npath.toPortablePath(scriptInput)
|
|
||||||
);
|
);
|
||||||
|
for (const [name, [_, binaryPath]] of binaries.entries()) {
|
||||||
let script;
|
const wrapperPath = ppath.join(binDir, name as Filename);
|
||||||
switch (nodeLinker) {
|
await this.writeWrapper(
|
||||||
case `pnp`:
|
wrapperPath,
|
||||||
script = renderTmpl(binWrapperPnpTmpl, {
|
npath.toPortablePath(binaryPath),
|
||||||
NODE_PATH: process.execPath,
|
{ configuration, project }
|
||||||
PNP_PATH: pnpPath,
|
);
|
||||||
SCRIPT_PATH: scriptPath,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case `node-modules`:
|
|
||||||
script = renderTmpl(binWrapperNodeModulesTmpl, {
|
|
||||||
NODE_PATH: process.execPath,
|
|
||||||
SCRIPT_PATH: scriptPath,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw Error(`Assertion failed: Invalid nodeLinker ${nodeLinker}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await xfs.writeFilePromise(binPath, script);
|
|
||||||
await xfs.chmodPromise(binPath, 0o755);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return report.exitCode();
|
return report.exitCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async writeWrapper(
|
||||||
|
wrapperPath: PortablePath,
|
||||||
|
binaryPath: PortablePath,
|
||||||
|
{
|
||||||
|
configuration,
|
||||||
|
project,
|
||||||
|
}: { configuration: Configuration; project: Project }
|
||||||
|
) {
|
||||||
|
let wrapper;
|
||||||
|
switch (configuration.get(`nodeLinker`)) {
|
||||||
|
case `pnp`:
|
||||||
|
wrapper = renderTmpl(binWrapperPnpTmpl, {
|
||||||
|
NODE_PATH: process.execPath,
|
||||||
|
PNP_PATH: getPnpPath(project).cjs,
|
||||||
|
BINARY_PATH: binaryPath,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case `node-modules`:
|
||||||
|
wrapper = renderTmpl(binWrapperNodeModulesTmpl, {
|
||||||
|
NODE_PATH: process.execPath,
|
||||||
|
BINARY_PATH: binaryPath,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Error(`Assertion failed: Invalid nodeLinker`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await xfs.writeFilePromise(wrapperPath, wrapper);
|
||||||
|
await xfs.chmodPromise(wrapperPath, 0o755);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ declare module "@yarnpkg/core" {
|
|||||||
generateDefaultNix: boolean;
|
generateDefaultNix: boolean;
|
||||||
enableNixPreload: boolean;
|
enableNixPreload: boolean;
|
||||||
isolatedNixBuilds: string[];
|
isolatedNixBuilds: string[];
|
||||||
|
installNixBinariesForDependencies: boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +56,11 @@ const plugin: Plugin<Hooks> = {
|
|||||||
default: [],
|
default: [],
|
||||||
isArray: true,
|
isArray: true,
|
||||||
},
|
},
|
||||||
|
installNixBinariesForDependencies: {
|
||||||
|
description: `If true, the Nix output 'bin' directory will also contain executables for binaries defined by dependencies`,
|
||||||
|
type: SettingsType.BOOLEAN,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec '@@NODE_PATH@@' '@@SCRIPT_PATH@@' "$@"
|
exec '@@NODE_PATH@@' '@@BINARY_PATH@@' "$@"
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
export NODE_OPTIONS="--require @@PNP_PATH@@"
|
export NODE_OPTIONS="--require @@PNP_PATH@@"
|
||||||
exec '@@NODE_PATH@@' '@@SCRIPT_PATH@@' "$@"
|
exec '@@NODE_PATH@@' '@@BINARY_PATH@@' "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user