1
1
mirror of https://github.com/nmattia/snack.git synced 2024-08-16 07:10:57 +03:00

Support extra packages in yaml

This commit is contained in:
Nicolas Mattia 2019-02-26 23:37:52 +01:00
parent e8cef886cf
commit f09f33fed4
9 changed files with 89 additions and 43 deletions

View File

@ -20,7 +20,7 @@ let
"${y2j} ${writeText "y2j" text} > $out"
);
in builtins.fromJSON json;
in
in rec
{
# Returns an attribute set with two fields:
# - library: a package spec
@ -28,6 +28,19 @@ in
pkgSpecsFromHPack = packageYaml:
let
package = fromYAML (builtins.readFile packageYaml);
base = builtins.dirOf packageYaml;
commonAttrs = component:
{ ghcOpts = topGhcOpts ++ (optAttr component "ghc-options" []);
extensions = topExtensions ++ (optAttr component "extensions" []);
src =
with { source-dirs = optAttr component "source-dirs" "."; };
if builtins.isList source-dirs
then builtins.map (sourceDir:
builtins.toPath "${builtins.toString base}/${sourceDir}"
) source-dirs
else
builtins.toPath "${builtins.toString base}/${source-dirs}";
};
# Snack drops the version bounds because here it has no meaning
dropVersionBounds =
@ -37,51 +50,43 @@ in
topExtensions = optAttr package "default-extensions" [];
topGhcOpts = optAttr package "ghc-options" [];
libs = withAttr package "library" [] (component:
[{
src =
let
base = builtins.dirOf packageYaml;
source-dirs = optAttr component "source-dirs" ".";
in
if builtins.isList source-dirs
then builtins.map (sourceDir:
builtins.toPath "${builtins.toString base}/${sourceDir}"
) source-dirs
else
builtins.toPath "${builtins.toString base}/${source-dirs}";
dependencies = topDeps ++ mkDeps component;
extensions = topExtensions ++ (optAttr component "extensions" []);
ghcOpts = topGhcOpts ++ (optAttr component "ghc-options" []);
}]
[ (commonAttrs component //
{ dependencies = topDeps ++ mkDeps component; }
)
]
);
exes =
withAttr package "executables" [] (lib.mapAttrsToList (k: v: mkExe k v)) ++
withAttr package "executable" [] (comp: [(mkExe package.name comp)] );
mkExe = nn: component:
let
depOrPack =
lib.lists.partition
(x: x == package.name)
(optAttr component "dependencies" []);
in
{ main = fileToModule component.main;
name = nn;
src =
let
base = builtins.dirOf packageYaml;
source-dirs = optAttr component "source-dirs" ".";
in
if builtins.isList source-dirs
then builtins.map (sourceDir:
builtins.toPath "${builtins.toString base}/${sourceDir}"
) source-dirs
else
builtins.toPath "${builtins.toString base}/${source-dirs}";
dependencies = topDeps ++ dropVersionBounds depOrPack.wrong;
extensions = topExtensions ++ (optAttr component "extensions" []);
ghcOpts = topGhcOpts ++ (optAttr component "ghc-options" []);
packages = if lib.length depOrPack.right > 0 then libs else [];
};
with
{
depsAndPacks = lib.foldl
(acc: x:
if x == package.name then tap acc "packs" (ps: ps ++ libs)
else if lib.hasPrefix "./" x then tap acc "packs" (ps:
ps ++
# This is extremely brittle:
# - there could be more than one package
# - this needs to make sure it only picks libraries
# - it only works with "package.yaml"
[
(lib.head
( pkgSpecsFromHPack
("${builtins.toString base}/${x}/package.yaml")
)
)
]
)
else tap acc "deps" (ds: ds ++ [x])
) { deps = []; packs = []; } (optAttr component "dependencies" []);
};
commonAttrs component //
{ main = fileToModule component.main;
name = nn;
dependencies = topDeps ++ dropVersionBounds depsAndPacks.deps; # depOrPack.wrong;
packages = depsAndPacks.packs;
};
in exes ++ libs;
}

View File

@ -50,4 +50,6 @@ withAttr = obj: attrName: def: f:
optAttr = obj: attrName: def:
if builtins.hasAttr attrName obj then obj.${attrName} else def;
tap = obj: attrName: f: obj // { "${attrName}" = f (obj.${attrName}) ; };
}

View File

@ -1,4 +1,4 @@
name: snack-readme
name: any-paths
dependencies:
- lens
@ -11,7 +11,7 @@ executable:
main: Main.hs
source-dirs: ./app
dependencies:
- snack-readme
- any-paths
default-extensions:
- OverloadedStrings

3
tests/packages-2/Main.hs Normal file
View File

@ -0,0 +1,3 @@
import Lib (fromLib)
main = putStrLn fromLib

1
tests/packages-2/golden Normal file
View File

@ -0,0 +1 @@
hello

View File

@ -0,0 +1,4 @@
module Lib (fromLib) where
fromLib :: String
fromLib = "hello"

View File

@ -0,0 +1,6 @@
name: snack-packages-2
# NOTE: should not fail if library is empty
# For some reason, Nix returns null as opposed to {}
library:
source-dirs: .

View File

@ -0,0 +1,6 @@
name: snack-packages
executable:
main: Main.hs
dependencies:
- ./lib

19
tests/packages-2/test Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
# vim: ft=sh sw=2 et
set -euo pipefail
test() {
$SNACK build
$SNACK run | diff golden -
TMP_FILE=$(mktemp)
capture_io "$TMP_FILE" main | $SNACK ghci
diff golden $TMP_FILE
rm $TMP_FILE
}
SNACK="snack --package-file ./package.yaml" test