rename export{Overlays,Packages}

This commit is contained in:
Mihai Fufezan 2021-07-20 20:46:38 +03:00
parent 22256e8560
commit 0f7b21670b
No known key found for this signature in database
GPG Key ID: 3AC82B48170331D3
3 changed files with 166 additions and 156 deletions

View File

@ -18,8 +18,8 @@
# Deprecated names of the above
systemFlake = mkFlake;
modulesFromList = exportModules;
fromOverlays = exportOverlays;
internalOverlays = exportPackages;
fromOverlays = exportPackages;
internalOverlays = exportOverlays;
in
rec {
inherit overlay;

View File

@ -1,91 +1,103 @@
{ flake-utils-plus }:
let
packagesFromOverlaysBuilder = overlays:
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
# overlays: self.overlays
inherit (builtins)
attrNames
attrValues
concatMap
elem
filter
foldl'
head
listToAttrs
mapAttrs
;
nameValuePair = name: value: { inherit name value; };
packagesFromOverlays = channels:
/**
Synopsis: packagesFromOverlaysBuilder _channels_
# 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);
channels: builder `channels` argument
pathStr = path: builtins.concatStringsSep "/" path;
Returns valid packges that have been defined within an overlay so they
can be shared via _self.packages_ with the world. This is especially useful
over sharing one's art via _self.overlays_ in case you have a binary cache
running from which third parties could benefit.
channelNames = attrNames channels;
overlayNames = overlay: attrNames (overlay null null);
Steps:
1. merge all channels into one nixpkgs attribute set
2. collect all overlays' packages' keys into one flat list
3. pick out each package from the nixpkgs set into one packages set
$. flatten package set and filter out disallowed packages - by flake check requirements
# 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));
example input and output:
```
overlays = {
"unstable/firefox" = prev: final: {
firefox = prev.override { privacySupport = true; };
};
}
extractAndNamespaceEachOverlay = channelName: overlay:
map
(overlayName:
nameValuePair
(pathStr [ channelName overlayName ])
(final: prev: {
${overlayName} = (overlay final prev).${overlayName};
})
)
(overlayNames overlay);
self.packages = {
firefox = *firefox derivation with privacySupport*;
}
```
checkOverlay = overlay:
(!elem (overlayNames overlay) flattenedInputOverlays)
&& (!elem "__dontExport" (overlayNames overlay));
**/
let
inherit (flake-utils-plus.lib) flattenTree filterPackages;
inherit (builtins) foldl' attrNames mapAttrs listToAttrs
attrValues concatStringSep concatMap any head;
nameValuePair = name: value: { inherit name value; };
flattenedPackages =
# merge all channels into one package set
foldl' (a: b: a // b) { } (attrValues channels);
# flatten all overlays' packages' keys into a single list
flattenedOverlaysNames =
let
allOverlays = attrValues overlays;
overlayNamesList = overlay:
attrNames (overlay null null);
in
concatMap overlayNamesList allOverlays;
# create list of single-attribute sets that contain each package
exportPackagesList = map
(name:
let
item = flattenedPackages.${name};
exportItem = { ${name} = item; };
in
if item ? type && item.type == "derivation" then
# if its a package export it
exportItem
else if item ? __dontExport && !item.__dontExport then
# if its a package sub-system, __dontExport has to be set to false to export
exportItem
else
{ }
)
flattenedOverlaysNames;
# fold list into one attribute set
exportPackages = foldl' (lhs: rhs: lhs // rhs) { } exportPackagesList;
system = (head (attrValues channels)).system;
in
# flatten nested sets with "/" delimiter then drop disallowed packages
filterPackages system (flattenTree exportPackages);
filterOverlays = channel: filter checkOverlay channel.overlays;
in
packagesFromOverlays;
listToAttrs (
concatMap
(channelName:
concatMap
(overlay:
extractAndNamespaceEachOverlay channelName overlay
)
(filterOverlays channels.${channelName})
)
channelNames
);
in
packagesFromOverlaysBuilder
exportOverlays

View File

@ -1,93 +1,91 @@
{ flake-utils-plus }:
let
overlaysFromChannelsExporter = { pkgs, inputs ? { } }:
/**
Synopsis: overlaysFromChannelsExporter _{ 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: { };
];
**/
exportPackagesBuilder = overlays:
let
inherit (builtins) mapAttrs foldl' filter head attrNames attrValues concatMap listToAttrs elem;
nameValuePair = name: value: { inherit name value; };
# overlays: self.overlays
# 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);
exportPackages = channels:
/**
Synopsis: exportPackagesBuilder _channels_
pathStr = path: builtins.concatStringsSep "/" path;
channels: builder `channels` argument
channelNames = attrNames channels;
overlayNames = overlay: attrNames (overlay null null);
Returns valid packges that have been defined within an overlay so they
can be shared via _self.packages_ with the world. This is especially useful
over sharing one's art via _self.overlays_ in case you have a binary cache
running from which third parties could benefit.
# 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));
Steps:
1. merge all channels into one nixpkgs attribute set
2. collect all overlays' packages' keys into one flat list
3. pick out each package from the nixpkgs set into one packages set
$. flatten package set and filter out disallowed packages - by flake check requirements
extractAndNamespaceEachOverlay = channelName: overlay:
map
(overlayName:
nameValuePair
(pathStr [ channelName overlayName ])
(final: prev: {
${overlayName} = (overlay final prev).${overlayName};
})
)
(overlayNames overlay);
example input and output:
```
overlays = {
"unstable/firefox" = prev: final: {
firefox = prev.override { privacySupport = true; };
};
}
checkOverlay = overlay:
(!elem (overlayNames overlay) flattenedInputOverlays)
&& (!elem "__dontExport" (overlayNames overlay));
self.packages = {
firefox = *firefox derivation with privacySupport*;
}
```
filterOverlays = channel: filter checkOverlay channel.overlays;
**/
let
inherit (flake-utils-plus.lib) flattenTree filterPackages;
inherit (builtins) foldl' attrNames mapAttrs listToAttrs
attrValues concatStringSep concatMap any head;
nameValuePair = name: value: { inherit name value; };
flattenedPackages =
# merge all channels into one package set
foldl' (a: b: a // b) { } (attrValues channels);
# flatten all overlays' packages' keys into a single list
flattenedOverlaysNames =
let
allOverlays = attrValues overlays;
overlayNamesList = overlay:
attrNames (overlay null null);
in
concatMap overlayNamesList allOverlays;
# create list of single-attribute sets that contain each package
exportPackagesList = map
(name:
let
item = flattenedPackages.${name};
exportItem = { ${name} = item; };
in
if item ? type && item.type == "derivation" then
# if its a package export it
exportItem
else if item ? __dontExport && !item.__dontExport then
# if its a package sub-system, __dontExport has to be set to false to export
exportItem
else
{ }
)
flattenedOverlaysNames;
# fold list into one attribute set
exportPackages = foldl' (lhs: rhs: lhs // rhs) { } exportPackagesList;
system = (head (attrValues channels)).system;
in
# flatten nested sets with "/" delimiter then drop disallowed packages
filterPackages system (flattenTree exportPackages);
in
listToAttrs (
concatMap
(channelName:
concatMap
(overlay:
extractAndNamespaceEachOverlay channelName overlay
)
(filterOverlays channels.${channelName})
)
channelNames
);
exportPackages;
in
overlaysFromChannelsExporter
exportPackagesBuilder