Sometimes things that get imported are (intentionally) not attribute sets, e.g. for build functions. Those should not be merged with the marker because, well, that's not possible.
		
			
				
	
	
		
			54 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			54 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| args: initPath:
 | |
| 
 | |
| let
 | |
|   inherit (builtins)
 | |
|     attrNames
 | |
|     baseNameOf
 | |
|     filter
 | |
|     head
 | |
|     length
 | |
|     listToAttrs
 | |
|     map
 | |
|     match
 | |
|     isAttrs
 | |
|     readDir;
 | |
| 
 | |
|   argsWithPath = parts: args // {
 | |
|     locatedAt = parts;
 | |
|   };
 | |
| 
 | |
|   # 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 = readDir path;
 | |
|       self = importWithMark path parts;
 | |
|       joinChild = c: path + ("/" + c);
 | |
| 
 | |
|       # Import non-empty subdirectories
 | |
|       filterDir = f: dir."${f}" == "directory";
 | |
|       children = 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 self // (listToAttrs children)
 | |
|       else listToAttrs (nixChildren ++ children);
 | |
| in readTree initPath [ (baseNameOf initPath) ]
 |