mirror of
https://github.com/nmattia/snack.git
synced 2024-11-13 00:58:00 +03:00
Split library
This commit is contained in:
parent
97de9631c7
commit
ae46edcc9f
@ -1,11 +1,5 @@
|
|||||||
# TODO: currently single out derivations prepend the PWD to the path
|
# TODO: currently single out derivations prepend the PWD to the path
|
||||||
# TODO: commented out modules (-- Foo.Module) aren't parsed properly
|
|
||||||
# TODO: make dependecies on GHC per-module if possible
|
|
||||||
# TODO: there are too many "does file exist"
|
|
||||||
# TODO: make sure that filters for "base" are airtight
|
# TODO: make sure that filters for "base" are airtight
|
||||||
# TODO: use --make everywhere ?!? NOTE: this is tricky because GHC flags
|
|
||||||
# change: when a module is built with its dependencies, the flags for the
|
|
||||||
# dependencies change as well, which causes them to be recompiled
|
|
||||||
{ lib
|
{ lib
|
||||||
, haskellPackages
|
, haskellPackages
|
||||||
, makeWrapper
|
, makeWrapper
|
||||||
@ -14,43 +8,15 @@
|
|||||||
, symlinkJoin
|
, symlinkJoin
|
||||||
, writeScript
|
, writeScript
|
||||||
, runCommand
|
, runCommand
|
||||||
|
, callPackage
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
with (callPackage ./files.nix {});
|
||||||
|
|
||||||
|
# why is "inherit" needed?
|
||||||
|
with (callPackage ./modules.nix { inherit singleOut; });
|
||||||
|
|
||||||
let
|
let
|
||||||
# Takes a (string) filepath and creates a derivation for that file (and for
|
|
||||||
# that file only)
|
|
||||||
singleOut = base: file:
|
|
||||||
let
|
|
||||||
basePrefix = (builtins.toString base) + "/";
|
|
||||||
pred = file: path: type:
|
|
||||||
let
|
|
||||||
actual = (lib.strings.removePrefix basePrefix path);
|
|
||||||
expected = file;
|
|
||||||
in
|
|
||||||
(expected == actual) ||
|
|
||||||
(type == "directory" && (lib.strings.hasPrefix actual expected));
|
|
||||||
mod = fileToModule file;
|
|
||||||
# TODO: even though we're doing a lot of cleaning, there's sitll some
|
|
||||||
# 'does-file-exist' happening
|
|
||||||
src0 = lib.cleanSource base;
|
|
||||||
|
|
||||||
in stdenv.mkDerivation {
|
|
||||||
name = mod;
|
|
||||||
src = lib.cleanSourceWith { filter = (pred file); src = src0; };
|
|
||||||
builder = 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
|
|
||||||
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})"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
makeModuleSpec = modName: deps: isMain: modFiles: modDirs:
|
makeModuleSpec = modName: deps: isMain: modFiles: modDirs:
|
||||||
{ moduleName = modName;
|
{ moduleName = modName;
|
||||||
moduleIsMain = isMain;
|
moduleIsMain = isMain;
|
||||||
@ -59,22 +25,6 @@ let
|
|||||||
moduleDirectories = modDirs;
|
moduleDirectories = modDirs;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Turns a module name to a file
|
|
||||||
moduleToFile = mod:
|
|
||||||
(lib.strings.replaceChars ["."] ["/"] mod) + ".hs";
|
|
||||||
|
|
||||||
moduleToObject = mod:
|
|
||||||
(lib.strings.replaceChars ["."] ["/"] mod) + ".o";
|
|
||||||
|
|
||||||
fileToModule = file:
|
|
||||||
lib.strings.removeSuffix ".hs"
|
|
||||||
(lib.strings.replaceChars ["/"] ["."] file);
|
|
||||||
|
|
||||||
singleOutModule = base: mod: singleOut base (moduleToFile mod);
|
|
||||||
|
|
||||||
singleOutModulePath = base: mod:
|
|
||||||
"${singleOut base (moduleToFile mod)}/${moduleToFile mod}";
|
|
||||||
|
|
||||||
# Create a module spec by following the dependencies. This assumes that the
|
# Create a module spec by following the dependencies. This assumes that the
|
||||||
# specified module is a "Main" module.
|
# specified module is a "Main" module.
|
||||||
makeModuleSpecRec = baseByModuleName: filesByModuleName: dirsByModuleName:
|
makeModuleSpecRec = baseByModuleName: filesByModuleName: dirsByModuleName:
|
||||||
@ -170,27 +120,8 @@ let
|
|||||||
(builtins.readFile (listAllModuleDependenciesJSON (baseByModuleName modName) modName))
|
(builtins.readFile (listAllModuleDependenciesJSON (baseByModuleName modName) modName))
|
||||||
);
|
);
|
||||||
|
|
||||||
doesFileExist = base: filename:
|
|
||||||
lib.lists.elem filename (listFilesInDir base);
|
|
||||||
|
|
||||||
listModulesInDir = dir: map fileToModule (listFilesInDir dir);
|
listModulesInDir = dir: map fileToModule (listFilesInDir dir);
|
||||||
|
|
||||||
listFilesInDir = dir:
|
|
||||||
let
|
|
||||||
go = dir: dirName:
|
|
||||||
lib.lists.concatLists
|
|
||||||
(
|
|
||||||
lib.attrsets.mapAttrsToList
|
|
||||||
(path: ty:
|
|
||||||
if ty == "directory"
|
|
||||||
then
|
|
||||||
go "${dir}/${path}" "${dirName}${path}/"
|
|
||||||
else
|
|
||||||
[ "${dirName}${path}" ]
|
|
||||||
)
|
|
||||||
(builtins.readDir dir)
|
|
||||||
);
|
|
||||||
in go dir "";
|
|
||||||
|
|
||||||
doesModuleExist = baseByModuleName: modName:
|
doesModuleExist = baseByModuleName: modName:
|
||||||
doesFileExist (baseByModuleName modName) (moduleToFile modName);
|
doesFileExist (baseByModuleName modName) (moduleToFile modName);
|
||||||
|
62
snack-lib/files.nix
Normal file
62
snack-lib/files.nix
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# file related operations
|
||||||
|
{ lib
|
||||||
|
, stdenv
|
||||||
|
, writeScript
|
||||||
|
}:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
# Takes a (string) filepath and creates a derivation for that file (and for
|
||||||
|
# that file only)
|
||||||
|
singleOut = base: file:
|
||||||
|
let
|
||||||
|
basePrefix = (builtins.toString base) + "/";
|
||||||
|
pred = file: path: type:
|
||||||
|
let
|
||||||
|
actual = (lib.strings.removePrefix basePrefix path);
|
||||||
|
expected = file;
|
||||||
|
in
|
||||||
|
(expected == actual) ||
|
||||||
|
(type == "directory" && (lib.strings.hasPrefix actual expected));
|
||||||
|
# TODO: even though we're doing a lot of cleaning, there's sitll some
|
||||||
|
# 'does-file-exist' happening
|
||||||
|
src0 = lib.cleanSource base;
|
||||||
|
|
||||||
|
in stdenv.mkDerivation {
|
||||||
|
name = file;
|
||||||
|
src = lib.cleanSourceWith { filter = (pred file); src = src0; };
|
||||||
|
builder = writeScript (file + "-single-out")
|
||||||
|
# TODO: make sure the file actually exists and that there's only one
|
||||||
|
''
|
||||||
|
echo "Singling out file ${file}"
|
||||||
|
source $stdenv/setup
|
||||||
|
mkdir -p $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 file ${file}"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
doesFileExist = base: filename:
|
||||||
|
lib.lists.elem filename (listFilesInDir base);
|
||||||
|
|
||||||
|
listFilesInDir = dir:
|
||||||
|
let
|
||||||
|
go = dir: dirName:
|
||||||
|
lib.lists.concatLists
|
||||||
|
(
|
||||||
|
lib.attrsets.mapAttrsToList
|
||||||
|
(path: ty:
|
||||||
|
if ty == "directory"
|
||||||
|
then
|
||||||
|
go "${dir}/${path}" "${dirName}${path}/"
|
||||||
|
else
|
||||||
|
[ "${dirName}${path}" ]
|
||||||
|
)
|
||||||
|
(builtins.readDir dir)
|
||||||
|
);
|
||||||
|
in go dir "";
|
||||||
|
}
|
26
snack-lib/modules.nix
Normal file
26
snack-lib/modules.nix
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# module related operations
|
||||||
|
{ lib
|
||||||
|
, singleOut
|
||||||
|
}:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
# Turns a module name to a file
|
||||||
|
moduleToFile = mod:
|
||||||
|
(lib.strings.replaceChars ["."] ["/"] mod) + ".hs";
|
||||||
|
|
||||||
|
# Turns a module name into the filepath of its object file
|
||||||
|
moduleToObject = mod:
|
||||||
|
(lib.strings.replaceChars ["."] ["/"] mod) + ".o";
|
||||||
|
|
||||||
|
# Turns a filepath name to a module name
|
||||||
|
fileToModule = file:
|
||||||
|
lib.strings.removeSuffix ".hs"
|
||||||
|
(lib.strings.replaceChars ["/"] ["."] file);
|
||||||
|
|
||||||
|
# Singles out a given module (by module name) (derivation)
|
||||||
|
singleOutModule = base: mod: singleOut base (moduleToFile mod);
|
||||||
|
|
||||||
|
# Singles out a given module (by module name) (path to module file)
|
||||||
|
singleOutModulePath = base: mod:
|
||||||
|
"${singleOut base (moduleToFile mod)}/${moduleToFile mod}";
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user