mirror of
https://github.com/nmattia/snack.git
synced 2024-10-26 04:29:51 +03:00
Add support for nested modules
This commit is contained in:
parent
51987daf76
commit
1000fc9a1a
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
**/result
|
11
nix/default.nix
Normal file
11
nix/default.nix
Normal file
@ -0,0 +1,11 @@
|
||||
{ nixpkgs ? ./nixpkgs }:
|
||||
import (import nixpkgs) {
|
||||
config = { allowUnfree = true; };
|
||||
overlays = [
|
||||
(self: super: { snack-lib = import ../snack;} )
|
||||
(self: super: { snack = self.writeScriptBin "snack"
|
||||
''
|
||||
${self.nix}/bin/nix-build snack.nix
|
||||
''; })
|
||||
];
|
||||
}
|
6
nix/nixpkgs/default.nix
Normal file
6
nix/nixpkgs/default.nix
Normal file
@ -0,0 +1,6 @@
|
||||
let
|
||||
spec = builtins.fromJSON (builtins.readFile ./nixpkgs-src.json);
|
||||
rev = spec.rev;
|
||||
url = "https://github.com/${spec.owner}/${spec.repo}/archive/${spec.rev}.tar.gz";
|
||||
in
|
||||
builtins.fetchTarball url
|
@ -5,8 +5,6 @@
|
||||
# See https://gist.github.com/zimbatm/de5350245874361762b6a4dfe5366530
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
|
||||
branch=master
|
||||
|
||||
owner=NixOS
|
||||
@ -16,7 +14,7 @@ url=https://github.com/$owner/$repo/archive/$rev.tar.gz
|
||||
|
||||
release_sha256=$(nix-prefetch-url --unpack "$url")
|
||||
|
||||
cat <<NIXPKGS | tee src.json
|
||||
cat <<NIXPKGS | tee nix/nixpkgs/nixpkgs-src.json
|
||||
{
|
||||
"owner": "$owner",
|
||||
"repo": "$repo",
|
||||
|
16
script/test
Executable file
16
script/test
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash
|
||||
#!nix-shell -I nixpkgs=./nix
|
||||
#!nix-shell -p snack
|
||||
#!nix-shell --pure
|
||||
# vim: ft=sh sw=2 et
|
||||
|
||||
set -eux
|
||||
|
||||
pushd tests/flat
|
||||
snack build
|
||||
popd
|
||||
|
||||
pushd tests/nested
|
||||
snack build
|
||||
popd
|
@ -1,8 +1,7 @@
|
||||
# TODO: currently single out derivations append the PWD
|
||||
let
|
||||
# Use pinned packages
|
||||
_nixpkgs = import <nixpkgs> {};
|
||||
nixpkgs = _nixpkgs.fetchFromGitHub (_nixpkgs.lib.importJSON ./nix/src.json);
|
||||
pkgs = import nixpkgs {config={}; overlays=[];};
|
||||
pkgs = import (../nix) {};
|
||||
|
||||
# Takes a (string) filepath and creates a derivation for that file (and for
|
||||
# that file only)
|
||||
@ -13,17 +12,26 @@ let
|
||||
topLevel = (builtins.toString base) + "/";
|
||||
actual = (pkgs.lib.strings.removePrefix topLevel path);
|
||||
expected = file;
|
||||
in expected == actual;
|
||||
in
|
||||
(expected == actual) ||
|
||||
(type == "directory" && (pkgs.lib.strings.hasPrefix actual expected));
|
||||
mod = fileToModule file;
|
||||
|
||||
in pkgs.stdenv.mkDerivation {
|
||||
name = file;
|
||||
name = mod;
|
||||
src = builtins.filterSource (pred file) base;
|
||||
builder = pkgs.writeScript (file + "-builder")
|
||||
builder = pkgs.writeScript (mod + "-builder")
|
||||
# TODO: make sure the file actually exists and that there's only one
|
||||
''
|
||||
echo "Singling out module ${mod} (file is ${file})"
|
||||
source $stdenv/setup
|
||||
mkdir -p $out
|
||||
cp -a $src/* $out/
|
||||
echo "Running: cp $src/${file} $out/${file}"
|
||||
echo "Listing $src"
|
||||
ls $src/**/*
|
||||
mkdir -p $(dirname $out/${file})
|
||||
cp $src/${file} $out/${file}
|
||||
echo "Done: Singling out module ${mod} (file is ${file})"
|
||||
'';
|
||||
};
|
||||
|
||||
@ -36,6 +44,13 @@ let
|
||||
moduleToFile = mod:
|
||||
(pkgs.lib.strings.replaceChars ["."] ["/"] mod) + ".hs";
|
||||
|
||||
moduleToObject = mod:
|
||||
(pkgs.lib.strings.replaceChars ["."] ["/"] mod) + ".o";
|
||||
|
||||
fileToModule = file:
|
||||
pkgs.lib.strings.removeSuffix ".hs"
|
||||
(pkgs.lib.strings.replaceChars ["/"] ["."] file);
|
||||
|
||||
singleOutModule = base: mod: singleOut base (moduleToFile mod);
|
||||
|
||||
buildModule = base: mod:
|
||||
@ -66,7 +81,7 @@ let
|
||||
echo "Compiling module ${mod.moduleName}"
|
||||
# Set a tmpdir we have control over, otherwise GHC fails, not sure why
|
||||
mkdir -p tmp
|
||||
ghc -tmpdir tmp/ ${mod.moduleName}.hs -c \
|
||||
ghc -tmpdir tmp/ ${moduleToFile mod.moduleName} -c \
|
||||
-outputdir $out \
|
||||
2>&1
|
||||
echo "Done building module ${mod.moduleName}"
|
||||
@ -84,16 +99,17 @@ let
|
||||
go = mod: attrs0:
|
||||
let
|
||||
objectName = x:
|
||||
# TODO: can't use "moduleName.o" because some modules get
|
||||
# renamed to "Main.o" :/
|
||||
# Also, hard coding the object file based on the module name feels
|
||||
# icky
|
||||
if x.moduleIsMain
|
||||
then "Main.o"
|
||||
else x.moduleName + ".o";
|
||||
else moduleToObject x.moduleName;
|
||||
attrs1 = f attrs0 mod;
|
||||
f = acc: elem:
|
||||
if pkgs.lib.attrsets.hasAttr elem.moduleName acc
|
||||
then acc
|
||||
# TODO: module path instead of module name
|
||||
# TODO: can't use "moduleName.o" because some modules get
|
||||
# renamed to "Main.o"
|
||||
else acc //
|
||||
{ "${elem.moduleName}" =
|
||||
"${buildModule base elem}/${objectName elem}";
|
||||
@ -120,8 +136,8 @@ let
|
||||
];
|
||||
};
|
||||
|
||||
# TODO: use ghc -M for module dependencies
|
||||
modB = makeModuleSpec "B" [] false;
|
||||
modA = makeModuleSpec "A" [modB] true;
|
||||
|
||||
in linkModuleObjects ./. modA
|
||||
## TODO: use ghc -M for module dependencies
|
||||
in
|
||||
{
|
||||
inherit linkModuleObjects makeModuleSpec;
|
||||
}
|
3
tests/flat/README.md
Normal file
3
tests/flat/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Flat
|
||||
|
||||
Makes sure that two modules, `A.hs` and `B.hs`, can be built into an executable
|
6
tests/flat/snack.nix
Normal file
6
tests/flat/snack.nix
Normal file
@ -0,0 +1,6 @@
|
||||
# This "snack" passing is ugly, figure out a nice way of passing snack-lib
|
||||
with (import ../../nix {}).snack-lib;
|
||||
let
|
||||
modB = makeModuleSpec "B" [] false;
|
||||
modA = makeModuleSpec "A" [modB] true;
|
||||
in linkModuleObjects ./. modA
|
3
tests/nested/Foo/A.hs
Normal file
3
tests/nested/Foo/A.hs
Normal file
@ -0,0 +1,3 @@
|
||||
import Foo.B.C
|
||||
|
||||
main = putStrLn var
|
3
tests/nested/Foo/B/C.hs
Normal file
3
tests/nested/Foo/B/C.hs
Normal file
@ -0,0 +1,3 @@
|
||||
module Foo.B.C where
|
||||
|
||||
var = "Hello, World!"
|
4
tests/nested/README.md
Normal file
4
tests/nested/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Nested
|
||||
|
||||
Make sure that nested modules (e.g. `Foo.A` and `Foo.B.C`) can be built into an
|
||||
executable
|
6
tests/nested/snack.nix
Normal file
6
tests/nested/snack.nix
Normal file
@ -0,0 +1,6 @@
|
||||
# This "snack" passing is ugly, figure out a nice way of passing snack-lib
|
||||
with (import ../../nix {}).snack-lib;
|
||||
let
|
||||
modB = makeModuleSpec "Foo.B.C" [] false;
|
||||
modA = makeModuleSpec "Foo.A" [modB] true;
|
||||
in linkModuleObjects ./. modA
|
Loading…
Reference in New Issue
Block a user