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