configuration/packages/override-utils.nix

103 lines
3.9 KiB
Nix
Raw Normal View History

2023-05-25 20:55:54 +00:00
{ stable }:
2023-02-07 21:15:13 +00:00
let
2023-05-25 20:55:54 +00:00
inherit (builtins) attrNames elemAt functionArgs isAttrs isPath length mapAttrs match pathExists removeAttrs toJSON tryEval;
inherit (stable) callPackage fetchFromGitHub;
2023-05-26 02:34:27 +00:00
inherit (stable.lib) attrByPath concatStringsSep const findFirst getAttrFromPath hasAttrByPath info optionalAttrs optionalString throwIf versionAtLeast;
2023-05-25 20:55:54 +00:00
# Utilities
composeOverrides = f1: f2: a0: let o1 = f1 a0; o2 = f2 (a0 // o1); in o1 // o2;
isEmpty = attrs: length (attrNames attrs) == 0;
isStable = r: isAttrs r && ! r ? "_name";
mkRepo = name: path: (import path { inherit (stable) config; overlays = [ ]; }) // { _name = name; };
repoName = r: if isPath r then toString r else r._name or "stable channel";
revision = rev: hash: fetchFromGitHub { inherit hash rev; owner = "NixOS"; repo = "nixpkgs"; };
versionMeetsSpec = candidate: spec:
let parts = match "^([^[:alnum:]]+)?(.+)$" spec; operator = elemAt parts 0; version = elemAt parts 1; in
if operator == null then candidate == version
else if operator == "" then versionAtLeast candidate version
else throw "version operator not implemented: ${toJSON operator}";
# Repositories
pin = rev: hash: mkRepo "pin ${rev}" (revision rev hash);
pr = id: hash: mkRepo "PR #${toString id}" (revision "refs/pull/${toString id}/head" hash);
unstable =
if (tryEval (pathExists <unstable>)).value then mkRepo "unstable channel" <unstable>
else info "No unstable channel found" null;
# Functions
2023-05-26 02:34:27 +00:00
resolve = scope: pname:
2023-05-25 20:55:54 +00:00
spec@{
# Repository selection
release ? null
, search ? null
, version ? null
# Package defaults
, deps ? { }
# Package attribute overlay
, gappsWrapperArgs ? null
, overlay ? null
, patch ? null
2023-05-25 20:55:54 +00:00
# Package input override
, ...
}:
let
# Implicit arguments
2023-05-26 02:34:27 +00:00
override = removeAttrs spec (attrNames (functionArgs (resolve scope pname)));
2023-05-25 20:55:54 +00:00
# Specification
doOverlay = gappsWrapperArgs != null || overlay != null || patch != null;
doOverride = ! isEmpty override;
# Package selection
2023-05-26 02:34:27 +00:00
path = scope ++ [ pname ];
name = concatStringsSep "." path;
suffices = r: r != null && hasAttrByPath path r
2023-05-25 20:55:54 +00:00
&& (release == null || versionMeetsSpec r.lib.trivial.release release)
2023-05-26 02:34:27 +00:00
&& (version == null || versionMeetsSpec (getAttrFromPath path r).version version);
2023-05-25 20:55:54 +00:00
repo = findFirst suffices (./. + "/${pname}.nix") [ stable unstable search ];
2023-05-26 02:34:27 +00:00
package = if isPath repo then callPackage repo deps else getAttrFromPath path repo;
2023-05-25 20:55:54 +00:00
# Package overlay
package_with_overlay =
if doOverlay then
package.overrideAttrs
(composeOverrides
(a:
(optionalAttrs (patch != null) { patches = a.patches or [ ] ++ [ patch ]; }) //
(optionalAttrs (gappsWrapperArgs != null) { preFixup = a.preFixup + "\ngappsWrapperArgs+=(${gappsWrapperArgs})"; })
)
(if overlay == null then const { } else overlay)
)
else package;
# Package override
package_with_overlay_with_override =
if doOverride then package_with_overlay.override override
else package_with_overlay;
# Summary
2023-05-26 02:34:27 +00:00
summary = "Resolved ${name}" +
2023-05-25 20:55:54 +00:00
(optionalString (version != null) " ${version}") +
(optionalString (release != null) " of NixOS ${release}") +
(optionalString (doOverlay || doOverride) " with override") +
(optionalString (! isStable repo) " via ${repoName repo}");
in
2023-05-26 02:34:27 +00:00
if (attrByPath path { } stable) ? "overrideScope'" then
(getAttrFromPath path stable).overrideScope' (_: _: mapAttrs (resolve path) spec)
else
throwIf (isStable repo && !doOverlay && !doOverride) "${name} no longer requires an override"
(info summary package_with_overlay_with_override)
2023-05-25 20:55:54 +00:00
;
2023-02-07 21:15:13 +00:00
in
{
2023-05-25 20:55:54 +00:00
inherit pin pr unstable;
any = { };
2023-05-26 02:34:27 +00:00
specify = mapAttrs (resolve [ ]);
2023-02-07 21:15:13 +00:00
}