Skip to content

Commit

Permalink
flek
Browse files Browse the repository at this point in the history
  • Loading branch information
balsoft committed Dec 24, 2021
1 parent 86b3235 commit d4df438
Show file tree
Hide file tree
Showing 13 changed files with 473 additions and 297 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
result*
264 changes: 6 additions & 258 deletions default.nix
Original file line number Diff line number Diff line change
@@ -1,258 +1,6 @@
# Pkgset = { ${name} = { ${version} = Pkgdef; ... } ... }
# Pkgdef = { name = String; version = String; depends = [OpamVar]; build = ?[[String]]; install = ?[[String]]; ... }

pkgs:
let
inherit (builtins)
readDir mapAttrs concatStringsSep concatMap all isString isList elem
attrValues filter attrNames head elemAt splitVersion foldl' fromJSON
listToAttrs readFile getAttr toFile match isAttrs pathExists;
inherit (pkgs) lib;
inherit (lib)
versionAtLeast splitString tail mapAttrs' nameValuePair zipAttrsWith collect
filterAttrs unique subtractLists concatMapStringsSep concatLists reverseList
fileContents pipe makeScope optionalAttrs filterAttrsRecursive hasSuffix
converge mapAttrsRecursive hasAttr composeManyExtensions;

readDirRecursive = dir:
mapAttrs (name: type:
if type == "directory" then readDirRecursive "${dir}/${name}" else type)
(readDir dir);

