forked from hswaw/hscloud
This makes all Nix files addressable from root by file path. For instance, if a file is located in //foo/bar:baz.nix containing: { pkgs, ... }: pkgs.stdenv.mkDerivation { pname = "foo"; # ... } You can then do: nix-build -A foo.bar.baz All nix files loaded this way must be a function taking a 'config' attrset - see nix/readTree.nix for more information. Currently the config attrset contains the following fields: - hscloud: the root of the hscloud repository itself, which allows for traversal via readTree (eg. hscloud.foo.bar.baz) - pkgs: nixpkgs - pkgsSrc: nixpkgs souce/channel, useful to load NixOS modules. - lib, stdenv: lib and stdenv from pkgs. Change-Id: Ieaacdcabceec18dd6c670d346928bff08b66cf79
96 lines
3.2 KiB
Nix
96 lines
3.2 KiB
Nix
# The MIT License (MIT)
|
|
#
|
|
# Copyright (c) 2019 Vincent Ambo
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
{ ... }:
|
|
|
|
args: initPath:
|
|
|
|
let
|
|
inherit (builtins)
|
|
attrNames
|
|
baseNameOf
|
|
filter
|
|
hasAttr
|
|
head
|
|
isAttrs
|
|
length
|
|
listToAttrs
|
|
map
|
|
match
|
|
readDir
|
|
substring;
|
|
|
|
argsWithPath = parts:
|
|
let meta.locatedAt = parts;
|
|
in meta // (if isAttrs args then args else args meta);
|
|
|
|
readDirVisible = path:
|
|
let
|
|
children = readDir path;
|
|
isVisible = f: f == ".skip-subtree" || (substring 0 1 f) != ".";
|
|
names = filter isVisible (attrNames children);
|
|
in listToAttrs (map (name: {
|
|
inherit name;
|
|
value = children.${name};
|
|
}) names);
|
|
|
|
# The marker is added to every set that was imported directly by
|
|
# readTree.
|
|
importWithMark = path: parts:
|
|
let imported = import path (argsWithPath parts);
|
|
in if (isAttrs imported)
|
|
then imported // { __readTree = true; }
|
|
else imported;
|
|
|
|
nixFileName = file:
|
|
let res = match "(.*)\.nix" file;
|
|
in if res == null then null else head res;
|
|
|
|
readTree = path: parts:
|
|
let
|
|
dir = readDirVisible path;
|
|
self = importWithMark path parts;
|
|
joinChild = c: path + ("/" + c);
|
|
|
|
# Import subdirectories of the current one, unless the special
|
|
# `.skip-subtree` file exists which makes readTree ignore the
|
|
# children.
|
|
#
|
|
# This file can optionally contain information on why the tree
|
|
# should be ignored, but its content is not inspected by
|
|
# readTree
|
|
filterDir = f: dir."${f}" == "directory";
|
|
children = if hasAttr ".skip-subtree" dir then [] else map (c: {
|
|
name = c;
|
|
value = readTree (joinChild c) (parts ++ [ c ]);
|
|
}) (filter filterDir (attrNames dir));
|
|
|
|
# Import Nix files
|
|
nixFiles = filter (f: f != null) (map nixFileName (attrNames dir));
|
|
nixChildren = map (c: let p = joinChild (c + ".nix"); in {
|
|
name = c;
|
|
value = importWithMark p (parts ++ [ c ]);
|
|
}) nixFiles;
|
|
in if dir ? "default.nix"
|
|
then (if isAttrs self then self // (listToAttrs children) else self)
|
|
else listToAttrs (nixChildren ++ children);
|
|
in readTree initPath [ (baseNameOf initPath) ]
|