diff --git a/default.nix b/default.nix index 3aa4d38..96a8011 100644 --- a/default.nix +++ b/default.nix @@ -1,5 +1,5 @@ { writeShellScriptBin, writeText, runCommand, writeScriptBin, - stdenv, fetchurl, makeWrapper, nodejs, yarn, jq }: + stdenv, fetchurl, makeWrapper, nodejs, yarn, jq, gnutar }: with stdenv.lib; let inherit (builtins) fromJSON toJSON split removeAttrs toFile; @@ -8,18 +8,35 @@ with stdenv.lib; let depsToFetches = deps: concatMap depToFetch (attrValues deps); - depFetchOwn = { resolved, integrity, name ? null, ... }: + makeTarball = name: path: runCommand "${name}.tar.gz" { + buildInputs = [ gnutar ]; + } '' + cp -R "${path}" package + tar -caf $out package + ''; + + depFetchOwn = args: let - ssri = split "-" integrity; + uri = args.resolved or args.version; + parsedURI = splitString "://" uri; + parsedPath= splitString "#" uri; + parsedFrom= splitString "#" args.from; + rev = elemAt parsedPath 1; + ref = if builtins.length parsedFrom > 1 then elemAt parsedFrom 1 else "master"; + protocol = elemAt parsedURI 0; + ssri = split "-" args.integrity; hashType = head ssri; hash = elemAt ssri 2; - bname = baseNameOf resolved; + bname = baseNameOf uri; fname = if hasSuffix ".tgz" bname || hasSuffix ".tar.gz" bname then bname else bname + ".tgz"; - in nameValuePair resolved { - inherit name bname; - path = fetchurl { name = fname; url = resolved; "${hashType}" = hash; }; - }; + path = if hasInfix "git" protocol + then makeTarball (args.name or "source") (builtins.fetchGit { url = uri; inherit ref rev; }) + else if args ? integrity + then fetchurl { name = fname; url = uri; "${hashType}" = hash; } + else throw "Unsupported dependency ${uri} (${args.name or "no name"})"; + + in nameValuePair uri { name = args.name or null; inherit bname path; }; overrideTgz = src: runCommand "${src.name}.tgz" {} '' cp -r --reflink=auto ${src} ./package @@ -31,8 +48,8 @@ with stdenv.lib; let overrideToFetch = pkg: { path = "${overrideTgz pkg}"; }; - depToFetch = args @ { resolved ? null, dependencies ? {}, ... }: - (optional (resolved != null) (depFetchOwn args)) ++ (depsToFetches dependencies); + depToFetch = args @ { dependencies ? {}, ... }: + (optional ((args ? resolved || args ? version) && (args ? integrity || args ? from)) (depFetchOwn args)) ++ (depsToFetches dependencies); cacheInput = oFile: iFile: overrides: writeText oFile (toJSON ((listToAttrs (depToFetch iFile)) diff --git a/mknpmcache.js b/mknpmcache.js index 0f17a26..ba94458 100644 --- a/mknpmcache.js +++ b/mknpmcache.js @@ -16,7 +16,7 @@ const lock = JSON.parse(fs.readFileSync(pkgLockFile, "utf8")) const nixPkgs = JSON.parse(fs.readFileSync(nixPkgsFile, "utf8")) function traverseDeps(pkg, fn) { - Object.entries(pkg.dependencies).forEach(([name, dep]) => { + Object.entries(pkg.dependencies).forEach(([name, dep]) => { fn(name, dep) if (dep.dependencies) traverseDeps(dep, fn) }) @@ -29,20 +29,18 @@ async function main(lockfile, nix, cache) { return [url, manifest._integrity] }) const hashes = new Map(await Promise.all(promises)) - traverseDeps(lockfile, (name, dep) => { + traverseDeps(lockfile, (name, dep) => { if (hashes.has(name)) { console.log("overriding package", name) dep.integrity = hashes.get(name) return } - if (!dep.integrity || !dep.resolved) { - return - } - if (dep.integrity.startsWith("sha1-")) { - assert(hashes.has(dep.resolved)) - dep.integrity = hashes.get(dep.resolved) + let id = dep.resolved || dep.version; + if ((dep.from && dep.from.includes("git")) || (dep.integrity && ! dep.integrity.startsWith("sha512-"))) { + assert(hashes.has(id)) + dep.integrity = hashes.get(id) } else { - assert(dep.integrity == hashes.get(dep.resolved)) + assert(dep.integrity == hashes.get(id)) } }) // rewrite lock file to use sha512 hashes from pacote and overrides