feat: make discoverers use modules

This commit is contained in:
Yusuf Bera Ertan 2022-09-27 21:35:49 +03:00
parent 730d42598e
commit 088fde510c
No known key found for this signature in database
GPG Key ID: 1D8F8FAF2294D6EA
18 changed files with 278 additions and 3 deletions

View File

@ -436,7 +436,7 @@ in let
translateProjects = {
discoveredProjects ?
dlib.discoverers.discoverProjects
framework.functions.discoverers.discoverProjects
{inherit projects settings tree;},
projects ? {},
source ? throw "Pass either `source` or `tree` to translateProjects",
@ -648,7 +648,7 @@ in let
makeOutputs = {
source ? throw "pass a 'source' to 'makeOutputs'",
discoveredProjects ?
dlib.discoverers.discoverProjects {
framework.functions.discoverers.discoverProjects {
inherit projects settings source;
},
pname ? null,

View File

@ -0,0 +1,6 @@
{
imports = [
./interface.nix
./implementation.nix
];
}

View File

@ -0,0 +1,65 @@
{
config,
lib,
...
}: let
l = lib // builtins;
translatorsWithDiscoverFunc =
l.filter
(translator: translator.discoverProject or null != null)
config.translators;
defaultDiscoverer.discover = {tree}: let
translatorsCurrentDir =
l.filter
(t: t.discoverProject tree)
translatorsWithDiscoverFunc;
projectsCurrentDir =
l.map
(t: {
name = "main";
relPath = tree.relPath;
translators = [t.name];
subsystem = t.subsystem;
})
translatorsCurrentDir;
# If there are multiple projects detected for the same subsystem,
# merge them to a single one with translators = [...]
projectsCurrentDirMerged =
l.attrValues
(l.foldl
(all: curr:
all
// {
"${curr.subsystem}" =
all.${curr.subsystem}
or curr
// {
translators =
l.unique (all.${curr.subsystem}.translators or [] ++ curr.translators);
};
})
{}
projectsCurrentDir);
subdirProjects =
l.flatten
(l.mapAttrsToList
(dirName: tree:
defaultDiscoverer.discover {
inherit tree;
})
tree.directories or {});
in (
if translatorsCurrentDir == []
then subdirProjects
else projectsCurrentDirMerged ++ subdirProjects
);
in {
config = {
inherit defaultDiscoverer;
};
}

View File

@ -0,0 +1,17 @@
{
lib,
specialArgs,
...
}: let
l = lib // builtins;
t = l.types;
in {
options = {
defaultDiscoverer = l.mkOption {
type = t.submoduleWith {
modules = [../discoverers/discoverer];
inherit specialArgs;
};
};
};
}

View File

@ -0,0 +1,6 @@
{
imports = [
./interface.nix
./implementation.nix
];
}

View File

@ -0,0 +1,5 @@
{
imports = [
./interface.nix
];
}

View File

@ -0,0 +1,27 @@
{
config,
lib,
...
}: let
t = lib.types;
in {
options = {
disabled = lib.mkOption {
type = t.bool;
default = false;
description = "Whether to disable the discoverer, if disabled it can't be used.";
};
name = lib.mkOption {
type = t.str;
description = "Name of the discoverer.";
};
subsystem = lib.mkOption {
type = t.str;
description = "Subsystem of the discoverer.";
};
discover = lib.mkOption {
type = t.functionTo t.attrs;
default = _: {};
};
};
}

View File

@ -0,0 +1,16 @@
{
config,
callPackageDream,
lib,
...
}: let
funcs = config.functions.subsystem-loading;
collectedModules = funcs.collect "discoverers";
in {
config = {
# The user can add more discoverers by extending this attribute
discoverers = funcs.import_ collectedModules;
discoverersBySubsystem = funcs.structureBySubsystem config.discoverers;
};
}

View File

@ -0,0 +1,22 @@
{
lib,
specialArgs,
...
}: let
t = lib.types;
in {
options = {
discoverers = lib.mkOption {
type = t.attrsOf (t.submoduleWith {
modules = [./discoverer/default.nix];
inherit specialArgs;
});
description = ''
discoverer module definitions
'';
};
discoverersBySubsystem = lib.mkOption {
type = t.attrsOf (t.attrsOf t.anything);
};
};
}

View File

@ -0,0 +1,6 @@
{
imports = [
./interface.nix
./implementation.nix
];
}

View File

@ -0,0 +1,81 @@
{
config,
dlib,
lib,
...
}: let
l = lib // builtins;
discoverProjects = {
projects,
source ? throw "Pass either `source` or `tree` to discoverProjects",
tree ? dlib.prepareSourceTree {inherit source;},
settings ? [],
}: let
discoveredProjects =
l.flatten
(
l.map
(discoverer: discoverer.discover {inherit tree;})
config.discoverers
);
discoveredProjectsSorted = let
sorted =
l.sort
(p1: p2: l.hasPrefix p1.relPath or "" p2.relPath or "")
discoveredProjects;
in
sorted;
allProjects = discoveredProjectsSorted ++ (l.attrValues projects);
rootProject = l.head allProjects;
projectsExtended =
l.forEach allProjects
(proj:
proj
// {
relPath = proj.relPath or "";
translator = proj.translator or (l.head proj.translators);
dreamLockPath = getDreamLockPath proj rootProject;
});
in
applyProjectSettings projectsExtended settings;
getDreamLockPath = project: rootProject:
dlib.sanitizeRelativePath
"${config.packagesDir}/${rootProject.name}/${project.relPath or ""}/dream-lock.json";
applyProjectSettings = projects: settingsList: let
settingsListForProject = project:
l.filter
(settings:
if ! settings ? filter
then true
else settings.filter project)
settingsList;
applySettings = project: settings:
l.recursiveUpdate project settings;
applyAllSettings = project:
l.foldl'
(proj: settings: applySettings proj settings)
project
(settingsListForProject project);
settingsApplied =
l.forEach projects (proj: applyAllSettings proj);
in
settingsApplied;
in {
functions.discoverers = {
inherit
discoverProjects
getDreamLockPath
applyProjectSettings
;
};
}

View File

@ -0,0 +1,16 @@
{lib, ...}: let
l = lib // builtins;
t = l.types;
in {
options.functions.discoverers = {
discoverProjects = l.mkOption {
type = t.functionTo (t.listOf t.attrs);
};
applyProjectSettings = l.mkOption {
type = t.functionTo (t.functionTo (t.listOf t.attrs));
};
getDreamLockPath = l.mkOption {
type = t.functionTo (t.functionTo t.path);
};
};
}

View File

@ -42,7 +42,12 @@ modules:
import_ = collectedModules:
lib.mapAttrs
(name: description:
(import description.path {inherit dlib lib;})
(
import description.path {
inherit dlib lib;
inherit (description) name subsystem;
}
)
// {inherit (description) name subsystem;})
(
lib.foldl'

View File

@ -8,8 +8,11 @@ in {
imports = [
./functions.subsystem-loading
./functions.translators
./functions.discoverers
./translators
./builders
./discoverers
./default-discoverer
];
options = {
lib = lib.mkOption {