forked from serokell/nix-npm-buildpackage
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathbuildYarnPackage.nix
106 lines (95 loc) · 3.53 KB
/
buildYarnPackage.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
{ npmInfo, npmModules, untarAndWrap, depToFetch, commonEnv, lib, runCommand
, fetchurl, writeScriptBin, nodejs, yarn, patchShebangs, writeText, stdenv
, makeWrapper, writeShellScriptBin, unScope }:
let
yarnpkg-lockfile = fetchurl {
name = "_yarnpkg_lockfile___lockfile_1.1.0.tgz";
url = "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz";
sha1 = "e77a97fbd345b76d83245edcd17d393b1b41fb31";
};
yarnCacheInput = oFile: iFile: overrides:
let
self = builtins.listToAttrs (depToFetch iFile);
final = with lib; fix (foldl' (flip extends) (const self) overrides);
in writeText oFile (builtins.toJSON final);
yarnWrapper = writeScriptBin "yarn" ''
#!${nodejs}/bin/node
const { promisify } = require('util')
const child_process = require('child_process');
const exec = promisify(child_process.exec)
const { existsSync } = require('fs')
async function getYarn() {
const yarn = "${yarn}/bin/yarn"
if (existsSync(`''${yarn}.js`)) return `''${yarn}.js`
return yarn
}
global.experimentalYarnHooks = {
async linkStep(cb) {
const res = await cb()
console.log("patching shebangs")
await exec("${patchShebangs}/bin/patchShebangs.sh $SOURCE_DIR/node_modules")
if (process.env.yarnPostLink) {
console.log("Running post-link hook")
console.log(await exec(process.env.yarnPostLink))
}
return res
}
}
getYarn().then(require)
'';
yarnCmd = "${yarnWrapper}/bin/yarn";
in args@{ src, yarnBuild ? "yarn", yarnBuildMore ? "", integreties ? { }
, packageOverrides ? [ ], buildInputs ? [ ], yarnFlags ? [ ],
subdir ? null
, ... }:
let
deps = { dependencies = builtins.fromJSON (builtins.readFile yarnJson); };
yarnIntFile = writeText "integreties.json" (builtins.toJSON integreties);
yarnJson = runCommand "yarn.json" { } ''
set -e
mkdir -p node_modules/@yarnpkg/lockfile
tar -C $_ --strip-components=1 -xf ${yarnpkg-lockfile}
addToSearchPath NODE_PATH $PWD/node_modules # @yarnpkg/lockfile
addToSearchPath NODE_PATH ${npmModules} # ssri
${nodejs}/bin/node ${./mkyarnjson.js} ${src + "/yarn.lock"} ${yarnIntFile} > $out
'';
pkgDir = if subdir != null then src + "/" + subdir else src;
in stdenv.mkDerivation (rec {
inherit (npmInfo pkgDir) pname version;
preBuildPhases = [ "yarnConfigPhase" "yarnCachePhase" ];
preInstallPhases = [ "yarnPackPhase" ];
outFile = unScope "${pname}-${version}";
# TODO
yarnConfigPhase = ''
cat <<-END >> .yarnrc
yarn-offline-mirror "$PWD/yarn-cache"
nodedir "${nodejs}"
END
'';
yarnCachePhase = ''
mkdir -p yarn-cache
node ${./mkyarncache.js} ${yarnCacheInput "yarn-cache-input.json" deps packageOverrides}
'';
buildPhase = ''
runHook preBuild
patchShebangs .
yarn() { command yarn $yarnFlags "$@"; }
export SOURCE_DIR="$PWD"
${if subdir != null then "cd ${subdir}" else ""}
${yarnBuild}
${yarnBuildMore}
runHook postBuild
'';
# TODO: install --production?
yarnPackPhase = ''
yarn pack --ignore-scripts --filename "${outFile}.tgz"
'';
installPhase = ''
runHook preInstall
${untarAndWrap "${outFile}" [ "${yarn}/bin/yarn" ]}
runHook postInstall
'';
} // commonEnv // removeAttrs args [ "integreties" "packageOverrides" ] // {
buildInputs = [ nodejs makeWrapper yarnWrapper ] ++ buildInputs;
yarnFlags = [ "--offline" "--frozen-lockfile" "--non-interactive" ] ++ yarnFlags;
})