diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-12-19 17:44:04 +0100 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-12-19 17:44:04 +0100 |
commit | 1021c1ffe1dd8dd75380dac618b93ff2cefd81f4 (patch) | |
tree | e8149b2e3cb0350d680c661fa390520ff9ca0863 | |
download | nix-library-1021c1ffe1dd8dd75380dac618b93ff2cefd81f4.zip |
chore: Initial Commit
-rw-r--r-- | by-name-overlay.nix | 76 | ||||
-rw-r--r-- | default.nix | 42 | ||||
-rw-r--r-- | flake.nix | 9 |
3 files changed, 127 insertions, 0 deletions
diff --git a/by-name-overlay.nix b/by-name-overlay.nix new file mode 100644 index 0000000..4d700a8 --- /dev/null +++ b/by-name-overlay.nix @@ -0,0 +1,76 @@ +{warn}: +# Adapted from this: https://github.com/NixOS/nixpkgs/blob/1814b56453c91192f6d5a6276079948f9fe96c18/pkgs/top-level/by-name-overlay.nix +# This file should not depend on `pkgs` and thus not use `lib`. +{ + baseDirectory, + fileName, + finalizeFunction, + coImportsNameFunction ? null, + coImportsWarnMessageObject ? null, +}: let + # Takes a list of attrs as input and returns one merged attr set. + flattenAttrs = list: + if builtins.isList list + then + builtins.foldl' (acc: elem: + if builtins.isList elem + # Merging them with `//` is okay here, as we can be sure that the attr names are + # unique (they were separate dictionary after all) + then acc // (flattenAttrs elem) + else acc // elem) {} + list + else list; + + # From nixpkgs/lib {{{ + # These functions are taken straight out of the `nixpkgs/lib`. + # We can't depended on `pkgs` (and thus on `lib`), because the `pkgs` module argument + # is only defined in the `nixpkgs` module (which is imported through this function). + mapAttrsToList = f: attrs: + builtins.map (name: f name attrs.${name}) (builtins.attrNames attrs); + + nameValuePair = name: value: {inherit name value;}; + filterAttrs = pred: set: + builtins.listToAttrs (builtins.concatMap (name: let + v = set.${name}; + in + if pred name v + then [(nameValuePair name v)] + else []) (builtins.attrNames set)); + # }}} + + # Module files for a single shard + # Type: String -> String -> ListOf Path + namesForShard = shard: type: + if type != "directory" + then warn "Ignored non-directory, whilst importing by-name directory (${fileName}): '${shard}'" {} + else let + mkPath = name: _type: let + path = baseDirectory + "/${shard}/${name}" + "/${fileName}"; + coImportPath = + if coImportsNameFunction != null + then + coImportsNameFunction + {inherit shard name;} + else path; + in + if builtins.pathExists path + then + if builtins.pathExists coImportPath + then path + else warn "'${builtins.toString coImportPath}' does not exist. Should include ${coImportsWarnMessageObject} for '${shard}/${name}'" path + else warn "'${builtins.toString path}' does not exist. Skipped" null; + in + filterAttrs (name: value: value != null) + (builtins.mapAttrs + mkPath + (builtins.readDir (baseDirectory + "/${shard}"))); + + # A list of all module paths. + # These can the be simply injected into `import` + files = flattenAttrs (mapAttrsToList namesForShard (builtins.readDir baseDirectory)); + output = + builtins.mapAttrs + finalizeFunction + files; +in + output diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..cb9f6ef --- /dev/null +++ b/default.nix @@ -0,0 +1,42 @@ +{}: let + # string -> string -> string + colorize = color: string: "[${color}m${string}[0m"; + + # Taken from `nixpkgs/lib`. + # Is here to avoid a dependency on `lib` (making this file easy to test with `nix eval`) + warn = + # Since Nix 2.23, https://github.com/NixOS/nix/pull/10592 + builtins.warn + or ( + # Do not eta reduce v, so that we have the same strictness as `builtins.warn`. + msg: v: + # `builtins.warn` requires a string message, so we enforce that in our implementation, so that callers aren't accidentally incompatible with newer Nix versions. + assert builtins.isString msg; + builtins.trace "${colorize "1;35" "evaluation warning:"} ${msg}" v + ); +in { + mkByName = import ./by-name-overlay.nix {inherit warn;}; + + # Warn while merging two attrsets if the RHS shares names with the LHS. + # # Example: + # ```nix + # let + # attr1 = {atuin = "first"; default = "second";}; + # attr2 = {atuin = "hi"; other = "hi2";}; + # in + # warnMerge attr1 attr2 "attr1 core value set" + # ``` + # # Type: + # {} -> {} -> string -> {} + warnMerge = lhs: rhs: sourceSet: let + overridden = builtins.intersectAttrs lhs rhs; + merged = lhs // rhs; + mkWarning = overriddenAttrs: + builtins.concatStringsSep " " (builtins.map (colorize "1;97") (builtins.attrNames overriddenAttrs)); + in + if overridden != {} + then + warn "Attributes overridden while merging ${sourceSet}: ${mkWarning overridden}" + merged + else merged; +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e6f5f4f --- /dev/null +++ b/flake.nix @@ -0,0 +1,9 @@ +{ + inputs = {}; + + outputs = _: let + lib = import ./default.nix {}; + in { + nixLib = lib; + }; +} |