init
This commit is contained in:
11
flake.nix
Normal file
11
flake.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
outputs =
|
||||
{ self }:
|
||||
{
|
||||
overlays.default = (
|
||||
final: prev: {
|
||||
fetchYarnDepsV2 = final.callPackage ./yarn.nix { };
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
140
yarn.nix
Normal file
140
yarn.nix
Normal file
@@ -0,0 +1,140 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
parseFile =
|
||||
filePath:
|
||||
let
|
||||
fileContent = builtins.readFile filePath;
|
||||
fileLines = lib.strings.splitString "\n" fileContent;
|
||||
in
|
||||
parseLines fileLines { } null false [ ];
|
||||
|
||||
parseKeyValue =
|
||||
line:
|
||||
let
|
||||
matchResult = builtins.match ''^[ ]*"?([^" ]+)"?[ ]+"?([^"]+)"?$'' line;
|
||||
in
|
||||
if matchResult == null then
|
||||
null
|
||||
else if builtins.length matchResult < 2 then
|
||||
null
|
||||
else
|
||||
{
|
||||
key = builtins.elemAt matchResult 0;
|
||||
value = builtins.elemAt matchResult 1;
|
||||
};
|
||||
isDependencySection =
|
||||
line: builtins.match ''^[ ]*(dependencies|optionalDependencies):$'' line != null;
|
||||
parsePackageHeader = line: builtins.match ''^(.*):$'' line;
|
||||
deepMergeAttr =
|
||||
attrName: update: attrSet:
|
||||
let
|
||||
previous = attrSet.${attrName} or { };
|
||||
in
|
||||
attrSet // { "${attrName}" = previous // update; };
|
||||
|
||||
cleanKey =
|
||||
rawKey:
|
||||
let
|
||||
# Remove surrounding quotes if present
|
||||
unquoted =
|
||||
if builtins.match ''^"(.*)"$'' rawKey != null then
|
||||
builtins.elemAt (builtins.match ''^"(.*)"$'' rawKey) 0
|
||||
else
|
||||
rawKey;
|
||||
# Remove leading @ if present
|
||||
noAtPrefix =
|
||||
if builtins.match ''^@(.*)$'' unquoted != null then
|
||||
builtins.elemAt (builtins.match ''^@(.*)$'' unquoted) 0
|
||||
else
|
||||
unquoted;
|
||||
# Remove everything after (and including) the last @ if present
|
||||
splitAt = builtins.match ''^([^@]+)@.*$'' noAtPrefix;
|
||||
cleaned = if splitAt != null then builtins.elemAt splitAt 0 else noAtPrefix;
|
||||
in
|
||||
cleaned;
|
||||
|
||||
parseLines =
|
||||
lines: acc: currentPkg: inDeps: depList:
|
||||
if lines == [ ] then
|
||||
acc
|
||||
else
|
||||
let
|
||||
line = builtins.head lines;
|
||||
rest = builtins.tail lines;
|
||||
pkgHeader = parsePackageHeader line;
|
||||
in
|
||||
if inDeps then
|
||||
let
|
||||
kv = parseKeyValue line;
|
||||
in
|
||||
if kv != null then
|
||||
parseLines rest acc currentPkg true (depList ++ [ kv ])
|
||||
else
|
||||
parseLines rest (deepMergeAttr currentPkg { deps = depList; } acc) currentPkg false [ ]
|
||||
else if isDependencySection line then
|
||||
parseLines rest acc currentPkg true [ ]
|
||||
else if pkgHeader != null then
|
||||
let
|
||||
pkgName = builtins.elemAt pkgHeader 0;
|
||||
in
|
||||
parseLines rest (acc // { "${pkgName}" = { }; }) pkgName false depList
|
||||
else if currentPkg != null then
|
||||
let
|
||||
kv = parseKeyValue line;
|
||||
in
|
||||
if kv == null then
|
||||
parseLines rest acc currentPkg false depList
|
||||
else
|
||||
parseLines rest (deepMergeAttr currentPkg { "${kv.key}" = kv.value; } acc) currentPkg false depList
|
||||
else
|
||||
parseLines rest acc currentPkg false depList;
|
||||
|
||||
convertKey =
|
||||
key:
|
||||
let
|
||||
hasSlash = builtins.match ".*/.*" key != null;
|
||||
split = lib.strings.splitString "/" key;
|
||||
first = builtins.elemAt split 0;
|
||||
last = builtins.elemAt split (builtins.length split - 1);
|
||||
result = if hasSlash then "_${first}_${last}___${last}" else "${key}___${key}";
|
||||
in
|
||||
result;
|
||||
|
||||
parseMap =
|
||||
pkgMap:
|
||||
builtins.listToAttrs (
|
||||
lib.mapAttrsToList (
|
||||
originalKey: pkgAttrs:
|
||||
let
|
||||
cleanedKey = cleanKey originalKey;
|
||||
convertedKey = convertKey cleanedKey;
|
||||
filenameRaw = "${convertedKey}_${pkgAttrs.version}.tgz";
|
||||
filename = builtins.replaceStrings [ "-" ] [ "_" ] filenameRaw;
|
||||
in
|
||||
{
|
||||
name = filename;
|
||||
value = pkgs.fetchurl {
|
||||
url = pkgAttrs.resolved;
|
||||
hash = pkgAttrs.integrity;
|
||||
};
|
||||
}
|
||||
) pkgMap
|
||||
);
|
||||
combineAll =
|
||||
fileMap: yarnLockPath:
|
||||
let
|
||||
copyCmds = lib.mapAttrsToList (filename: filePath: "cp ${filePath} $out/${filename}") fileMap;
|
||||
script = builtins.concatStringsSep "\n" copyCmds;
|
||||
in
|
||||
pkgs.runCommand "combine-all" { } ''
|
||||
mkdir -p $out;
|
||||
${script}
|
||||
cp ${yarnLockPath} $out/yarn.lock
|
||||
'';
|
||||
in
|
||||
{
|
||||
yarnLock ? null,
|
||||
}:
|
||||
combineAll (parseMap (parseFile yarnLock)) yarnLock
|
||||
Reference in New Issue
Block a user