# [Pkgset] -> Pkgset
mergePackageSets = zipAttrsWith (_: foldl' (a: b: a // b) { });

bootstrapPackagesStub = import ./bootstrapPackages.nix { };

bootstrapPackageNames = attrNames bootstrapPackagesStub;
in rec {
# filterRelevant (traverseOPAMRepository ../../opam-repository) "opam-ed"
opam2json = pkgs.ocaml-ng.ocamlPackages_4_09.callPackage ./opam2json.nix { };

# Path -> {...}
fromOPAM = opamFile:
let
json = pkgs.runCommandNoCC "opam.json" {
preferLocalBuild = true;
allowSubstitutes = false;
} "${opam2json}/bin/opam2json ${opamFile} > $out";
in fromJSON (readFile json);

fromOPAM' = opamText: fromOPAM (toFile "opam" opamText);

# Pkgdef -> Derivation
pkgdef2drv = import ./pkgdef2drv.nix pkgs;

# Path -> Derivation
opam2nix = { opamFile, name ? null, version ? null }:
pkgdef2drv (fromOPAM opamFile // { inherit name version; });

splitNameVer = nameVer:
let nv = nameVerToValuePair nameVer;
in { inherit (nv) name version; };

nameVerToValuePair = nameVer:
let split = splitString "." nameVer;
in nameValuePair (head split) (concatStringsSep "." (tail split));

ops = {
eq = "=";
gt = ">";
lt = "<";
geq = ">=";
leq = "<=";
neq = "!=";
};

global-variables = import ./global-variables.nix pkgs;

opamListToQuery = list: listToAttrs (map nameVerToValuePair list);

opamList = repos: packages:
let
opam-root = pkgs.runCommand "opamroot" {
nativeBuildInputs = [ pkgs.opam ];
OPAMNO = "true";
} ''
export OPAMROOT=$out
mkdir -p $NIX_BUILD_TOP/repos
${concatStringsSep "\n" (attrValues (mapAttrs (name: repo:
"cp -R --no-preserve=all ${repo} $NIX_BUILD_TOP/repos/${name}")
repos))}
opam init --bare default $NIX_BUILD_TOP/repos/default --disable-sandboxing --disable-completion -n --bypass-checks
${concatStringsSep "\n" (attrValues (mapAttrs (name: repo:
"opam repository add --set-default ${name} $NIX_BUILD_TOP/repos/${name}")
(lib.filterAttrs (name: _: name != "default") repos)))}
'';

pkgRequest = name: version:
if isNull version then name else "${name}.${version}";

resolve-drv = pkgs.runCommand "resolve" {
nativeBuildInputs = [ pkgs.opam ];
OPAMNO = "true";
OPAMCLI = "2.0";
} ''
export OPAMROOT=$NIX_BUILD_TOP/opam
cp -R --no-preserve=all ${opam-root} $OPAMROOT
opam list --resolve=${
concatStringsSep "," (attrValues (mapAttrs pkgRequest packages))
} --no-switch --short --with-test --depopts --columns=package > $out
'';
solution = fileContents resolve-drv;

lines = s: splitString "\n" s;

in lines solution;

makeOpamRepo = dir:
let
files = readDirRecursive dir;
opamFiles = filterAttrsRecursive
(name: value: isAttrs value || hasSuffix "opam" name) files;
opamFilesOnly =
converge (filterAttrsRecursive (_: v: v != { })) opamFiles;
packages = collect isList (mapAttrsRecursive (path: _:
let
fileName = lib.last path;
dirName = lib.last (lib.init path);
# We try to avoid reading this opam file if possible
name = if fileName == "opam" then
(fromOPAM "${dir + ("/" + concatStringsSep "/" path)}").name or dirName
else
lib.removeSuffix ".opam" (lib.last path);

in [
{
name = "sources/${name}/${name}.local";
path = "${dir + ("/" + concatStringsSep "/" (lib.init path))}";
}
{
name = "packages/${name}/${name}.local/opam";
path = "${dir + ("/" + concatStringsSep "/" path)}";
}
]) opamFilesOnly);
repo-description = {
name = "repo";
path = toFile "repo" ''opam-version: "2.0"'';
};
repo = pkgs.linkFarm "opam-repo"
([ repo-description ] ++ concatLists packages);
in repo;

queryToDefs = repos: packages:
let
# default has the lowest prio
repos' = (attrValues (filterAttrs (name: _: name != "default") repos))
++ [ repos.default ];

findPackage = name: version:
head (filter ({ opamFile, ... }: pathExists opamFile) (map (repo:
let
sourcePath = "${repo}/sources/${name}/${name}.local";
isLocal = pathExists sourcePath;
pkgDir = "${repo}/packages/${name}/${name}.${version}";
filesPath = "${pkgDir}/files";
in {
opamFile = "${pkgDir}/opam";
inherit name version isLocal repo;
src = if isLocal then
pkgs.runCommand "source-copy" { }
"cp --no-preserve=all -R ${sourcePath}/ $out"
else
pkgs.emptyDirectory;
} // optionalAttrs (pathExists filesPath) { files = filesPath; })
repos'));

packageFiles = mapAttrs findPackage packages;
in mapAttrs
(_: { opamFile, name, version, ... }@args: args // (fromOPAM opamFile))
packageFiles;

queryToDefs' = repos: packages:
let
# default has the lowest prio
repos' = (attrValues (filterAttrs (name: _: name != "default") repos))
++ [ repos.default ];

findPackage = name: version:
head (filter ({ dir, ... }: pathExists dir) (map (repo: {
dir = "${repo}/packages/${name}/${name}.${version}";
inherit name version;
src = repo.passthru.origSrc or pkgs.emptyDirectory;
}) repos'));

packageFiles = mapAttrs (_:
{ dir, name, version, src }:
{
inherit name version src;
opamFile = "${dir}/opam";
} // optionalAttrs (pathExists "${dir}/files") {
files = "${dir}/files";
}) (mapAttrs findPackage packages);

readPackageFiles = ''
(
echo '['
${concatMapStringsSep ''
echo ','
'' ({ opamFile, name, version, src, files ? null }:
''
opam2json ${opamFile} | jq '.name = "${name}" | .version = "${version}" | .opamFile = "${opamFile}" | .src = "${src}"${
lib.optionalString (!isNull files) ''| .files = "${files}"''
}' '') (attrValues packageFiles)}
echo ']'
) > $out
'';

pkgdefs = pkgs.runCommand "opam2json-many.json" {
nativeBuildInputs = [ opam2json pkgs.jq ];
} readPackageFiles;

listToAttrsByName = lst:
listToAttrs (map (x: nameValuePair x.name x) lst);
in listToAttrsByName (fromJSON (readFile pkgdefs));

defsToScope = repos: pkgs: packages:
makeScope pkgs.newScope (self:
(mapAttrs (name: pkg: self.callPackage (pkgdef2drv pkg) { }) packages)
// (import ./bootstrapPackages.nix pkgs
packages.ocaml.version or packages.ocaml-base-compiler.version));

defaultOverlay = import ./overlay.nix;

applyOverlays = overlays: scope:
scope.overrideScope' (composeManyExtensions overlays);

queryToScope = { repos, pkgs, overlays ? [ defaultOverlay ] }:
query:
pipe query [
(opamList repos)
(opamListToQuery)
(queryToDefs repos)
(defsToScope repos pkgs)
(applyOverlays overlays)
];

opamImport = { repos, pkgs }:
export:
let
installedList = (fromOPAM export).installed;
set = pipe installedList [
opamListToQuery
(queryToDefs repos)
(defsToScope repos pkgs)
];
installedPackageNames = map (x: (splitNameVer x).name) installedList;
combined = pkgs.symlinkJoin {
name = "opam-switch";
paths = attrValues (lib.getAttrs installedPackageNames set);
};
in combined;
}
(import (let lock = builtins.fromJSON (builtins.readFile ./flake.lock);
in fetchTarball {
url =
"https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}) { src = ./.; }).defaultNix
8 changes: 5 additions & 3 deletions examples/0install.nix
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
inputs:
pkgs:
let
pkgs = import <nixpkgs> { };
opam-nix = import ../. pkgs;
opam-nix = inputs.self.lib.${pkgs.system};

repos = {
default = pkgs.fetchFromGitHub (pkgs.lib.importJSON ./opam-repository.json);
default = inputs.opam-repository;
};
scope = opam-nix.queryToScope { inherit repos pkgs; } {
"0install" = null;
Expand Down
8 changes: 8 additions & 0 deletions examples/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
inputs: pkgs:
{
inherit (import ./0install.nix inputs pkgs) "0install";
inherit (import ./frama-c.nix inputs pkgs) frama-c;
inherit (import ./mina.nix inputs pkgs) mina;
inherit (import ./opam2json.nix inputs pkgs) opam2json;
inherit (import ./tezos.nix inputs pkgs) tezos;
}
8 changes: 5 additions & 3 deletions examples/frama-c.nix
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
inputs:
pkgs:
let
pkgs = import <nixpkgs> { };
opam-nix = import ../. pkgs;
opam-nix = inputs.self.lib.${pkgs.system};

repos = {
default = pkgs.fetchFromGitHub (pkgs.lib.importJSON ./opam-repository.json);
default = inputs.opam-repository;
};
scope = opam-nix.queryToScope { inherit repos pkgs; } {
frama-c = null;
Expand Down
16 changes: 10 additions & 6 deletions examples/mina.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
inputs:
pkgs:
let
pkgs = import <nixpkgs> { };
opam-nix = import ../. pkgs;
opam-nix = inputs.self.lib.${pkgs.system};

mina = pkgs.fetchFromGitHub {
owner = "minaprotocol";
Expand All @@ -11,7 +12,7 @@ let
};
repos = {
default = pkgs.runCommand "opam-repository-depext-fix" {
src = pkgs.fetchFromGitHub (pkgs.lib.importJSON ./opam-repository.json);
src = inputs.opam-repository;
} ''
cp --no-preserve=all -R $src $out
sed 's/available: .*//' -i $out/packages/depext/depext.transition/opam
Expand Down Expand Up @@ -77,10 +78,13 @@ let
version = "dev";
src = mina;
buildInputs = unique' (deps ++ propagatedExternalBuildInputs);
nativeBuildInputs = [ self.dune self.ocamlfind ];
nativeBuildInputs = [ self.dune self.ocamlfind pkgs.cargo pkgs.rustc ];

buildPhase =
"dune build src/app/logproc/logproc.exe src/app/cli/src/mina.exe";
buildPhase = ''
sed 's/mina_version.normal/mina_version.dummy/' -i src/lib/mina_version/dune
sed 's,/usr/local/lib/librocksdb_coda.a,${pkgs.rocksdb}/lib/librocksdb.a,' -i src/external/ocaml-rocksdb/dune
dune build src/app/logproc/logproc.exe src/app/cli/src/mina.exe
'';
installPhase = ''
mkdir -p $out/bin
mv src/app/logproc/logproc.exe src/app/cli/src/mina.exe $out/bin
Expand Down
7 changes: 0 additions & 7 deletions examples/opam-repository.json

This file was deleted.

10 changes: 5 additions & 5 deletions examples/opam2json.nix
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
inputs:
pkgs:
let
pkgs = import <nixpkgs> { };
opam-nix = import ../. pkgs;
opam-nix = inputs.self.lib.${pkgs.system};
repos = {
default = pkgs.fetchFromGitHub (pkgs.lib.importJSON ./opam-repository.json);
# Only uses the source, not the derivation itself
opam2json = opam-nix.makeOpamRepo (pkgs.ocamlPackages.callPackage ../opam2json.nix {}).src;
default = inputs.opam-repository;
opam2json = opam-nix.makeOpamRepo inputs.opam2json;
};
scope = opam-nix.queryToScope { inherit repos pkgs; } {
opam2json = null;
Expand Down
13 changes: 5 additions & 8 deletions examples/tezos.nix
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
inputs:
pkgs:
let
pkgs = import <nixpkgs> { };
opam-nix = import ../. pkgs;
opam-nix = inputs.self.lib.${pkgs.system};
repos = {
default = pkgs.fetchFromGitHub (pkgs.lib.importJSON ./opam-repository.json);
default = inputs.opam-repository;

tezos = opam-nix.makeOpamRepo (pkgs.fetchgit {
url = "https://gitlab.com/tezos/tezos.git";
rev = "7a8c3312f7f02d8c143164352ce8564f856ddcd5"; # v12.0-rc1
sha256 = "sha256-1/u8tWP0yuB0omCq54Lfp+Rkr/IUUV21RjUt7hGdU+8=";
});
tezos = opam-nix.makeOpamRepo inputs.tezos;
};
scope = opam-nix.queryToScope { inherit repos pkgs; } {
tezos = null;
Expand Down
Loading

0 comments on commit d4df438

Please sign in to comment.