forked from gytis-ivaskevicius/flake-utils-plus
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexportOverlays.nix
More file actions
103 lines (84 loc) · 3.55 KB
/
exportOverlays.nix
File metadata and controls
103 lines (84 loc) · 3.55 KB
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
{ flake-utils-plus }:
let
exportOverlays = { pkgs, inputs ? { } }:
/**
Synopsis: exportOverlays _{ pkgs, inputs }_
pkgs: self.pkgs
inputs: flake inputs to sort out external overlays
Overlays with an attribute named "__dontExport" will be filtered out.
Returns an attribute set of all packages defined in an overlay by any channel
intended to be passed to be exported via _self.overlays_. This method of
sharing has the advantage over _self.packages_, that the user will instantiate
overlays with his proper nixpkgs version, and thereby significantly reduce their system's
closure as they avoid depending on entirely different nixpkgs versions dependency
trees. On the flip side, any caching that is set up for one's packages will essentially
be useless to users.
It can happen that an overlay is not compatible with the version of nixpkgs a user tries
to instantiate it. In order to provide users with a visual clue for which nixpkgs version
an overlay was originally created, we prefix the channle name: "<channelname>/<packagekey>".
In the case of the unstable channel, this information is still of varying usefulness,
as effective cut dates can vary heavily between repositories.
To ensure only overlays that originate from the flake are exported you can optionally pass
a set of flake inputs and any overlay which is taken from an input will be filtered out.
Optimally this would be done by detecting flake ownership of each overlay, but that is not
possible yet, so this is the next best workaround.
Example:
overlays = [
"unstable/development" = final: prev: { };
"nixos2009/chromium" = final: prev: { };
"nixos2009/pythonPackages" = final: prev: { };
];
**/
let
inherit (builtins)
attrNames
attrValues
concatMap
elem
filter
foldl'
head
listToAttrs
mapAttrs
;
nameValuePair = name: value: { inherit name value; };
# just pull out one arch from the system-spaced pkgs to get access to channels
# overlays can be safely evaluated on any arch
channels = head (attrValues pkgs);
pathStr = path: builtins.concatStringsSep "/" path;
channelNames = attrNames channels;
overlayNames = overlay: attrNames (overlay null null);
# get all overlays from inputs
inputOverlays = mapAttrs
(_: v: [ v.overlay or (_: _: { }) ] ++ attrValues v.overlays or { })
(removeAttrs inputs [ "self" ]);
# use overlayNames as a way to identify overlays
flattenedInputOverlays = map overlayNames (foldl' (a: b: a ++ b) [ ] (attrValues inputOverlays));
extractAndNamespaceEachOverlay = channelName: overlay:
map
(overlayName:
nameValuePair
(pathStr [ channelName overlayName ])
(final: prev: {
${overlayName} = (overlay final prev).${overlayName};
})
)
(overlayNames overlay);
checkOverlay = overlay:
(!elem (overlayNames overlay) flattenedInputOverlays)
&& (!elem "__dontExport" (overlayNames overlay));
filterOverlays = channel: filter checkOverlay channel.overlays;
in
listToAttrs (
concatMap
(channelName:
concatMap
(overlay:
extractAndNamespaceEachOverlay channelName overlay
)
(filterOverlays channels.${channelName})
)
channelNames
);
in
exportOverlays