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

Make package file discovery more robust

This commit is contained in:
Nicolas Mattia 2019-02-27 20:34:47 +01:00
parent f09f33fed4
commit c2129fa221
8 changed files with 88 additions and 37 deletions

View File

@ -16,9 +16,10 @@ with (callPackage ./lib.nix {});
with (callPackage ./modules.nix {});
with (callPackage ./module-spec.nix {});
with (callPackage ./package-spec.nix {});
with (callPackage ./hpack.nix {});
let
with rec
{
hpack = callPackage ./hpack.nix { inherit pkgDescriptionsFromPath; };
# Derivation that creates a binary in a 'bin' folder.
executable = packageFile:
@ -119,31 +120,66 @@ let
in modSpecs.${mainModName};
in mainModSpec;
# Get a list of package specs from a file (.nix or .yaml)
specsFromPackageFile = packageFile:
let
basename = builtins.baseNameOf packageFile;
components = pkgs.lib.strings.splitString "." basename;
ext =
if pkgs.lib.length components <= 1
then abort ("File " ++ packageFile ++ " does not have an extension")
else pkgs.lib.last components;
fromNix = [(mkPackageSpec (import packageFile))];
fromHPack = builtins.map mkPackageSpec (pkgSpecsFromHPack packageFile);
specs =
# Get a list of package descriptions from a path
# This can be
# - a path, relative or absolute, to a directory that contains either a
# package.yaml or a package.nix
# - a path, relative or absolute, to a file with either .nix or .yaml or
# .yml extension
pkgDescriptionsFromPath =
with rec
{
pkgDescriptionsFromFile = packageFile:
with rec
{
basename = builtins.baseNameOf packageFile;
components = pkgs.lib.strings.splitString "." basename;
ext =
if pkgs.lib.length components <= 1
then abort ("File " ++ packageFile ++ " does not have an extension")
else pkgs.lib.last components;
fromNix = [(import packageFile)];
fromHPack = hpack.pkgDescriptionsFromHPack packageFile;
};
if ext == "nix" then fromNix
else if ext == "yaml" then fromHPack
else if ext == "yml" then fromHPack
else abort ("Unknown extension " ++ ext ++ " of file " ++ packageFile);
in specs;
else abort ("Unknown extension " ++ ext ++ " of file " ++ packagePath);
pkgDescriptionsFromDir = packageDir:
with rec
{ dirContent = builtins.readDir packageDir;
hasPackageYaml = builtins.hasAttr "package.yaml" dirContent;
hasPackageNix = builtins.hasAttr "package.nix" dirContent;
};
if hasPackageYaml && hasPackageNix
then abort "Found both package.yaml and package.nix in ${packageDir}"
else if ! (hasPackageYaml || hasPackageNix)
then abort "Couldn't find package.yaml or package.nix in ${packageDir}"
else if hasPackageYaml
then pkgDescriptionsFromFile
"${builtins.toString packageDir}/package.yaml"
else pkgDescriptionsFromFile
"${builtins.toString packageDir}/package.nix";
};
in
{
inherit
inferBuild
inferGhci
buildAsExecutable
buildAsLibrary
executable
;
}
packagePath:
with { pathType = pkgs.lib.pathType packagePath ; } ;
if pathType == "directory"
then pkgDescriptionsFromDir packagePath
else if pathType == "regular"
then pkgDescriptionsFromFile packagePath
else abort "Don't know how to load package path of type ${pathType}";
specsFromPackageFile = packagePath:
map mkPackageSpec (pkgDescriptionsFromPath packagePath);
};
{
inherit
inferBuild
inferGhci
buildAsExecutable
buildAsLibrary
executable
;
}

View File

@ -1,4 +1,11 @@
{ lib, glibcLocales, callPackage, writeText, runCommand, haskellPackages }:
{ lib
, glibcLocales
, callPackage
, writeText
, runCommand
, haskellPackages
, pkgDescriptionsFromPath
}:
with (callPackage ./lib.nix {});
with (callPackage ./modules.nix {});
@ -22,10 +29,7 @@ let
in builtins.fromJSON json;
in rec
{
# Returns an attribute set with two fields:
# - library: a package spec
# - executable: an attr set of executable name to package spec
pkgSpecsFromHPack = packageYaml:
pkgDescriptionsFromHPack = packageYaml:
let
package = fromYAML (builtins.readFile packageYaml);
base = builtins.dirOf packageYaml;
@ -70,11 +74,10 @@ in rec
# 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")
( pkgDescriptionsFromPath
("${builtins.toString base}/${x}")
)
)
]

View File

@ -1,3 +1,4 @@
import Lib (fromLib)
import Lib2 (fromLib2)
main = putStrLn fromLib
main = putStrLn (fromLib <> fromLib2)

View File

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

View File

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

View File

@ -0,0 +1,4 @@
module Lib2 (fromLib2) where
fromLib2 :: String
fromLib2 = "lo"

View File

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

View File

@ -4,3 +4,4 @@ executable:
main: Main.hs
dependencies:
- ./lib
- ./lib2/package.yaml