pkgs: let findOpamFile = src: let opamFiles = (builtins.filter (x: !isNull (builtins.match ".*.opam" x)) (builtins.attrNames (builtins.readDir src))); in if builtins.length opamFiles == 1 then builtins.head opamFiles else builtins.throw "Unable to determine a single opam file in ${src} (${ toString opamFiles }), unable to proceed" ""; in rec { opam-parser = pkgs.stdenv.mkDerivation { name = "opam-parser"; src = ./opam-parser.hs; unpackPhase = "true"; buildInputs = [ pkgs.ghc ]; buildPhase = "ghc -o $out $src"; phases = [ "buildPhase" ]; }; opam2nix = { src, opamFile ? findOpamFile src, ... }@args: pkgs.runCommandNoCC (args.pname or opamFile + ".nix") args "cat ${src}/${opamFile} | ${opam-parser} > $out"; traverseOPAMRepo = repo: self: super: let pkgNames = builtins.readDir "${repo}/packages"; parseVersion = n: builtins.head (builtins.match "[^.]*.(.*)" n); versions = pkg: map parseVersion (builtins.attrNames (builtins.readDir "${repo}/packages/${pkg}")); latestVersion = builtins.foldl' (x: acc: if builtins.compareVersions x acc == 1 then x else acc) ""; opamPkgs = builtins.mapAttrs (n: _: let v = latestVersion (versions n); file = opam2nix { src = "${repo}/packages/${n}/${n}.${v}"; opamFile = "opam"; pname = n; version = v; }; in self.callPackage file { }) pkgNames; in opamPkgs; callOPAMPackage' = callPackage: src: newAttrs: overrides: (callPackage (opam2nix (newAttrs // { inherit src; })) overrides).overrideAttrs ({ buildInputs, src ? src, ... }: { inherit src; buildInputs = buildInputs ++ newAttrs.extraBuildInputs or [ ]; propagatedBuildInputs = buildInputs ++ newAttrs.extraBuildInputs or [ ]; } // newAttrs); }