mirror of
https://github.com/nmattia/snack.git
synced 2024-10-26 12:38:49 +03:00
Support extra packages in yaml
This commit is contained in:
parent
e8cef886cf
commit
f09f33fed4
@ -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
|
||||
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;
|
||||
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 [];
|
||||
dependencies = topDeps ++ dropVersionBounds depsAndPacks.deps; # depOrPack.wrong;
|
||||
packages = depsAndPacks.packs;
|
||||
};
|
||||
in exes ++ libs;
|
||||
}
|
||||
|
@ -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}) ; };
|
||||
|
||||
}
|
||||
|
@ -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
3
tests/packages-2/Main.hs
Normal file
@ -0,0 +1,3 @@
|
||||
import Lib (fromLib)
|
||||
|
||||
main = putStrLn fromLib
|
1
tests/packages-2/golden
Normal file
1
tests/packages-2/golden
Normal file
@ -0,0 +1 @@
|
||||
hello
|
4
tests/packages-2/lib/Lib.hs
Normal file
4
tests/packages-2/lib/Lib.hs
Normal file
@ -0,0 +1,4 @@
|
||||
module Lib (fromLib) where
|
||||
|
||||
fromLib :: String
|
||||
fromLib = "hello"
|
6
tests/packages-2/lib/package.yaml
Normal file
6
tests/packages-2/lib/package.yaml
Normal 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: .
|
6
tests/packages-2/package.yaml
Normal file
6
tests/packages-2/package.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
name: snack-packages
|
||||
|
||||
executable:
|
||||
main: Main.hs
|
||||
dependencies:
|
||||
- ./lib
|
19
tests/packages-2/test
Executable file
19
tests/packages-2/test
Executable 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
|
Loading…
Reference in New Issue
Block a user