HORIZON HASKELLDocslts/ghc-9.14.xb2f3bfd2026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · b2f3bfd · 2026-10-11

Modulehorizon-config-shell-0.12.1GHC2024

Horizon.Config.Writers

Write the per-package pkgs/*.nix derivations and the overlay / package-set files. Ported from horizon-gen-nix, retargeted onto Horizon.Config.Schema (no horizon-spec, no dhall) and onto set-level Modifiers: the one set-wide build policy is applied to every pin, and a local package is built by its own (Horizon.Config.Cabal2Nix).

Every package, a local one included, is a generated pkgs/*.nix, so the set evaluates without building anything first. A package's native libraries are passed at its callPackage in the overlay / package-set file; its source patches are the patches of its pkgs/*.nix. A set with local packages calls them through horizon-local.nix, the Nix the generator ships for them, copied beside the set: it decides what of a local directory is the package's source, and checks that the package's file was generated from the .cabal the directory now holds.

  • 10 values

The repository's overlay, as a flake-parts module: one overlay under horizon.overlay's overlays — this module sets the repository's members as overlays, and the consumer (the toolchain repo's generated nix/horizon.nix, or a hand one with its own base input) reads them from the option and composes. The members' values are the functions the repository's pkgs modules publish at horizon.pkgs, applied with the set under composition.

valueasPkgsModule :: Text -> [SystemDep] -> Text -> Text
#

A generated package's file: one module carrying the package's set-composition value — the callPackage function the overlays and the initialPackages read from the per-system horizon.pkgs option, one key per file so the option's merge is unique. The packages reach the consumer through the composed set's own packages.

The repository's cabal.project: one packages: entry per local package's directory, and the compiler the set builds with. Written when the repository has local packages; the set's own generated cabal.config (the solve probe) stays the solve's business.

Write every package's .nix (only the ones whose pin changed, per the lock), then rewrite the lock and prune .nix files for dropped packages. locals holds the .cabal of each local package, which its pin is keyed on and its file records.

The Hackage pins are rendered from one Hackage index, read once, at the set's index state; a set read at an index state refuses, with the ConfigError, a local Hackage index that has not reached it, before anything is written.

A single package's failure does NOT abort the batch: every package is attempted, and the lock records ONLY the packages that succeeded (plus the prior lock's still-current entries), so the next run's lockDiff re-selects exactly the failures — real incrementality. The run then fails with PackagesUnrendered, naming them, without losing the work that did complete. | The generated nix/horizon-pkgs.nix: the repository's packages as functions under flake.lib.horizon.pkgs, one per package, each taking the callPackage scope's usual arguments. A module, published with importAndPublish like every hand-written one — never reached by path. A consumer (the horizon.packageSet module of a toolchain repo, a hand nix/<app>.nix, anything overlaying this set) refers to them:

horizon.packageSet.base.initialPackages = horizon.lib.horizon.pkgs
overrides = final: prev: { tint = horizon.lib.horizon.pkgs.tint { }; }

A local package's function carries its directory's source filter and the fresh passthru inline, so horizon-local.nix is gone: what it did is data here, beside the other packages.

A patch path, relative to the config, as the Nix path literal that names it from a file in the packages directory: patches/x.patch is ..patchesx.patch from pkgs/. It must be a relative file inside the repository (so the flake's source carries it) spelt only with the ASCII characters Nix accepts in a bare path literal.

valuenixStr :: String -> String
#

A Nix string literal: a quote, a backslash and the dollar that could open an interpolation are escaped.

valuenixList :: [String] -> String
#

A Nix list of already-rendered elements, formatted as nixpkgs-fmt leaves it.