2023-05-25 20:55:54 +00:00
|
|
|
{ stable }:
|
2023-02-07 21:15:13 +00:00
|
|
|
|
|
|
|
let
|
2023-06-14 01:48:19 +00:00
|
|
|
inherit (builtins) attrNames elemAt filter functionArgs isAttrs isPath length mapAttrs match pathExists removeAttrs toJSON tryEval;
|
2023-05-25 20:55:54 +00:00
|
|
|
inherit (stable) callPackage fetchFromGitHub;
|
2023-06-14 01:48:19 +00:00
|
|
|
inherit (stable.lib) attrByPath concatMapStringsSep const findFirst getAttrFromPath hasAttrByPath imap1 info optionalAttrs optionalString recurseIntoAttrs showAttrPath throwIf toList 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@{
|
2023-06-14 01:48:19 +00:00
|
|
|
# Namespacing
|
|
|
|
recurseForDerivations ? false
|
|
|
|
|
2023-05-25 20:55:54 +00:00
|
|
|
# Repository selection
|
2023-06-14 01:48:19 +00:00
|
|
|
, condition ? null
|
2023-05-26 06:06:20 +00:00
|
|
|
, release ? null
|
2023-05-25 20:55:54 +00:00
|
|
|
, search ? null
|
|
|
|
, version ? null
|
|
|
|
|
|
|
|
# Package defaults
|
|
|
|
, deps ? { }
|
|
|
|
|
|
|
|
# Package attribute overlay
|
|
|
|
, gappsWrapperArgs ? null
|
|
|
|
, overlay ? null
|
|
|
|
, patch ? null
|
2023-05-17 01:24:49 +00:00
|
|
|
|
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-17 01:24:49 +00:00
|
|
|
|
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 ];
|
2023-05-26 06:06:20 +00:00
|
|
|
name = showAttrPath path;
|
2023-05-26 02:34:27 +00:00
|
|
|
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 06:06:20 +00:00
|
|
|
&& (version == null || versionMeetsSpec (getAttrFromPath path r).version version)
|
|
|
|
&& (condition == null || condition (getAttrFromPath path r));
|
2023-06-14 01:48:19 +00:00
|
|
|
extra = if search == null then [ ] else imap1 (i: s: { _extra = i; _name = "search"; } // s) (toList search);
|
|
|
|
repo = findFirst suffices (./. + "/${pname}.nix") ([ stable unstable ] ++ extra);
|
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;
|
|
|
|
|
2023-05-26 06:27:04 +00:00
|
|
|
# Report
|
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") +
|
2023-05-26 06:06:20 +00:00
|
|
|
(optionalString (condition != null) " meeting condition") +
|
2023-05-25 20:55:54 +00:00
|
|
|
(optionalString (! isStable repo) " via ${repoName repo}");
|
2023-05-26 06:27:04 +00:00
|
|
|
unnecessary = isStable repo && !doOverlay && !doOverride;
|
2023-06-14 01:48:19 +00:00
|
|
|
unnecessarySearches = concatMapStringsSep ", " repoName (filter (r: r._extra > repo._extra or 0) extra);
|
2023-05-25 20:55:54 +00:00
|
|
|
in
|
2023-06-14 01:33:12 +00:00
|
|
|
if hasAttrByPath (path ++ [ "overrideScope'" ]) stable then
|
2023-05-26 02:34:27 +00:00
|
|
|
(getAttrFromPath path stable).overrideScope' (_: _: mapAttrs (resolve path) spec)
|
2023-06-14 01:48:19 +00:00
|
|
|
else if recurseForDerivations || (attrByPath (path ++ [ "recurseForDerivations" ]) false repo) then
|
|
|
|
(attrByPath path { } repo) // (mapAttrs (resolve path) spec)
|
2023-05-26 02:34:27 +00:00
|
|
|
else
|
2023-06-14 01:48:19 +00:00
|
|
|
throwIf (unnecessarySearches != "") "${name} no longer requires searching ${unnecessarySearches}"
|
2023-05-26 06:27:04 +00:00
|
|
|
(throwIf unnecessary "${name} no longer requires an override")
|
2023-05-26 02:34:27 +00:00
|
|
|
(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-06-14 01:48:19 +00:00
|
|
|
namespaced = mapAttrs (_: recurseIntoAttrs);
|
|
|
|
|
2023-05-26 02:34:27 +00:00
|
|
|
specify = mapAttrs (resolve [ ]);
|
2023-02-07 21:15:13 +00:00
|
|
|
}
|