From a13a3381382d12d62006befd916e6ee41a06b353 Mon Sep 17 00:00:00 2001 From: Greg Pfeil Date: Tue, 13 Jan 2026 10:26:54 -0700 Subject: [PATCH] Extract flake outputs to a separate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The outputs are the only part of the flake that are actually a Nix expression[^1]. This makes it easier to deal with that by pulling `outputs` into an actual Nix file. [^1]: Even that isn’t quite true – `outputs` isn’t an arbitrary function, but must syntactically have a single argument. That is, we can’t η-reduce `outputs` to get rid of the `inputs` argument. This also helps with reducing templating – because flake.nix isn’t a Nix expression and since Project Manager runs from the flake, flake.nix _must_ be part of the template. Extracting outputs makes it easier to see what can actually be removed, and reduces conflicts in flake.nix when the template is updated. --- .config/flake/outputs.nix | 80 +++++++ flake.nix | 83 +------- templates/bash/.config/flake/outputs.nix | 89 ++++++++ templates/bash/flake.nix | 92 +------- templates/c/.config/flake/outputs.nix | 94 +++++++++ templates/c/flake.nix | 97 +-------- templates/default/.config/flake/outputs.nix | 62 ++++++ templates/default/flake.nix | 65 +----- templates/dhall/.config/flake/outputs.nix | 75 +++++++ templates/dhall/flake.nix | 78 +------ .../emacs-lisp/.config/flake/outputs.nix | 77 +++++++ templates/emacs-lisp/flake.nix | 80 +------ templates/haskell/.config/flake/outputs.nix | 194 +++++++++++++++++ templates/haskell/flake.nix | 197 +----------------- templates/nix/.config/flake/outputs.nix | 63 ++++++ templates/nix/flake.nix | 66 +----- 16 files changed, 758 insertions(+), 734 deletions(-) create mode 100644 .config/flake/outputs.nix create mode 100644 templates/bash/.config/flake/outputs.nix create mode 100644 templates/c/.config/flake/outputs.nix create mode 100644 templates/default/.config/flake/outputs.nix create mode 100644 templates/dhall/.config/flake/outputs.nix create mode 100644 templates/emacs-lisp/.config/flake/outputs.nix create mode 100644 templates/haskell/.config/flake/outputs.nix create mode 100644 templates/nix/.config/flake/outputs.nix diff --git a/.config/flake/outputs.nix b/.config/flake/outputs.nix new file mode 100644 index 0000000..193e1bd --- /dev/null +++ b/.config/flake/outputs.nix @@ -0,0 +1,80 @@ +{ + flake-utils, + flaky, + nixpkgs, + self, + systems, +}: let + sys = flake-utils.lib.system; + + supportedSystems = import systems; + + localPackages = pkgs: import ../../packages {inherit pkgs;}; +in + { + ## These are also consumed by downstream projects, so it may include more + ## than is referenced in this flake. + schemas = flaky.schemas; + + overlays = { + default = nixpkgs.lib.composeManyExtensions [ + flaky.overlays.default + self.overlays.dependencies + self.overlays.local + ]; + + dependencies = import ../../nix/dependencies.nix; + + local = final: prev: let + localPkgs = localPackages final; + in { + flaky-management-scripts = localPkgs.management-scripts; + }; + }; + + templates = import ../../templates; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self + [ + ({pkgs, ...}: { + home.packages = [pkgs.flaky-management-scripts]; + nixpkgs.overlays = [self.overlays.default]; + }) + ]) + supportedSystems); + } + // flake-utils.lib.eachSystem supportedSystems + (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + self.overlays.dependencies + ]; + in { + devShells = + {default = flaky.lib.devShells.default system self [] "";} + // self.projectConfigurations.${system}.devShells + // import ../../devShells { + inherit pkgs sys; + inherit (nixpkgs) lib; + }; + + apps.sync-template = flake-utils.lib.mkApp { + drv = self.packages.${system}.management-scripts; + name = "sync-template"; + }; + + packages = + {default = self.packages.${system}.management-scripts;} + // localPackages pkgs; + + projectConfigurations = flaky.lib.projectConfigurations.nix { + inherit pkgs self; + modules = [flaky.projectModules.bash]; + }; + + checks = self.projectConfigurations.${system}.checks; + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/flake.nix b/flake.nix index 3a7ce1e..d41ddd9 100644 --- a/flake.nix +++ b/flake.nix @@ -20,86 +20,9 @@ use-registries = false; }; - outputs = { - flake-utils, - flaky, - nixpkgs, - self, - systems, - }: let - sys = flake-utils.lib.system; - - supportedSystems = import systems; - - localPackages = pkgs: import ./packages {inherit pkgs;}; - in - { - ## These are also consumed by downstream projects, so it may include more - ## than is referenced in this flake. - schemas = flaky.schemas; - - overlays = { - default = nixpkgs.lib.composeManyExtensions [ - flaky.overlays.default - self.overlays.dependencies - self.overlays.local - ]; - - dependencies = import ./nix/dependencies.nix; - - local = final: prev: let - localPkgs = localPackages final; - in { - flaky-management-scripts = localPkgs.management-scripts; - }; - }; - - templates = import ./templates; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self - [ - ({pkgs, ...}: { - home.packages = [pkgs.flaky-management-scripts]; - nixpkgs.overlays = [self.overlays.default]; - }) - ]) - supportedSystems); - } - // flake-utils.lib.eachSystem supportedSystems - (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - self.overlays.dependencies - ]; - in { - devShells = - {default = flaky.lib.devShells.default system self [] "";} - // self.projectConfigurations.${system}.devShells - // import ./devShells { - inherit pkgs sys; - inherit (nixpkgs) lib; - }; - - apps.sync-template = flake-utils.lib.mkApp { - drv = self.packages.${system}.management-scripts; - name = "sync-template"; - }; - - packages = - {default = self.packages.${system}.management-scripts;} - // localPackages pkgs; - - projectConfigurations = flaky.lib.projectConfigurations.nix { - inherit pkgs self; - modules = [flaky.projectModules.bash]; - }; - - checks = self.projectConfigurations.${system}.checks; - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs. diff --git a/templates/bash/.config/flake/outputs.nix b/templates/bash/.config/flake/outputs.nix new file mode 100644 index 0000000..5ef9a49 --- /dev/null +++ b/templates/bash/.config/flake/outputs.nix @@ -0,0 +1,89 @@ +{ + flake-utils, + flaky, + nixpkgs, + self, + systems, +}: let + pname = "{{project.name}}"; + + supportedSystems = import systems; +in + { + schemas = { + inherit + (flaky.schemas) + overlays + homeConfigurations + apps + packages + devShells + projectConfigurations + checks + formatter + ; + }; + + overlays.default = final: prev: {}; + + lib = {}; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self [ + ({pkgs, ...}: {home.packages = [pkgs.${pname}];}) + ]) + supportedSystems); + } + // flake-utils.lib.eachSystem supportedSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + ]; + + src = pkgs.lib.cleanSource ../..; + in { + apps = {}; + + packages = { + default = self.packages.${system}.${pname}; + + "${pname}" = pkgs.checkedDrv (pkgs.stdenv.mkDerivation { + inherit pname src; + + version = "0.1.0"; + + meta = { + description = "{{project.summary}}"; + longDescription = '' + {{project.description}} + ''; + }; + + nativeBuildInputs = [pkgs.bats]; + + patchPhase = '' + runHook prePatch + patchShebangs . + runHook postPatch + ''; + + doCheck = true; + + checkPhase = '' + bats --print-output-on-failure ./test/all-tests.bats + ''; + + doInstallCheck = true; + }); + }; + + projectConfigurations = + flaky.lib.projectConfigurations.bash {inherit pkgs self;}; + + devShells = + self.projectConfigurations.${system}.devShells + // {default = flaky.lib.devShells.default system self [] "";}; + checks = self.projectConfigurations.${system}.checks; + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/templates/bash/flake.nix b/templates/bash/flake.nix index f2622a3..abeece5 100644 --- a/templates/bash/flake.nix +++ b/templates/bash/flake.nix @@ -20,95 +20,9 @@ use-registries = false; }; - outputs = { - flake-utils, - flaky, - nixpkgs, - self, - systems, - }: let - pname = "{{project.name}}"; - - supportedSystems = import systems; - in - { - schemas = { - inherit - (flaky.schemas) - overlays - homeConfigurations - apps - packages - devShells - projectConfigurations - checks - formatter - ; - }; - - overlays.default = final: prev: {}; - - lib = {}; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self [ - ({pkgs, ...}: {home.packages = [pkgs.${pname}];}) - ]) - supportedSystems); - } - // flake-utils.lib.eachSystem supportedSystems (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - ]; - - src = pkgs.lib.cleanSource ./.; - in { - apps = {}; - - packages = { - default = self.packages.${system}.${pname}; - - "${pname}" = pkgs.checkedDrv (pkgs.stdenv.mkDerivation { - inherit pname src; - - version = "0.1.0"; - - meta = { - description = "{{project.summary}}"; - longDescription = '' - {{project.description}} - ''; - }; - - nativeBuildInputs = [pkgs.bats]; - - patchPhase = '' - runHook prePatch - patchShebangs . - runHook postPatch - ''; - - doCheck = true; - - checkPhase = '' - bats --print-output-on-failure ./test/all-tests.bats - ''; - - doInstallCheck = true; - }); - }; - - projectConfigurations = - flaky.lib.projectConfigurations.bash {inherit pkgs self;}; - - devShells = - self.projectConfigurations.${system}.devShells - // {default = flaky.lib.devShells.default system self [] "";}; - checks = self.projectConfigurations.${system}.checks; - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs. diff --git a/templates/c/.config/flake/outputs.nix b/templates/c/.config/flake/outputs.nix new file mode 100644 index 0000000..72dcc6e --- /dev/null +++ b/templates/c/.config/flake/outputs.nix @@ -0,0 +1,94 @@ +{ + flake-utils, + flaky, + nixpkgs, + self, + systems, +}: let + pname = "{{project.name}}"; + + supportedSystems = import systems; +in + { + schemas = { + inherit + (flaky.schemas) + overlays + homeConfigurations + packages + devShells + projectConfigurations + checks + formatter + ; + }; + + overlays.default = final: prev: {}; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self + [({pkgs, ...}: {home.packages = [pkgs.${pname}];})]) + supportedSystems); + + lib = {}; + } + // flake-utils.lib.eachSystem supportedSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + ]; + + src = pkgs.lib.cleanSource ../..; + + ## TODO: This _should_ be done with an overlay, but I can’t seem to avoid + ## getting infinite recursion with it. + stdenv = pkgs.llvmPackages_16.stdenv; + in { + packages = { + default = self.packages.${system}.${pname}; + + ## NB: Can’t use `pkgs.checkedDrv, because `set -o nounset` causes + ## `libtoolize` to fail with “line 2775: debug_mode: unbound + ## variable”. And you can’t run `set` to disable it locally in + ## pre/post hooks (because they’re run in a subshell). + "${pname}" = pkgs.shellchecked (stdenv.mkDerivation { + inherit pname src; + + buildInputs = [ + pkgs.autoreconfHook + ]; + + version = "0.1.0"; + }); + }; + + projectConfigurations = + flaky.lib.projectConfigurations.c {inherit pkgs self;}; + + devShells = + self.projectConfigurations.${system}.devShells + // {default = flaky.lib.devShells.default system self [] "";}; + + checks = + self.projectConfigurations.${system}.checks + // { + ## TODO: This doesn’t quite work yet. + c-lint = + pkgs.checks.simple + "clang-tidy" + src + [pkgs.llvmPackages_16.clang] + '' + ## TODO: Can we keep the compile-commands.json from the original + ## build? E.g., send it to a separate output, which we + ## depend on from this check. We also want it for clangd in + ## the devShell. + make clean && bear -- make + find "$src" \( -name '*.c' -o -name '*.cpp' -o -name '*.h' \) \ + -exec clang-tidy {} + + ''; + }; + + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/templates/c/flake.nix b/templates/c/flake.nix index 86e83a2..abeece5 100644 --- a/templates/c/flake.nix +++ b/templates/c/flake.nix @@ -20,100 +20,9 @@ use-registries = false; }; - outputs = { - flake-utils, - flaky, - nixpkgs, - self, - systems, - }: let - pname = "{{project.name}}"; - - supportedSystems = import systems; - in - { - schemas = { - inherit - (flaky.schemas) - overlays - homeConfigurations - packages - devShells - projectConfigurations - checks - formatter - ; - }; - - overlays.default = final: prev: {}; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self - [({pkgs, ...}: {home.packages = [pkgs.${pname}];})]) - supportedSystems); - - lib = {}; - } - // flake-utils.lib.eachSystem supportedSystems (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - ]; - - src = pkgs.lib.cleanSource ./.; - - ## TODO: This _should_ be done with an overlay, but I can’t seem to avoid - ## getting infinite recursion with it. - stdenv = pkgs.llvmPackages_16.stdenv; - in { - packages = { - default = self.packages.${system}.${pname}; - - ## NB: Can’t use `pkgs.checkedDrv, because `set -o nounset` causes - ## `libtoolize` to fail with “line 2775: debug_mode: unbound - ## variable”. And you can’t run `set` to disable it locally in - ## pre/post hooks (because they’re run in a subshell). - "${pname}" = pkgs.shellchecked (stdenv.mkDerivation { - inherit pname src; - - buildInputs = [ - pkgs.autoreconfHook - ]; - - version = "0.1.0"; - }); - }; - - projectConfigurations = - flaky.lib.projectConfigurations.c {inherit pkgs self;}; - - devShells = - self.projectConfigurations.${system}.devShells - // {default = flaky.lib.devShells.default system self [] "";}; - - checks = - self.projectConfigurations.${system}.checks - // { - ## TODO: This doesn’t quite work yet. - c-lint = - pkgs.checks.simple - "clang-tidy" - src - [pkgs.llvmPackages_16.clang] - '' - ## TODO: Can we keep the compile-commands.json from the original - ## build? E.g., send it to a separate output, which we - ## depend on from this check. We also want it for clangd in - ## the devShell. - make clean && bear -- make - find "$src" \( -name '*.c' -o -name '*.cpp' -o -name '*.h' \) \ - -exec clang-tidy {} + - ''; - }; - - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs. diff --git a/templates/default/.config/flake/outputs.nix b/templates/default/.config/flake/outputs.nix new file mode 100644 index 0000000..d8dd6a2 --- /dev/null +++ b/templates/default/.config/flake/outputs.nix @@ -0,0 +1,62 @@ +{ + flake-utils, + flaky, + nixpkgs, + self, + systems, +}: let + pname = "{{project.name}}"; + + supportedSystems = import systems; +in + { + schemas = { + inherit + (flaky.schemas) + overlays + homeConfigurations + packages + devShells + projectConfigurations + checks + formatter + ; + }; + + overlays.default = final: prev: {}; + + lib = {}; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self + [({pkgs, ...}: {home.packages = [pkgs.${pname}];})]) + supportedSystems); + } + // flake-utils.lib.eachSystem supportedSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + ]; + + src = pkgs.lib.cleanSource ../..; + in { + packages = { + default = self.packages.${system}.${pname}; + + "${pname}" = pkgs.checkedDrv (pkgs.stdenv.mkDerivation { + inherit pname src; + + version = "0.1.0"; + }); + }; + + projectConfigurations = + flaky.lib.projectConfigurations.default {inherit pkgs self;}; + + devShells = + self.projectConfigurations.${system}.devShells + // {default = flaky.lib.devShells.default system self [] "";}; + checks = self.projectConfigurations.${system}.checks; + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/templates/default/flake.nix b/templates/default/flake.nix index 2b45019..abeece5 100644 --- a/templates/default/flake.nix +++ b/templates/default/flake.nix @@ -20,68 +20,9 @@ use-registries = false; }; - outputs = { - flake-utils, - flaky, - nixpkgs, - self, - systems, - }: let - pname = "{{project.name}}"; - - supportedSystems = import systems; - in - { - schemas = { - inherit - (flaky.schemas) - overlays - homeConfigurations - packages - devShells - projectConfigurations - checks - formatter - ; - }; - - overlays.default = final: prev: {}; - - lib = {}; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self - [({pkgs, ...}: {home.packages = [pkgs.${pname}];})]) - supportedSystems); - } - // flake-utils.lib.eachSystem supportedSystems (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - ]; - - src = pkgs.lib.cleanSource ./.; - in { - packages = { - default = self.packages.${system}.${pname}; - - "${pname}" = pkgs.checkedDrv (pkgs.stdenv.mkDerivation { - inherit pname src; - - version = "0.1.0"; - }); - }; - - projectConfigurations = - flaky.lib.projectConfigurations.default {inherit pkgs self;}; - - devShells = - self.projectConfigurations.${system}.devShells - // {default = flaky.lib.devShells.default system self [] "";}; - checks = self.projectConfigurations.${system}.checks; - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs. diff --git a/templates/dhall/.config/flake/outputs.nix b/templates/dhall/.config/flake/outputs.nix new file mode 100644 index 0000000..b43d6b0 --- /dev/null +++ b/templates/dhall/.config/flake/outputs.nix @@ -0,0 +1,75 @@ +{ + flake-utils, + flaky, + nixpkgs, + self, + systems, +}: let + pname = "{{project.name}}"; + + supportedSystems = import systems; +in + { + schemas = { + inherit + (flaky.schemas) + overlays + homeConfigurations + packages + devShells + projectConfigurations + checks + formatter + ; + }; + + overlays = { + default = final: prev: { + dhallPackages = prev.dhallPackages.override (old: { + overrides = + final.lib.composeExtensions + (old.overrides or (_: _: {})) + (self.overlays.dhall final prev); + }); + }; + + dhall = final: prev: dfinal: dprev: { + ${pname} = self.packages.${final.system}.${pname}; + }; + }; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self + ## TODO: Is there something more like `dhallWithPackages`? + [({pkgs, ...}: {home.packages = [pkgs.dhallPackages.${pname}];})]) + supportedSystems); + } + // flake-utils.lib.eachSystem supportedSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + ]; + + src = pkgs.lib.cleanSource ../..; + in { + packages = { + default = self.packages.${system}.${pname}; + + "${pname}" = pkgs.checkedDrv (pkgs.dhallPackages.buildDhallDirectoryPackage { + src = "${src}/dhall"; + name = pname; + dependencies = [pkgs.dhallPackages.Prelude]; + document = true; + }); + }; + + projectConfigurations = + flaky.lib.projectConfigurations.dhall {inherit pkgs self;}; + + devShells = + self.projectConfigurations.${system}.devShells + // {default = flaky.lib.devShells.default system self [] "";}; + checks = self.projectConfigurations.${system}.checks; + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/templates/dhall/flake.nix b/templates/dhall/flake.nix index d0a3c27..8f22fa0 100644 --- a/templates/dhall/flake.nix +++ b/templates/dhall/flake.nix @@ -24,81 +24,9 @@ use-registries = false; }; - outputs = { - flake-utils, - flaky, - nixpkgs, - self, - systems, - }: let - pname = "{{project.name}}"; - - supportedSystems = import systems; - in - { - schemas = { - inherit - (flaky.schemas) - overlays - homeConfigurations - packages - devShells - projectConfigurations - checks - formatter - ; - }; - - overlays = { - default = final: prev: { - dhallPackages = prev.dhallPackages.override (old: { - overrides = - final.lib.composeExtensions - (old.overrides or (_: _: {})) - (self.overlays.dhall final prev); - }); - }; - - dhall = final: prev: dfinal: dprev: { - ${pname} = self.packages.${final.system}.${pname}; - }; - }; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self - ## TODO: Is there something more like `dhallWithPackages`? - [({pkgs, ...}: {home.packages = [pkgs.dhallPackages.${pname}];})]) - supportedSystems); - } - // flake-utils.lib.eachSystem supportedSystems (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - ]; - - src = pkgs.lib.cleanSource ./.; - in { - packages = { - default = self.packages.${system}.${pname}; - - "${pname}" = pkgs.checkedDrv (pkgs.dhallPackages.buildDhallDirectoryPackage { - src = "${src}/dhall"; - name = pname; - dependencies = [pkgs.dhallPackages.Prelude]; - document = true; - }); - }; - - projectConfigurations = - flaky.lib.projectConfigurations.dhall {inherit pkgs self;}; - - devShells = - self.projectConfigurations.${system}.devShells - // {default = flaky.lib.devShells.default system self [] "";}; - checks = self.projectConfigurations.${system}.checks; - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs. diff --git a/templates/emacs-lisp/.config/flake/outputs.nix b/templates/emacs-lisp/.config/flake/outputs.nix new file mode 100644 index 0000000..898f0d2 --- /dev/null +++ b/templates/emacs-lisp/.config/flake/outputs.nix @@ -0,0 +1,77 @@ +{ + flake-utils, + flaky, + nixpkgs, + self, + systems, +}: let + pname = "{{project.name}}"; + ename = "emacs-${pname}"; + + supportedSystems = import systems; +in + { + schemas = { + inherit + (flaky.schemas) + overlays + homeConfigurations + packages + devShells + projectConfigurations + checks + formatter + ; + }; + + overlays = { + default = flaky.lib.elisp.overlays.default self.overlays.emacs; + + emacs = final: prev: efinal: eprev: { + "${pname}" = self.packages.${final.system}.${ename}; + }; + }; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self [ + ({pkgs, ...}: { + programs.emacs = { + enable = true; + extraConfig = "(require '${pname})"; + extraPackages = epkgs: [epkgs.${pname}]; + }; + }) + ]) + supportedSystems); + } + // flake-utils.lib.eachSystem supportedSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + flaky.overlays.elisp-dependencies + ]; + + src = pkgs.lib.cleanSource ../..; + in { + packages = { + default = self.packages.${system}.${ename}; + "${ename}" = pkgs.elisp.package pname src (_: []); + }; + + projectConfigurations = + flaky.lib.projectConfigurations.emacs-lisp {inherit pkgs self;}; + + devShells = + self.projectConfigurations.${system}.devShells + // {default = flaky.lib.devShells.default system self [] "";}; + + checks = + self.projectConfigurations.${system}.checks + // { + elisp-doctor = pkgs.elisp.checks.doctor src; + elisp-lint = pkgs.elisp.checks.lint src (_: []); + }; + + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/templates/emacs-lisp/flake.nix b/templates/emacs-lisp/flake.nix index 669c287..abeece5 100644 --- a/templates/emacs-lisp/flake.nix +++ b/templates/emacs-lisp/flake.nix @@ -20,83 +20,9 @@ use-registries = false; }; - outputs = { - flake-utils, - flaky, - nixpkgs, - self, - systems, - }: let - pname = "{{project.name}}"; - ename = "emacs-${pname}"; - - supportedSystems = import systems; - in - { - schemas = { - inherit - (flaky.schemas) - overlays - homeConfigurations - packages - devShells - projectConfigurations - checks - formatter - ; - }; - - overlays = { - default = flaky.lib.elisp.overlays.default self.overlays.emacs; - - emacs = final: prev: efinal: eprev: { - "${pname}" = self.packages.${final.system}.${ename}; - }; - }; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self [ - ({pkgs, ...}: { - programs.emacs = { - enable = true; - extraConfig = "(require '${pname})"; - extraPackages = epkgs: [epkgs.${pname}]; - }; - }) - ]) - supportedSystems); - } - // flake-utils.lib.eachSystem supportedSystems (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - flaky.overlays.elisp-dependencies - ]; - - src = pkgs.lib.cleanSource ./.; - in { - packages = { - default = self.packages.${system}.${ename}; - "${ename}" = pkgs.elisp.package pname src (_: []); - }; - - projectConfigurations = - flaky.lib.projectConfigurations.emacs-lisp {inherit pkgs self;}; - - devShells = - self.projectConfigurations.${system}.devShells - // {default = flaky.lib.devShells.default system self [] "";}; - - checks = - self.projectConfigurations.${system}.checks - // { - elisp-doctor = pkgs.elisp.checks.doctor src; - elisp-lint = pkgs.elisp.checks.lint src (_: []); - }; - - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs. diff --git a/templates/haskell/.config/flake/outputs.nix b/templates/haskell/.config/flake/outputs.nix new file mode 100644 index 0000000..ec2785a --- /dev/null +++ b/templates/haskell/.config/flake/outputs.nix @@ -0,0 +1,194 @@ +### This is a complicated flake. Here’s the rundown: +### +### overlays.default – includes all of the packages from cabal.project +### packages = { +### default = points to `packages.${defaultGhcVersion}` +### - = an individual package compiled for one +### GHC version +### -all = all of the packages in cabal.project compiled for one +### GHC version +### }; +### devShells = { +### default = points to `devShells.${defaultGhcVersion}` +### = a shell providing all of the dependencies for all +### packages in cabal.project compiled for one GHC version +### }; +### checks.format = verify that code matches Ormolu expectations +{ + flake-utils, + flaky, + flaky-haskell, + nixpkgs, + self, + systems, +}: let + pname = "{{project.name}}"; + + supportedSystems = import systems; + + cabalPackages = pkgs: hpkgs: + flaky-haskell.lib.cabalProject2nix + ../../cabal.project + pkgs + hpkgs + (old: { + configureFlags = old.configureFlags ++ ["--ghc-options=-Werror"]; + }); +in + { + schemas = { + inherit + (flaky.schemas) + overlays + homeConfigurations + packages + devShells + projectConfigurations + checks + formatter + ; + }; + + # see these issues and discussions: + # - NixOS/nixpkgs#16394 + # - NixOS/nixpkgs#25887 + # - NixOS/nixpkgs#26561 + # - https://discourse.nixos.org/t/nix-haskell-development-2020/6170 + overlays = { + default = final: prev: + flaky-haskell.lib.overlayHaskellPackages + (map self.lib.nixifyGhcVersion + (self.lib.supportedGhcVersions final.system)) + (final: prev: + nixpkgs.lib.composeManyExtensions [ + ## TODO: I think this overlay is only needed by formatters, + ## devShells, etc., so it shouldn’t be included in the + ## standard overlay. + (flaky.overlays.haskellDependencies final prev) + (self.overlays.haskell final prev) + (self.overlays.haskellDependencies final prev) + ]) + final + prev; + + haskell = flaky-haskell.lib.haskellOverlay cabalPackages; + + ## NB: Dependencies that are overridden because they are broken in + ## Nixpkgs should be pushed upstream to Flaky. This is for + ## dependencies that we override for reasons local to the project. + haskellDependencies = final: prev: hfinal: hprev: {}; + }; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self [ + ({pkgs, ...}: { + home.packages = [ + (pkgs.haskellPackages.ghcWithPackages (hpkgs: [hpkgs.${pname}])) + ]; + }) + ]) + supportedSystems); + + lib = { + nixifyGhcVersion = version: + "ghc" + nixpkgs.lib.replaceStrings ["."] [""] version; + + ## TODO: Extract this automatically from `pkgs.haskellPackages`. + defaultGhcVersion = "9.8.4"; + + ## Test the oldest revision possible for each minor release. If it’s not + ## available in nixpkgs, test the oldest available, then try an older + ## one via GitHub workflow. Additionally, check any revisions that have + ## explicit conditionalization. And check whatever version `pkgs.ghc` + ## maps to in the nixpkgs we depend on. + testedGhcVersions = system: [ + self.lib.defaultGhcVersion + "8.10.7" + "9.0.2" + "9.2.8" + "9.4.7" + "9.6.3" + "9.8.1" + "9.10.1" + "9.12.1" + # "ghcHEAD" # doctest doesn’t work on current HEAD + ]; + + ## The versions that are older than those supported by Nix that we + ## prefer to test against. + nonNixTestedGhcVersions = [ + "7.10.3" + "8.0.2" + "8.2.2" + "8.4.1" + "8.6.1" + "8.8.1" + "8.10.1" + "9.0.1" + "9.2.1" + "9.4.1" + "9.6.1" + ## since `cabal-plan-bounds` doesn’t work under Nix + "9.8.1" + "9.10.1" + "9.12.1" + ]; + + ## However, provide packages in the default overlay for _every_ + ## supported version. + supportedGhcVersions = system: + self.lib.testedGhcVersions system + ++ [ + "9.4.8" + "9.6.4" + "9.6.5" + "9.8.2" + "9.10.2" + "9.12.2" + ]; + }; + } + // flake-utils.lib.eachSystem supportedSystems + (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + ## NB: This uses `self.overlays.default` because packages need to be + ## able to find other packages in this flake as dependencies. + self.overlays.default + ]; + in { + packages = + { + default = + self.packages.${system}."${self.lib.nixifyGhcVersion self.lib.defaultGhcVersion}_all"; + } + // flaky-haskell.lib.mkPackages + pkgs + (map self.lib.nixifyGhcVersion (self.lib.supportedGhcVersions system)) + cabalPackages; + + devShells = + { + default = + self.devShells.${system}.${self.lib.nixifyGhcVersion self.lib.defaultGhcVersion}; + } + // self.projectConfigurations.${system}.devShells + // flaky-haskell.lib.mkDevShells + pkgs + (map self.lib.nixifyGhcVersion (self.lib.supportedGhcVersions system)) + cabalPackages + (hpkgs: + [self.projectConfigurations.${system}.packages.path] + ## NB: Haskell Language Server no longer supports GHC <9.4. + ++ nixpkgs.lib.optional + (nixpkgs.lib.versionAtLeast hpkgs.ghc.version "9.4") + hpkgs.haskell-language-server); + + projectConfigurations = + flaky.lib.projectConfigurations.haskell {inherit pkgs self;}; + + checks = self.projectConfigurations.${system}.checks; + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/templates/haskell/flake.nix b/templates/haskell/flake.nix index fc2a1fe..28d09c4 100644 --- a/templates/haskell/flake.nix +++ b/templates/haskell/flake.nix @@ -23,200 +23,9 @@ use-registries = false; }; - ### This is a complicated flake. Here’s the rundown: - ### - ### overlays.default – includes all of the packages from cabal.project - ### packages = { - ### default = points to `packages.${defaultGhcVersion}` - ### - = an individual package compiled for one - ### GHC version - ### -all = all of the packages in cabal.project compiled for one - ### GHC version - ### }; - ### devShells = { - ### default = points to `devShells.${defaultGhcVersion}` - ### = a shell providing all of the dependencies for all - ### packages in cabal.project compiled for one GHC version - ### }; - ### checks.format = verify that code matches Ormolu expectations - outputs = { - flake-utils, - flaky, - flaky-haskell, - nixpkgs, - self, - systems, - }: let - pname = "{{project.name}}"; - - supportedSystems = import systems; - - cabalPackages = pkgs: hpkgs: - flaky-haskell.lib.cabalProject2nix - ./cabal.project - pkgs - hpkgs - (old: { - configureFlags = old.configureFlags ++ ["--ghc-options=-Werror"]; - }); - in - { - schemas = { - inherit - (flaky.schemas) - overlays - homeConfigurations - packages - devShells - projectConfigurations - checks - formatter - ; - }; - - # see these issues and discussions: - # - NixOS/nixpkgs#16394 - # - NixOS/nixpkgs#25887 - # - NixOS/nixpkgs#26561 - # - https://discourse.nixos.org/t/nix-haskell-development-2020/6170 - overlays = { - default = final: prev: - flaky-haskell.lib.overlayHaskellPackages - (map self.lib.nixifyGhcVersion - (self.lib.supportedGhcVersions final.system)) - (final: prev: - nixpkgs.lib.composeManyExtensions [ - ## TODO: I think this overlay is only needed by formatters, - ## devShells, etc., so it shouldn’t be included in the - ## standard overlay. - (flaky.overlays.haskellDependencies final prev) - (self.overlays.haskell final prev) - (self.overlays.haskellDependencies final prev) - ]) - final - prev; - - haskell = flaky-haskell.lib.haskellOverlay cabalPackages; - - ## NB: Dependencies that are overridden because they are broken in - ## Nixpkgs should be pushed upstream to Flaky. This is for - ## dependencies that we override for reasons local to the project. - haskellDependencies = final: prev: hfinal: hprev: {}; - }; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self [ - ({pkgs, ...}: { - home.packages = [ - (pkgs.haskellPackages.ghcWithPackages (hpkgs: [hpkgs.${pname}])) - ]; - }) - ]) - supportedSystems); - - lib = { - nixifyGhcVersion = version: - "ghc" + nixpkgs.lib.replaceStrings ["."] [""] version; - - ## TODO: Extract this automatically from `pkgs.haskellPackages`. - defaultGhcVersion = "9.8.4"; - - ## Test the oldest revision possible for each minor release. If it’s not - ## available in nixpkgs, test the oldest available, then try an older - ## one via GitHub workflow. Additionally, check any revisions that have - ## explicit conditionalization. And check whatever version `pkgs.ghc` - ## maps to in the nixpkgs we depend on. - testedGhcVersions = system: [ - self.lib.defaultGhcVersion - "8.10.7" - "9.0.2" - "9.2.8" - "9.4.7" - "9.6.3" - "9.8.1" - "9.10.1" - "9.12.1" - # "ghcHEAD" # doctest doesn’t work on current HEAD - ]; - - ## The versions that are older than those supported by Nix that we - ## prefer to test against. - nonNixTestedGhcVersions = [ - "7.10.3" - "8.0.2" - "8.2.2" - "8.4.1" - "8.6.1" - "8.8.1" - "8.10.1" - "9.0.1" - "9.2.1" - "9.4.1" - "9.6.1" - ## since `cabal-plan-bounds` doesn’t work under Nix - "9.8.1" - "9.10.1" - "9.12.1" - ]; - - ## However, provide packages in the default overlay for _every_ - ## supported version. - supportedGhcVersions = system: - self.lib.testedGhcVersions system - ++ [ - "9.4.8" - "9.6.4" - "9.6.5" - "9.8.2" - "9.10.2" - "9.12.2" - ]; - }; - } - // flake-utils.lib.eachSystem supportedSystems - (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - ## NB: This uses `self.overlays.default` because packages need to be - ## able to find other packages in this flake as dependencies. - self.overlays.default - ]; - in { - packages = - { - default = - self.packages.${system}."${self.lib.nixifyGhcVersion self.lib.defaultGhcVersion}_all"; - } - // flaky-haskell.lib.mkPackages - pkgs - (map self.lib.nixifyGhcVersion (self.lib.supportedGhcVersions system)) - cabalPackages; - - devShells = - { - default = - self.devShells.${system}.${self.lib.nixifyGhcVersion self.lib.defaultGhcVersion}; - } - // self.projectConfigurations.${system}.devShells - // flaky-haskell.lib.mkDevShells - pkgs - (map self.lib.nixifyGhcVersion (self.lib.supportedGhcVersions system)) - cabalPackages - (hpkgs: - [self.projectConfigurations.${system}.packages.path] - ## NB: Haskell Language Server no longer supports GHC <9.4. - ++ nixpkgs.lib.optional - (nixpkgs.lib.versionAtLeast hpkgs.ghc.version "9.4") - hpkgs.haskell-language-server); - - projectConfigurations = - flaky.lib.projectConfigurations.haskell {inherit pkgs self;}; - - checks = self.projectConfigurations.${system}.checks; - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs. diff --git a/templates/nix/.config/flake/outputs.nix b/templates/nix/.config/flake/outputs.nix new file mode 100644 index 0000000..cdcbd8a --- /dev/null +++ b/templates/nix/.config/flake/outputs.nix @@ -0,0 +1,63 @@ +{ + flake-utils, + flaky, + nixpkgs, + self, + systems, +}: let + pname = "{{project.name}}"; + + supportedSystems = import systems; +in + { + schemas = { + inherit + (flaky.schemas) + overlays + homeConfigurations + packages + devShells + projectConfigurations + checks + formatter + ; + }; + + overlays.default = final: prev: {}; + + lib = {}; + + homeConfigurations = + builtins.listToAttrs + (builtins.map + (flaky.lib.homeConfigurations.example self + [({pkgs, ...}: {home.packages = [pkgs.${pname}];})]) + supportedSystems); + } + // flake-utils.lib.eachSystem supportedSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ + flaky.overlays.default + ]; + + src = pkgs.lib.cleanSource ../..; + in { + packages = { + default = self.packages.${system}.${pname}; + + "${pname}" = pkgs.checkedDrv (pkgs.stdenv.mkDerivation { + inherit pname src; + + version = "0.1.0"; + }); + }; + + projectConfigurations = + flaky.lib.projectConfigurations.nix {inherit pkgs self;}; + + devShells = + self.projectConfigurations.${system}.devShells + // {default = flaky.lib.devShells.default system self [] "";}; + + checks = self.projectConfigurations.${system}.checks; + formatter = self.projectConfigurations.${system}.formatter; + }) diff --git a/templates/nix/flake.nix b/templates/nix/flake.nix index 549fad8..abeece5 100644 --- a/templates/nix/flake.nix +++ b/templates/nix/flake.nix @@ -20,69 +20,9 @@ use-registries = false; }; - outputs = { - flake-utils, - flaky, - nixpkgs, - self, - systems, - }: let - pname = "{{project.name}}"; - - supportedSystems = import systems; - in - { - schemas = { - inherit - (flaky.schemas) - overlays - homeConfigurations - packages - devShells - projectConfigurations - checks - formatter - ; - }; - - overlays.default = final: prev: {}; - - lib = {}; - - homeConfigurations = - builtins.listToAttrs - (builtins.map - (flaky.lib.homeConfigurations.example self - [({pkgs, ...}: {home.packages = [pkgs.${pname}];})]) - supportedSystems); - } - // flake-utils.lib.eachSystem supportedSystems (system: let - pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [ - flaky.overlays.default - ]; - - src = pkgs.lib.cleanSource ./.; - in { - packages = { - default = self.packages.${system}.${pname}; - - "${pname}" = pkgs.checkedDrv (pkgs.stdenv.mkDerivation { - inherit pname src; - - version = "0.1.0"; - }); - }; - - projectConfigurations = - flaky.lib.projectConfigurations.nix {inherit pkgs self;}; - - devShells = - self.projectConfigurations.${system}.devShells - // {default = flaky.lib.devShells.default system self [] "";}; - - checks = self.projectConfigurations.${system}.checks; - formatter = self.projectConfigurations.${system}.formatter; - }); + ## The flake isn’t a Nix expression, so it’s clearer to keep `outputs` (which + ## is) in a separate file. + outputs = inputs: import .config/flake/outputs.nix inputs; inputs = { ## Flaky should generally be the source of truth for its inputs.