dream2nix/src/lib.nix
Yusuf Bera Ertan 9b6638a1a7
feat: implement makeOutputs that outputs systemless structure (#161)
* feat: return underlying d2n instance if pkgs was passed to init, document init pkgs

* feat: implement makeOutputs

* tests: dont fail if resolveImpure fails

* feat: make init return a dream2nix instance, rework makeFlakeOutputs code

* feat: default to source if config.projectRoot is not specified, update examples and readme

* fix: update the simple template

* docs: clarify init in readme

* docs: change readme numbering to back to 1

* refactor: dont default projectRoot to source

* docs: make extensive example use makeFlakeOutputs, link per-pkgs d2n example in readme

* fix: call loadConfig correctly
2022-06-01 22:53:46 +02:00

135 lines
3.4 KiB
Nix

# like ./default.nix but system intependent
# (allows to generate outputs for several systems)
# follows flake output schema
{
nixpkgsSrc,
lib,
overridesDirs,
externalSources,
externalPaths,
} @ args: let
l = lib // builtins;
initDream2nix = config: pkgs:
import ./default.nix
{inherit config pkgs externalPaths externalSources;};
loadConfig = config'': let
config' = (import ./utils/config.nix).loadConfig config'';
config =
config'
// {
overridesDirs = args.overridesDirs ++ config'.overridesDirs;
};
in
config;
# TODO: design output schema for cross compiled packages
makePkgsKey = pkgs: let
build = pkgs.buildPlatform.system;
host = pkgs.hostPlatform.system;
in
if build == host
then build
else throw "cross compiling currently not supported";
makeNixpkgs = pkgsList: systems:
# fail if neither pkgs nor systems are defined
if pkgsList == null && systems == []
then throw "Either `systems` or `pkgs` must be defined"
# fail if pkgs and systems are both defined
else if pkgsList != null && systems != []
then throw "Define either `systems` or `pkgs`, not both"
# only pkgs is specified
else if pkgsList != null
then
if l.isList pkgsList
then
l.listToAttrs
(pkgs: l.nameValuePair (makePkgsKey pkgs) pkgs)
pkgsList
else {"${makePkgsKey pkgsList}" = pkgsList;}
# only systems is specified
else
l.genAttrs systems
(system: import nixpkgsSrc {inherit system;});
flakifyBuilderOutputs = system: outputs:
l.mapAttrs
(_: outputValue: {"${system}" = outputValue;})
outputs;
init = {
pkgs ? throw "please pass 'pkgs' (a nixpkgs instance) to 'init'",
config ? {},
}:
initDream2nix (loadConfig config) pkgs;
makeFlakeOutputs = {
source,
pkgs ? null,
systems ? [],
config ? {},
inject ? {},
pname ? throw "Please pass `pname` to makeFlakeOutputs",
packageOverrides ? {},
settings ? [],
sourceOverrides ? oldSources: {},
translator ? null,
translatorArgs ? {},
} @ args: let
allPkgs = makeNixpkgs pkgs systems;
config = loadConfig (args.config or {});
dlib = import ./lib {inherit lib config;};
initD2N = initDream2nix config;
dream2nixFor = l.mapAttrs (_: pkgs: initD2N pkgs) allPkgs;
discoveredProjects = dlib.discoverers.discoverProjects {
inherit settings;
tree = dlib.prepareSourceTree {inherit source;};
};
allBuilderOutputs =
l.mapAttrs
(system: pkgs: let
dream2nix = dream2nixFor."${system}";
allOutputs = dream2nix.makeOutputs {
inherit
source
pname
discoveredProjects
settings
sourceOverrides
packageOverrides
inject
;
};
in
allOutputs)
allPkgs;
flakifiedOutputsList =
l.mapAttrsToList
(system: outputs: flakifyBuilderOutputs system outputs)
allBuilderOutputs;
flakeOutputsBuilders =
l.foldl'
(allOutputs: output: lib.recursiveUpdate allOutputs output)
{}
flakifiedOutputsList;
flakeOutputs =
{projectsJson = l.toJSON discoveredProjects;}
// flakeOutputsBuilders;
in
flakeOutputs;
in {
inherit init makeFlakeOutputs;
dlib = import ./lib {inherit lib;};
riseAndShine = throw "Use makeFlakeOutputs instead of riseAndShine.";
}