diff --git a/snack-lib/default.nix b/snack-lib/default.nix index fe7ec86..fc20899 100644 --- a/snack-lib/default.nix +++ b/snack-lib/default.nix @@ -40,7 +40,7 @@ let libraryModSpecs = pkgSpec: let moduleSpecFold' = modSpecFoldFromPackageSpec pkgSpec; - modNames = listModulesInDir pkgSpec.packageBase; + modNames = pkgs.lib.concatMap listModulesInDir pkgSpec.packageSourceDirs; fld = moduleSpecFold' modSpecs'; modSpecs' = foldDAG fld modNames; modSpecs = builtins.attrValues modSpecs'; diff --git a/snack-lib/hpack.nix b/snack-lib/hpack.nix index fa62816..9c1811f 100644 --- a/snack-lib/hpack.nix +++ b/snack-lib/hpack.nix @@ -37,7 +37,13 @@ in packageLib = withAttr package "library" null (component: { src = let base = builtins.dirOf packageYaml; - in builtins.toPath "${builtins.toString base}/${component.source-dirs}"; + in + if builtins.isList component.source-dirs + then builtins.map (sourceDir: + builtins.toPath "${builtins.toString base}/${sourceDir}" + ) component.source-dirs + else + builtins.toPath "${builtins.toString base}/${component.source-dirs}"; dependencies = topDeps ++ mkDeps component; extensions = topExtensions ++ (optAttr component "extensions" []); } @@ -55,9 +61,14 @@ in in { main = fileToModule component.main; src = - let - base = builtins.dirOf packageYaml; - in builtins.toPath "${builtins.toString base}/${component.source-dirs}"; + let base = builtins.dirOf packageYaml; + in + if builtins.isList component.source-dirs + then builtins.map (sourceDir: + builtins.toPath "${builtins.toString base}/${sourceDir}" + ) component.source-dirs + else + builtins.toPath "${builtins.toString base}/${component.source-dirs}"; dependencies = topDeps ++ dropVersionBounds depOrPack.wrong; extensions = topExtensions ++ (optAttr component "extensions" []); packages = map (_: packageLib) depOrPack.right; diff --git a/snack-lib/module-spec.nix b/snack-lib/module-spec.nix index aada6c5..b12b543 100644 --- a/snack-lib/module-spec.nix +++ b/snack-lib/module-spec.nix @@ -100,8 +100,8 @@ rec { modSpecFoldFromPackageSpec = pkgSpec: let baseByModuleName = modName: - let res = pkgSpecByModuleName pkgSpec null modName; - in if res == null then null else res.packageBase; + let res = pkgSpecAndBaseByModuleName pkgSpec modName; + in if res == null then null else res.base; depsByModuleName = modName: (pkgSpecByModuleName pkgSpec diff --git a/snack-lib/package-spec.nix b/snack-lib/package-spec.nix index 22f6d89..adb269f 100644 --- a/snack-lib/package-spec.nix +++ b/snack-lib/package-spec.nix @@ -18,7 +18,10 @@ rec { , packages ? [] }: { packageMain = main; - packageBase = src; + packageSourceDirs = + if builtins.isList src + then src + else [src]; packageGhcOpts = ghcOpts; packageExtensions = extensions; packageDependencies = mkPerModuleAttr dependencies; @@ -45,14 +48,25 @@ rec { # Traverses all transitive packages and returns the first package spec that # contains a module with given name. If none is found, returns the supplied # default value. - pkgSpecByModuleName = topPkgSpec: def: modName: - ( lib.findFirst + pkgSpecAndBaseByModuleName = topPkgSpec: modName: + let + foo = pkgSpec: + lib.findFirst + (base: lib.lists.elem modName (listModulesInDir base)) + null + pkgSpec.packageSourceDirs; + bar = lib.concatMap (pkgSpec: - lib.lists.elem - modName - (listModulesInDir pkgSpec.packageBase) - ) - def - (flattenPackages topPkgSpec) - ); + let base = foo pkgSpec; + in if base == null then [] else [ { inherit pkgSpec base; } ]) + (flattenPackages topPkgSpec); + in if lib.length bar <= 0 then null else + if lib.length bar == 1 then lib.head bar + else abort + "Refusing to return base, module name was found more than once: ${modName}"; + + pkgSpecByModuleName = topPkgSpec: def: modName: + let + res = pkgSpecAndBaseByModuleName topPkgSpec modName; + in if res == null then def else res.pkgSpec; }