Yarn v4 support
This commit is contained in:
+44
-15
@@ -1,13 +1,11 @@
|
||||
import { tmpdir } from "os";
|
||||
|
||||
import { Filename, npath, PortablePath, ppath, xfs } from "@yarnpkg/fslib";
|
||||
import { patchUtils } from "@yarnpkg/plugin-patch";
|
||||
import {
|
||||
computeFixedOutputStorePath,
|
||||
sanitizeDerivationName,
|
||||
} from "./nixUtils";
|
||||
import { json, indent, renderTmpl, upperCamelize } from "./textUtils";
|
||||
|
||||
import {
|
||||
Cache,
|
||||
YarnVersion,
|
||||
execUtils,
|
||||
hashUtils,
|
||||
InstallMode,
|
||||
@@ -20,7 +18,12 @@ import {
|
||||
|
||||
import defaultExprTmpl from "./tmpl/default.nix.in";
|
||||
import projectExprTmpl from "./tmpl/yarn-project.nix.in";
|
||||
import { tmpdir } from "os";
|
||||
import {
|
||||
computeFixedOutputStorePath,
|
||||
sanitizeDerivationName,
|
||||
} from "./nixUtils";
|
||||
|
||||
const isYarn3 = YarnVersion?.startsWith("3.") || false;
|
||||
|
||||
// Generator function that runs after `yarn install`.
|
||||
export default async (
|
||||
@@ -49,12 +52,24 @@ export default async (
|
||||
const nixExprPath = configuration.get(`nixExprPath`);
|
||||
|
||||
const yarnPathAbs = configuration.get(`yarnPath`);
|
||||
let yarnPathExpr: string;
|
||||
if (yarnPathAbs.startsWith(cwd)) {
|
||||
yarnPathExpr =
|
||||
let yarnBinExpr: string;
|
||||
if (yarnPathAbs === null) {
|
||||
// Assume the current running script is the correct Yarn.
|
||||
const hexHash = await hashUtils.checksumFile(
|
||||
process.argv[1] as PortablePath,
|
||||
);
|
||||
const sriHash = "sha512-" + Buffer.from(hexHash, "hex").toString("base64");
|
||||
yarnBinExpr = [
|
||||
"fetchurl {",
|
||||
` url = "https://repo.yarnpkg.com/${YarnVersion!}/packages/yarnpkg-cli/bin/yarn.js";`,
|
||||
` hash = "${sriHash}";`,
|
||||
"}",
|
||||
].join("\n ");
|
||||
} else if (yarnPathAbs.startsWith(cwd)) {
|
||||
yarnBinExpr =
|
||||
"./" + ppath.relative(ppath.dirname(nixExprPath), yarnPathAbs);
|
||||
} else {
|
||||
yarnPathExpr = json(yarnPathAbs);
|
||||
yarnBinExpr = json(yarnPathAbs);
|
||||
report.reportWarning(
|
||||
0,
|
||||
`The Yarn path ${yarnPathAbs} is outside the project - it may not be reachable by the Nix build`,
|
||||
@@ -65,6 +80,8 @@ export default async (
|
||||
let cacheFolderExpr: string;
|
||||
if (cacheFolderAbs.startsWith(cwd)) {
|
||||
cacheFolderExpr = json(ppath.relative(cwd, cacheFolderAbs));
|
||||
} else if (!isYarn3 && configuration.get(`enableGlobalCache`)) {
|
||||
cacheFolderExpr = '".yarn/cache"';
|
||||
} else {
|
||||
throw Error(
|
||||
`The cache folder ${cacheFolderAbs} is outside the project, this is currently not supported`,
|
||||
@@ -99,6 +116,7 @@ export default async (
|
||||
// Build a list of cache entries so Nix can fetch them.
|
||||
// TODO: See if we can use Nix fetchurl for npm: dependencies.
|
||||
interface CacheEntry {
|
||||
originalFilename: Filename;
|
||||
filename: Filename;
|
||||
sha512: string;
|
||||
}
|
||||
@@ -109,7 +127,9 @@ export default async (
|
||||
for (const pkg of project.storedPackages.values()) {
|
||||
const { locatorHash } = pkg;
|
||||
const checksum = project.storedChecksums.get(locatorHash);
|
||||
const cachePath = cache.getLocatorPath(pkg, checksum || null, cacheOptions);
|
||||
const cachePath = isYarn3
|
||||
? (cache as any).getLocatorPath(pkg, checksum || null, cacheOptions)
|
||||
: cache.getLocatorPath(pkg, checksum || null);
|
||||
if (!cachePath) continue;
|
||||
|
||||
const filename = ppath.basename(cachePath);
|
||||
@@ -119,7 +139,13 @@ export default async (
|
||||
const sha512 = checksum
|
||||
? checksum.split(`/`).pop()!
|
||||
: await hashUtils.checksumFile(cachePath);
|
||||
cacheEntries.set(locatorStr, { filename, sha512 });
|
||||
cacheEntries.set(locatorStr, {
|
||||
originalFilename: filename,
|
||||
// Rebuild the filename, because the cache file we're operating on may be
|
||||
// from the mirror directory, which uses different naming.
|
||||
filename: cache.getChecksumFilename(pkg, sha512),
|
||||
sha512,
|
||||
});
|
||||
}
|
||||
|
||||
let cacheEntriesCode = `cacheEntries = {\n`;
|
||||
@@ -290,7 +316,7 @@ export default async (
|
||||
const projectName = ident ? structUtils.stringifyIdent(ident) : `workspace`;
|
||||
const projectExpr = renderTmpl(projectExprTmpl, {
|
||||
PROJECT_NAME: json(projectName),
|
||||
YARN_PATH: yarnPathExpr,
|
||||
YARN_BIN: yarnBinExpr,
|
||||
LOCKFILE: lockfileExpr,
|
||||
CACHE_FOLDER: cacheFolderExpr,
|
||||
CACHE_ENTRIES: cacheEntriesCode,
|
||||
@@ -321,7 +347,10 @@ export default async (
|
||||
) {
|
||||
await xfs.mktempPromise(async (tempDir) => {
|
||||
const toPreload: PortablePath[] = [];
|
||||
for (const [locator, { filename, sha512 }] of cacheEntries.entries()) {
|
||||
for (const [
|
||||
locator,
|
||||
{ originalFilename, sha512 },
|
||||
] of cacheEntries.entries()) {
|
||||
const name = sanitizeDerivationName(locator);
|
||||
// Check to see if the Nix store entry already exists.
|
||||
const hash = Buffer.from(sha512, "hex");
|
||||
@@ -336,7 +365,7 @@ export default async (
|
||||
const subdir = ppath.join(tempDir, sha512.slice(0, 7) as Filename);
|
||||
await xfs.mkdirPromise(subdir);
|
||||
|
||||
const src = ppath.join(cache.cwd, filename);
|
||||
const src = ppath.join(cache.cwd, originalFilename);
|
||||
const dst = ppath.join(subdir, name as Filename);
|
||||
await xfs.copyFilePromise(src, dst);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user