Upgrade to Yarn v3

This commit is contained in:
Stéphan Kochen
2021-08-15 21:00:54 +02:00
parent 47e5ae1b79
commit 2757cfd115
14 changed files with 1871 additions and 1167 deletions
+24 -3
View File
@@ -5,6 +5,8 @@ on: [push, pull_request]
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
NIX_PATH: nixpkgs=channel:nixpkgs-unstable
steps: steps:
- name: Checkout - name: Checkout
@@ -13,7 +15,7 @@ jobs:
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: 10.x node-version: 12.x
- name: Yarn cache - name: Yarn cache
uses: actions/cache@v2 uses: actions/cache@v2
@@ -59,5 +61,24 @@ jobs:
- name: Test nix-build - name: Test nix-build
run: nix-build run: nix-build
env:
NIX_PATH: nixpkgs=channel:nixpkgs-unstable # TODO: Check there really is a separate derivation,
# and that Yarn actually reuses the build.
- name: Test isolated builds
run: |
# Matches example in ISOLATED_BUILDS.md
echo 'isolatedNixBuilds: ["sqlite3"]' >> .yarnrc.yml
cat > default.nix << EOF
{ pkgs ? import <nixpkgs> { } }:
pkgs.callPackage ./yarn-project.nix { } {
src = ./.;
overrideSqlite3Attrs = old: {
npm_config_sqlite = "/"; # Don't accidentally use the wrong sqlite.
buildInputs = old.buildInputs ++ (with pkgs; [ python3 sqlite ]);
};
}
EOF
yarn add sqlite3
nix-build
-55
View File
File diff suppressed because one or more lines are too long
+631
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
yarnPath: .yarn/releases/yarn-2.4.1.cjs yarnPath: .yarn/releases/yarn-3.0.0.cjs
+2 -2
View File
@@ -2,7 +2,7 @@
**Upgrading the plugin? See [UPGRADING.md](./UPGRADING.md)** **Upgrading the plugin? See [UPGRADING.md](./UPGRADING.md)**
Generates a [Nix] expression to build a [Yarn] v2 project (not using Generates a [Nix] expression to build a [Yarn] v3 project (not using
zero-install). zero-install).
- Provides a `yarn` shell alias in the Nix builder — no global Yarn v1 install - Provides a `yarn` shell alias in the Nix builder — no global Yarn v1 install
@@ -43,7 +43,7 @@ Related projects:
## Usage ## Usage
The minimum version of Yarn is 2.2.0. Run the following in your project folder The minimum version of Yarn is 3.0.0. Run the following in your project folder
to check: to check:
```sh ```sh
+1 -1
View File
File diff suppressed because one or more lines are too long
+31 -31
View File
@@ -14,42 +14,42 @@
"@babel/plugin-proposal-decorators": "^7.10.5", "@babel/plugin-proposal-decorators": "^7.10.5",
"@babel/preset-typescript": "^7.10.4", "@babel/preset-typescript": "^7.10.4",
"@types/node": "10", "@types/node": "10",
"@yarnpkg/cli": "^2.2.0", "@yarnpkg/cli": "^3.0.0",
"@yarnpkg/core": "^2.2.0", "@yarnpkg/core": "^3.0.0",
"@yarnpkg/fslib": "^2.2.0", "@yarnpkg/fslib": "^2.5.1",
"@yarnpkg/parsers": "^2.2.0", "@yarnpkg/parsers": "^2.4.0",
"@yarnpkg/plugin-patch": "^2.1.1", "@yarnpkg/plugin-patch": "^3.0.0",
"@yarnpkg/plugin-pnp": "^2.2.0", "@yarnpkg/plugin-pnp": "^3.0.0",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"clipanion": "^2.4.4", "clipanion": "^3.0.0",
"prettier": "2.2.1", "prettier": "2.3.2",
"raw-loader": "^4.0.1", "raw-loader": "^4.0.1",
"typescript": "4.2.4", "typescript": "4.3.5",
"webpack": "^5.35.0", "webpack": "^5.35.0",
"webpack-sources": "^2.2.0" "webpack-sources": "^2.2.0"
}, },
"resolutions": { "resolutions": {
"@yarnpkg/cli": "2.2.0", "@yarnpkg/cli": "3.0.1",
"@yarnpkg/core": "2.2.0", "@yarnpkg/core": "3.0.0",
"@yarnpkg/fslib": "2.2.0", "@yarnpkg/fslib": "2.5.1",
"@yarnpkg/libzip": "2.2.0", "@yarnpkg/libzip": "2.2.2",
"@yarnpkg/parsers": "2.2.0", "@yarnpkg/parsers": "2.4.0",
"@yarnpkg/plugin-compat": "2.1.1", "@yarnpkg/plugin-compat": "3.0.0",
"@yarnpkg/plugin-dlx": "2.1.1", "@yarnpkg/plugin-dlx": "3.0.0",
"@yarnpkg/plugin-essentials": "2.2.0", "@yarnpkg/plugin-essentials": "3.0.0",
"@yarnpkg/plugin-file": "2.2.0", "@yarnpkg/plugin-file": "2.2.1",
"@yarnpkg/plugin-git": "2.1.1", "@yarnpkg/plugin-git": "2.4.0",
"@yarnpkg/plugin-github": "2.1.1", "@yarnpkg/plugin-github": "2.2.0",
"@yarnpkg/plugin-http": "2.1.1", "@yarnpkg/plugin-http": "2.1.3",
"@yarnpkg/plugin-init": "2.1.1", "@yarnpkg/plugin-init": "3.0.0",
"@yarnpkg/plugin-link": "2.1.1", "@yarnpkg/plugin-link": "2.1.2",
"@yarnpkg/plugin-node-modules": "2.1.1", "@yarnpkg/plugin-node-modules": "2.3.0",
"@yarnpkg/plugin-npm": "2.2.0", "@yarnpkg/plugin-npm": "2.5.0",
"@yarnpkg/plugin-npm-cli": "2.1.1", "@yarnpkg/plugin-npm-cli": "3.0.0",
"@yarnpkg/plugin-pack": "2.2.0", "@yarnpkg/plugin-pack": "3.0.0",
"@yarnpkg/plugin-patch": "2.1.1", "@yarnpkg/plugin-patch": "3.0.0",
"@yarnpkg/plugin-pnp": "2.2.0", "@yarnpkg/plugin-pnp": "3.0.1",
"@yarnpkg/plugin-stage": "2.1.1", "@yarnpkg/plugin-stage": "3.0.0",
"@yarnpkg/shell": "2.2.0" "@yarnpkg/shell": "3.0.0"
} }
} }
+3 -4
View File
@@ -1,4 +1,4 @@
import { Command } from "clipanion"; import { Command, Option } from "clipanion";
import { import {
Cache, Cache,
@@ -12,10 +12,9 @@ import {
// Internal command that fetches a single locator. // Internal command that fetches a single locator.
// Used from within Nix to build the cache for the project. // Used from within Nix to build the cache for the project.
export default class FetchOneCommand extends Command<CommandContext> { export default class FetchOneCommand extends Command<CommandContext> {
@Command.String() static paths = [[`nixify`, `fetch-one`]];
locator: string = ``; locator = Option.String();
@Command.Path(`nixify`, `fetch-one`)
async execute() { async execute() {
const configuration = await Configuration.find( const configuration = await Configuration.find(
this.context.cwd, this.context.cwd,
+7 -14
View File
@@ -1,4 +1,4 @@
import { Command } from "clipanion"; import { Command, Option } from "clipanion";
import { PortablePath, ppath, xfs } from "@yarnpkg/fslib"; import { PortablePath, ppath, xfs } from "@yarnpkg/fslib";
import { createHash } from "crypto"; import { createHash } from "crypto";
import { parseSyml, stringifySyml } from "@yarnpkg/parsers"; import { parseSyml, stringifySyml } from "@yarnpkg/parsers";
@@ -16,14 +16,11 @@ import {
// Internal command that injects an isolated build inside a Nix build. // Internal command that injects an isolated build inside a Nix build.
export default class InjectBuildCommand extends Command<CommandContext> { export default class InjectBuildCommand extends Command<CommandContext> {
@Command.String() static paths = [[`nixify`, `inject-build`]];
locator: string = ``; locator = Option.String();
@Command.String() source = Option.String();
source: string = ``; installLocation = Option.String();
@Command.String()
installLocation: string = ``;
@Command.Path(`nixify`, `inject-build`)
async execute() { async execute() {
const configuration = await Configuration.find( const configuration = await Configuration.find(
this.context.cwd, this.context.cwd,
@@ -132,12 +129,8 @@ export default class InjectBuildCommand extends Command<CommandContext> {
// Update build state. The way we do this is crude, but we run // Update build state. The way we do this is crude, but we run
// `yarn install` later, which should clean it up again. // `yarn install` later, which should clean it up again.
const bstatePath: PortablePath = configuration.get(`bstatePath`); project.storedBuildState.set(pkg.locatorHash, buildHash);
const bstate: { [key: string]: string } = xfs.existsSync(bstatePath) await project.persistInstallStateFile();
? parseSyml(await xfs.readFilePromise(bstatePath, `utf8`))
: {};
bstate[pkg.locatorHash] = buildHash;
await xfs.writeFilePromise(bstatePath, stringifySyml(bstate));
} }
); );
+4 -5
View File
@@ -1,4 +1,4 @@
import { Command } from "clipanion"; import { Command, Option } from "clipanion";
import { Filename, npath, ppath, xfs } from "@yarnpkg/fslib"; import { Filename, npath, ppath, xfs } from "@yarnpkg/fslib";
import { getPnpPath } from "@yarnpkg/plugin-pnp"; import { getPnpPath } from "@yarnpkg/plugin-pnp";
@@ -18,10 +18,9 @@ const supportedLinkers = [`pnp`, `node-modules`];
// Internal command that creates wrappers for binaries. // Internal command that creates wrappers for binaries.
// Used inside the Nix install phase. // Used inside the Nix install phase.
export default class InstallBinCommand extends Command<CommandContext> { export default class InstallBinCommand extends Command<CommandContext> {
@Command.String() static paths = [[`nixify`, `install-bin`]];
binDir: string = ``; binDir = Option.String();
@Command.Path(`nixify`, `install-bin`)
async execute() { async execute() {
const configuration = await Configuration.find( const configuration = await Configuration.find(
this.context.cwd, this.context.cwd,
@@ -49,7 +48,7 @@ export default class InstallBinCommand extends Command<CommandContext> {
} }
const binDir = npath.toPortablePath(this.binDir); const binDir = npath.toPortablePath(this.binDir);
const pnpPath = getPnpPath(project).main; const pnpPath = getPnpPath(project).cjs;
for (const [name, scriptInput] of workspace.manifest.bin) { for (const [name, scriptInput] of workspace.manifest.bin) {
const binPath = ppath.join(binDir, name as Filename); const binPath = ppath.join(binDir, name as Filename);
const scriptPath = ppath.join( const scriptPath = ppath.join(
+2 -6
View File
@@ -117,17 +117,13 @@ export default async (project: Project, cache: Cache, report: Report) => {
cacheEntriesCode += `};`; cacheEntriesCode += `};`;
// Generate Nix code for isolated builds. // Generate Nix code for isolated builds.
const isolatedBuilds: string[] = configuration.get(`isolatedNixBuilds`); const isolatedBuilds = configuration.get(`isolatedNixBuilds`);
let isolatedPackages = new Set<Package>(); let isolatedPackages = new Set<Package>();
let isolatedIntegration = []; let isolatedIntegration = [];
let isolatedCode = []; let isolatedCode = [];
const nodeLinker = configuration.get(`nodeLinker`); const nodeLinker = configuration.get(`nodeLinker`);
const pnpUnpluggedFolder = configuration.get(`pnpUnpluggedFolder`); const pnpUnpluggedFolder = configuration.get(`pnpUnpluggedFolder`);
const bstatePath: PortablePath = configuration.get(`bstatePath`);
const bstate: { [key: string]: string } = xfs.existsSync(bstatePath)
? parseSyml(await xfs.readFilePromise(bstatePath, `utf8`))
: {};
const collectTree = (pkg: Package, out: Set<string> = new Set()) => { const collectTree = (pkg: Package, out: Set<string> = new Set()) => {
const locatorStr = structUtils.stringifyLocator(pkg); const locatorStr = structUtils.stringifyLocator(pkg);
@@ -184,7 +180,7 @@ export default async (project: Project, cache: Cache, report: Report) => {
return out; return out;
}; };
for (const locatorHash of Object.keys(bstate)) { for (const locatorHash of project.storedBuildState.keys()) {
const pkg = project.storedPackages.get(locatorHash as LocatorHash); const pkg = project.storedPackages.get(locatorHash as LocatorHash);
if (!pkg) { if (!pkg) {
throw Error(`Assertion failed: The locator should have been registered`); throw Error(`Assertion failed: The locator should have been registered`);
+11
View File
@@ -1,10 +1,21 @@
import { Hooks, Plugin, SettingsType } from "@yarnpkg/core"; import { Hooks, Plugin, SettingsType } from "@yarnpkg/core";
import { PortablePath } from "@yarnpkg/fslib";
import FetchOneCommand from "./FetchOneCommand"; import FetchOneCommand from "./FetchOneCommand";
import InjectBuildCommand from "./InjectBuildCommand"; import InjectBuildCommand from "./InjectBuildCommand";
import InstallBinCommand from "./InstallBinCommand"; import InstallBinCommand from "./InstallBinCommand";
import generate from "./generate"; import generate from "./generate";
declare module "@yarnpkg/core" {
interface ConfigurationValueMap {
enableNixify: boolean;
nixExprPath: PortablePath;
generateDefaultNix: boolean;
enableNixPreload: boolean;
isolatedNixBuilds: string[];
}
}
const plugin: Plugin<Hooks> = { const plugin: Plugin<Hooks> = {
commands: [FetchOneCommand, InjectBuildCommand, InstallBinCommand], commands: [FetchOneCommand, InjectBuildCommand, InstallBinCommand],
hooks: { hooks: {
+5
View File
@@ -75,6 +75,8 @@ let
echo '{ "dependencies": { "${pname}": "${version}" } }' > package.json echo '{ "dependencies": { "${pname}": "${version}" } }' > package.json
install -m 0600 ${lockfile} ./yarn.lock install -m 0600 ${lockfile} ./yarn.lock
export yarn_global_folder="$TMP"
export YARN_ENABLE_IMMUTABLE_INSTALLS=false
yarn --immutable-cache yarn --immutable-cache
''; '';
@@ -107,6 +109,9 @@ let
source ${mkCacheBuilderForDrvs (lib.attrValues cacheDrvs)} source ${mkCacheBuilderForDrvs (lib.attrValues cacheDrvs)}
popd > /dev/null popd > /dev/null
# Yarn may need a writable home directory.
export yarn_global_folder="$TMP"
@@ISOLATED_INTEGRATION@@ @@ISOLATED_INTEGRATION@@
# Run normal Yarn install to complete dependency installation. # Run normal Yarn install to complete dependency installation.
+1149 -1045
View File
File diff suppressed because it is too large Load Diff