-
Notifications
You must be signed in to change notification settings - Fork 0
/
stability.nix
112 lines (107 loc) · 3.95 KB
/
stability.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
final: prev: let
# Get information about the channels that are currently supported and
# maintained.
rawChannelData = builtins.fromJSON (
builtins.readFile (
builtins.fetchurl
"https://prometheus.nixos.org/api/v1/query?query=channel_revision"
)
);
channelData = rawChannelData.data.result;
channelInfo = excludeOverlays:
map (data: rec {
name = data.metric.channel;
status =
if builtins.elem data.metric.status ["stable" "rolling" "unmaintained"]
then data.metric.status
else throw "Unexpected channel status ${data.metric.status} for channel ${name}";
variant = let
v = data.metric.variant or null;
in
if builtins.elem v ["primary" "small" "darwin" null]
then v
else throw "Unexpected channel variant ${v} for channel ${name}";
url = "https://channels.nixos.org/${name}/nixexprs.tar.xz";
pkgs =
if excludeOverlays == null
then import (builtins.fetchTarball url) {}
else let
# Based on the nixpkgs overlays configuration.
path = ./.;
content = builtins.readDir path;
overlayFiles = builtins.filter (n:
!(builtins.elem n excludeOverlays)
&& (
(
(builtins.match ".*\\.nix" n != null)
&& (builtins.match "\\.#.*" n == null)
)
|| builtins.pathExists (path + ("/" + n + "/default.nix"))
))
(builtins.attrNames content);
overlays = map (n: import (path + ("/" + n))) overlayFiles;
in
import (builtins.fetchTarball url) {inherit overlays;};
})
channelData;
allowedChannels = excludeOverlays:
builtins.filter
(c: c.status != "unmaintained" && c.variant != "darwin")
(channelInfo excludeOverlays);
# More stable = lower = at the front of the sorted list. Assume anything
# marked as "stable" is more stable than anything that isn't, anything marked
# as "small" is less stable than anything marked as "primary", and anything
# with neither "small" nor "primary" labels -- which seems to mean
# nixpkgs-unstable -- is least stable.
#
# Order tests assume the values are restricted by the filtering in
# allowedChannels and the value tests in channelInfo. The final `throw`
# should only be hit in the event there are multiple channels that compare
# identically.
stabilityCmp = a: b:
if a.status != b.status
then a.status == "stable"
else if a.variant != b.variant
then
if a.variant == "primary"
then true
else if b.variant == "primary"
then false
else a.variant == "small"
else throw "Cannot sort channels ${a.name} and ${b.name} in stability order";
channelsByStability = excludeOverlays:
builtins.sort stabilityCmp (allowedChannels excludeOverlays);
packageFromChannel = name: channel:
final.lib.attrByPath (final.lib.splitString "." name) null channel.pkgs;
packagesByStability = excludeOverlays: name:
builtins.filter (p: p != null)
(map (packageFromChannel name) (channelsByStability excludeOverlays));
in {
lib = prev.lib.attrsets.recursiveUpdate prev.lib {
channels = {
mostStablePackageWith = {
name,
pred,
default,
excludeOverlays ? null,
# If calling from an overlay, can add prev.package in case the local
# package already satisfies the predicate.
testFirst ? [],
}:
final.lib.findFirst pred default
(testFirst ++ packagesByStability excludeOverlays name);
mostStablePackageVersionAtLeast = {
name,
version,
excludeOverlays ? null,
testFirst ? [],
}:
final.lib.channels.mostStablePackageWith {
inherit name excludeOverlays testFirst;
pred = p: final.lib.versionAtLeast p.version version;
default =
throw "No ${name} package with version at least ${version} available";
};
};
};
}