Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c1543d606c |
@@ -44,6 +44,8 @@ else
|
|||||||
./units-config.nix
|
./units-config.nix
|
||||||
./lix.nix
|
./lix.nix
|
||||||
./git.nix
|
./git.nix
|
||||||
|
./repos-options.nix
|
||||||
|
./repos-impl.nix
|
||||||
];
|
];
|
||||||
options = {
|
options = {
|
||||||
vacu.rootCAs = mkOption { type = types.listOf types.str; };
|
vacu.rootCAs = mkOption { type = types.listOf types.str; };
|
||||||
|
@@ -1,7 +1,30 @@
|
|||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
inherit (builtins) isList;
|
||||||
|
mkOutOption =
|
||||||
|
val:
|
||||||
|
lib.mkOption {
|
||||||
|
readOnly = true;
|
||||||
|
default = val;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
listToIndexAttrs = list:
|
||||||
|
let
|
||||||
|
thing = lib.foldl (acc: val:
|
||||||
|
{
|
||||||
|
index = acc.index + 1;
|
||||||
|
result = acc.result // { ${toString acc.index} = val; };
|
||||||
|
}
|
||||||
|
) { result = {}; index = 0; } list;
|
||||||
|
in
|
||||||
|
assert isList list;
|
||||||
|
thing.result
|
||||||
|
;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./makeWrapper.nix
|
./makeWrapper.nix
|
||||||
|
./duplicates.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
options.vacu.vaculib = lib.mkOption {
|
options.vacu.vaculib = lib.mkOption {
|
||||||
@@ -10,10 +33,8 @@
|
|||||||
|
|
||||||
config._module.args.vaculib = config.vacu.vaculib;
|
config._module.args.vaculib = config.vacu.vaculib;
|
||||||
|
|
||||||
config.vacu.vaculib.mkOutOption =
|
config.vacu.vaculib = {
|
||||||
val:
|
inherit mkOutOption;
|
||||||
lib.mkOption {
|
inherit listToIndexAttrs;
|
||||||
readOnly = true;
|
};
|
||||||
default = val;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
85
common/lib/duplicates.nix
Normal file
85
common/lib/duplicates.nix
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
vaculib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (builtins) isString isList isFunction isAttrs;
|
||||||
|
pathFromStr = str:
|
||||||
|
assert isString str;
|
||||||
|
if str == "" then [] else
|
||||||
|
lib.splitString "." str
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
For each value, make a list of each attr name that has that value.
|
||||||
|
|
||||||
|
Values must be `toString`able, and are deduped based on the output of `toString`.
|
||||||
|
|
||||||
|
# Type
|
||||||
|
```
|
||||||
|
findDuplicates :: { a :: b } -> { String :: [ a ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `vaculib.findDuplicates` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
findDuplicates { a = 1; b = 2; c = 3; x = 1; y = 2; }
|
||||||
|
=> { "1" = [ "a" "x" ]; "2" = [ "b" "y" ]; }
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
*/
|
||||||
|
findDuplicates = attrs:
|
||||||
|
let
|
||||||
|
occurances = lib.foldl (acc: name: value:
|
||||||
|
let
|
||||||
|
key = toString value;
|
||||||
|
in
|
||||||
|
acc // { ${key} = (acc.${key} or []) ++ [ name ]; }
|
||||||
|
) {} attrs;
|
||||||
|
in
|
||||||
|
assert isAttrs attrs;
|
||||||
|
lib.filterAttrs (_: names: (builtins.length names) > 1) occurances
|
||||||
|
;
|
||||||
|
|
||||||
|
# returns a list of attrSets suitable for vacu.assertions
|
||||||
|
assertNoDuplicatesModule = among: attr:
|
||||||
|
let
|
||||||
|
list_or_attrs = lib.getAttrFromPath (pathFromStr among) config;
|
||||||
|
attrs =
|
||||||
|
if isAttrs list_or_attrs
|
||||||
|
then list_or_attrs
|
||||||
|
else vaculib.listToIndexAttrs list_or_attrs
|
||||||
|
;
|
||||||
|
innerPath = pathFromStr attr;
|
||||||
|
valueMap = (v: lib.getAttrFromPath innerPath v);
|
||||||
|
duplicates = findDuplicates (lib.mapAttrs (_: valueMap) attrs);
|
||||||
|
valueName = if attr == "" then "value" else "`${attr}`";
|
||||||
|
messages = lib.mapAttrsToList (duplicate: names:
|
||||||
|
let
|
||||||
|
pretty = name: "`${name}`";
|
||||||
|
prettyNames = map pretty names;
|
||||||
|
in
|
||||||
|
"Duplicate found in ${among}: ${lib.concatStringsSep ", " prettyNames} all have the same ${valueName}: ${duplicate}"
|
||||||
|
) duplicates;
|
||||||
|
in
|
||||||
|
assert isString among;
|
||||||
|
assert isString attr;
|
||||||
|
assert (isList list_or_attrs) || (isAttrs list_or_attrs);
|
||||||
|
{
|
||||||
|
config.vacu.assertions = map (message: {
|
||||||
|
assertion = false;
|
||||||
|
inherit message;
|
||||||
|
}) messages;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config.vacu.vaculib = {
|
||||||
|
inherit findDuplicates;
|
||||||
|
inherit assertNoDuplicatesModule;
|
||||||
|
};
|
||||||
|
}
|
55
common/repos-impl.nix
Normal file
55
common/repos-impl.nix
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
vacuModuleType,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(lib.optionalAttrs (vacuModuleType == "nixos") {
|
||||||
|
config.vacu.repos.path = lib.mkIf (config.users.users ? shelvacu) (lib.mkDefault "${config.users.users.shelvacu.home}/dev");
|
||||||
|
})
|
||||||
|
(lib.optionalAttrs (vacuModuleType == "nix-on-droid") {
|
||||||
|
config.vacu.repos.path = lib.mkDefault "${config.user.home}";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
vacu.repos = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
forges.uninsane.baseUrl = "git@git.uninsane.org:";
|
||||||
|
forges.github.baseUrl = "git@github.com";
|
||||||
|
forges.gitlab.basrUrl = "git@gitlab.com";
|
||||||
|
defaultOrigin = "uninsane";
|
||||||
|
repos.colin-nix-files = {
|
||||||
|
owner = "colin";
|
||||||
|
repoName = "nix-files";
|
||||||
|
origin = "uninsane";
|
||||||
|
};
|
||||||
|
# gh:Isaac0-dev/coopnet
|
||||||
|
repos.coopnet = {
|
||||||
|
owner = "Isaac0-dev";
|
||||||
|
origin = "github";
|
||||||
|
};
|
||||||
|
repos.metadl = {};
|
||||||
|
repos.nixos-apple-silicon = {
|
||||||
|
origin = "github";
|
||||||
|
owner = "tpwrules";
|
||||||
|
};
|
||||||
|
repos.nixpkgs = {
|
||||||
|
origin = "github";
|
||||||
|
owner = "nixos";
|
||||||
|
remotes = [
|
||||||
|
{
|
||||||
|
forge = "uninsane";
|
||||||
|
owner = "colin";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
repos.nix-stuff = {};
|
||||||
|
repos.numberlink-solver = {};
|
||||||
|
repos.sm64coopdx = {
|
||||||
|
origin = "github";
|
||||||
|
owner = "coop-deluxe";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
132
common/repos-options.nix
Normal file
132
common/repos-options.nix
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
vaculib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
cfg = config.vacu.repos;
|
||||||
|
forgeModule = {
|
||||||
|
name,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
|
||||||
|
remoteName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = config.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
remoteModule = {
|
||||||
|
name,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
options = {
|
||||||
|
name = mkOption { type = types.str; default = name; };
|
||||||
|
baseUrl = mkOption { type = types.str; };
|
||||||
|
path = mkOption { type = types.str; };
|
||||||
|
url = mkOption { type = types.str; default = config.baseUrl + config.path; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
repoModule = let outercfg = cfg; in {
|
||||||
|
name,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
remoteType = (
|
||||||
|
types.coercedTo
|
||||||
|
types.str
|
||||||
|
(from: { name = from; baseUrl = config.vacu.repos.forges.${from}.url; })
|
||||||
|
(types.subModuleWith {
|
||||||
|
modules = [
|
||||||
|
remoteModule
|
||||||
|
{
|
||||||
|
config.path = lib.mkDefault config.remotePath;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
})
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
|
||||||
|
localDir = mkOption {
|
||||||
|
type = types.strMatching "[^/]+";
|
||||||
|
default = config.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
localPath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "${outercfg.path}/${config.localDir}";
|
||||||
|
};
|
||||||
|
|
||||||
|
owner = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "shelvacu";
|
||||||
|
};
|
||||||
|
|
||||||
|
remoteName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = config.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
remotePath = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "${config.owner}/${config.remoteName}";
|
||||||
|
};
|
||||||
|
|
||||||
|
origin = mkOption {
|
||||||
|
type = remoteType;
|
||||||
|
};
|
||||||
|
|
||||||
|
remotes = mkOption {
|
||||||
|
type = types.listOf remoteType;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# (vaculib.assertNoDuplicatesModule "vacu.repos" "name")
|
||||||
|
# (vaculib.assertNoDuplicatesModule "vacu.repos" "localPath")
|
||||||
|
];
|
||||||
|
|
||||||
|
options.vacu.repos = {
|
||||||
|
enable = lib.mkEnableOption "manage repos";
|
||||||
|
path = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
defaultOrigin = mkOption { type = types.str; };
|
||||||
|
forges = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrsOf (types.submoduleWith {
|
||||||
|
modules = [ forgeModule ];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
repos = mkOption {
|
||||||
|
type = types.attrsOf (types.submoduleWith { modules = [
|
||||||
|
repoModule
|
||||||
|
{ config.origin = cfg.defaultOrigin; }
|
||||||
|
]; });
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user