Revamp 'outputs' (#102)

This commit is contained in:
Sridhar Ratnakumar 2023-03-02 14:15:39 -05:00 committed by GitHub
parent fc8f69f8b3
commit 9e2f7f159a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 56 deletions

View File

@ -4,6 +4,7 @@
- New features
- #63: Add `config.haskellProjects.${name}.outputs` containing all flake outputs for that project.
- #102 In addition, `outputs` contains `finalPackages` and `localPackages`.
- #49 & #91: The `packages` option now autodiscovers the top-level `.cabal` file (in addition to looking inside sub-directories) as its default value.
- #69: The default flake template creates `flake.nix` only, while the `#example` one creates the full Haskell project template.
- #92: Add `devShell.mkShellArgs` to pass custom arguments to `mkShell`

View File

@ -86,6 +86,48 @@ in
};
};
};
outputsSubmodule = types.submodule {
options = {
finalOverlay = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
finalPackages = mkOption {
# This must be raw because the Haskell package set also contains functions.
type = types.attrsOf types.raw;
readOnly = true;
description = ''
The final Haskell package set including local packages and any
overrides, on top of `basePackages`.
'';
};
localPackages = mkOption {
type = types.attrsOf types.package;
readOnly = true;
description = ''
The local Haskell packages in the project.
This is a subset of `finalPackages` containing only local
packages excluding everything else.
'';
};
devShell = mkOption {
type = types.package;
readOnly = true;
description = ''
The development shell derivation generated for this project.
'';
};
hlsCheck = mkOption {
type = types.package;
readOnly = true;
description = ''
The `hlsCheck` derivation generated for this project.
'';
};
};
};
projectSubmodule = types.submoduleWith {
specialArgs = { inherit pkgs self; };
modules = [
@ -163,7 +205,7 @@ in
default = { };
};
outputs = mkOption {
type = types.attrsOf types.raw;
type = outputsSubmodule;
description = ''
The flake outputs generated for this project.
@ -171,21 +213,7 @@ in
'';
};
# Derived options
finalPackages = mkOption {
type = types.attrsOf raw;
readOnly = true;
description = ''
The final package set, based on `basePackages` plus
the additions and overrides specified in the other options.
'';
};
finalOverlay = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
};
}
];
@ -215,16 +243,32 @@ in
in
{
packages =
mergeMapAttrs (_: project: project.outputs.packages) config.haskellProjects;
mergeMapAttrs
(name: project:
let
mapKeys = f: attrs: lib.mapAttrs' (n: v: { name = f n; value = v; }) attrs;
# Prefix package names with the project name (unless
# project is named `default`)
dropDefaultPrefix = packageName:
if name == "default"
then packageName
else "${name}-${packageName}";
in
mapKeys dropDefaultPrefix project.outputs.localPackages)
config.haskellProjects;
devShells =
mergeMapAttrs
(_: project:
lib.optionalAttrs project.devShell.enable project.outputs.devShells)
(name: project:
lib.optionalAttrs project.devShell.enable {
"${name}" = project.outputs.devShell;
})
config.haskellProjects;
checks =
mergeMapAttrs
(_: project:
lib.optionalAttrs project.devShell.enable project.outputs.checks)
(name: project:
lib.optionalAttrs (project.devShell.enable && project.devShell.hlsCheck.enable) {
"${name}-hls" = project.outputs.hlsCheck;
})
config.haskellProjects;
};
});

View File

@ -28,7 +28,7 @@ in
config =
let
inherit (config) finalPackages;
inherit (config.outputs) finalPackages finalOverlay;
projectKey = name;
@ -86,44 +86,31 @@ in
});
in
{
finalPackages = config.basePackages.extend config.finalOverlay;
finalOverlay = lib.composeManyExtensions [
# The order here matters.
#
# User's overrides (cfg.overrides) is applied **last** so
# as to give them maximum control over the final package
# set used.
localPackagesOverlay
(pkgs.haskell.lib.packageSourceOverrides config.source-overrides)
config.overrides
];
outputs = {
packages =
let
mapKeys = f: attrs: lib.mapAttrs' (n: v: { name = f n; value = v; }) attrs;
# Prefix package names with the project name (unless
# project is named `default`)
dropDefaultPrefix = packageName:
if projectKey == "default"
then packageName
else "${projectKey}-${packageName}";
in
mapKeys dropDefaultPrefix
(lib.mapAttrs
(name: _: finalPackages."${name}")
config.packages);
inherit devShell;
devShells."${projectKey}" = devShell;
finalOverlay = lib.composeManyExtensions [
# The order here matters.
#
# User's overrides (cfg.overrides) is applied **last** so
# as to give them maximum control over the final package
# set used.
localPackagesOverlay
(pkgs.haskell.lib.packageSourceOverrides config.source-overrides)
config.overrides
];
finalPackages = config.basePackages.extend finalOverlay;
localPackages = lib.mapAttrs
(name: _: finalPackages."${name}")
config.packages;
hlsCheck = runCommandInSimulatedShell
devShell
self "${projectKey}-hls-check"
{ } "haskell-language-server";
checks = lib.optionalAttrs config.devShell.hlsCheck.enable {
"${projectKey}-hls" =
runCommandInSimulatedShell
devShell
self "${projectKey}-hls-check"
{ } "haskell-language-server";
};
};
};
}