This is a little helper that Graham cobbled together at one point, it will filter an exact list of files. Change-Id: Iab786abcd4a7a3cce45a20b2950f103defa91998 Reviewed-on: https://cl.tvl.fyi/c/depot/+/5332 Reviewed-by: Profpatsch <mail@profpatsch.de> Tested-by: BuildkiteCI
		
			
				
	
	
		
			90 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ ... }:
 | 
						|
# SPDX-License-Identifier: MIT
 | 
						|
# Created by Graham Christensen
 | 
						|
# version from https://github.com/grahamc/mayday/blob/c48f7583e622fe2e695a2a929de34679e5818816/exact-source.nix
 | 
						|
 | 
						|
let
 | 
						|
  # Require that every path specified does exist.
 | 
						|
  #
 | 
						|
  # By default, Nix won't complain if you refer to a missing file
 | 
						|
  # if you don't actually use it:
 | 
						|
  #
 | 
						|
  #     nix-repl> ./bogus
 | 
						|
  #     /home/grahamc/playground/bogus
 | 
						|
  #
 | 
						|
  #     nix-repl> toString ./bogus
 | 
						|
  #     "/home/grahamc/playground/bogus"
 | 
						|
  #
 | 
						|
  # so in order for this interface to be *exact*, we must
 | 
						|
  # specifically require every provided path exists:
 | 
						|
  #
 | 
						|
  #     nix-repl> "${./bogus}"
 | 
						|
  #     error: getting attributes of path
 | 
						|
  #     '/home/grahamc/playground/bogus': No such file or
 | 
						|
  #     directory
 | 
						|
  requireAllPathsExist = paths:
 | 
						|
    let
 | 
						|
      validation = builtins.map (path: "${path}") paths;
 | 
						|
    in
 | 
						|
    builtins.deepSeq validation paths;
 | 
						|
 | 
						|
  # Break down a given path in to a list of all of the path and
 | 
						|
  # its parent directories.
 | 
						|
  #
 | 
						|
  # `builtins.path` / `builtins.filterSource` will ask about
 | 
						|
  # a containing directory, and we must say YES otherwise it will
 | 
						|
  # not include anything below it.
 | 
						|
  #
 | 
						|
  # Concretely, convert: "/foo/baz/tux" in to:
 | 
						|
  #     [ "/foo/baz/tux" "/foo/baz" "/foo" ]
 | 
						|
  recursivelyPopDir = path:
 | 
						|
    if path == "/" then [ ]
 | 
						|
    else [ path ] ++ (recursivelyPopDir (builtins.dirOf path));
 | 
						|
 | 
						|
  # Given a list of of strings, dedup the list and return a
 | 
						|
  # list of all unique strings.
 | 
						|
  #
 | 
						|
  # Note: only works on strings ;):
 | 
						|
  #
 | 
						|
  # First convert [ "foo" "foo" "bar" ] in to:
 | 
						|
  #     [
 | 
						|
  #       { name = "foo"; value = ""; }
 | 
						|
  #       { name = "foo"; value = ""; }
 | 
						|
  #       { name = "bar"; value = ""; }
 | 
						|
  #     ]
 | 
						|
  # then convert that to { "foo" = ""; "bar" = ""; }
 | 
						|
  # then get the attribute names, "foo" and "bar".
 | 
						|
  dedup = strings:
 | 
						|
    let
 | 
						|
      name_value_pairs = builtins.map
 | 
						|
        (string: { name = string; value = ""; })
 | 
						|
        strings;
 | 
						|
      attrset_of_strings = builtins.listToAttrs name_value_pairs;
 | 
						|
    in
 | 
						|
    builtins.attrNames attrset_of_strings;
 | 
						|
 | 
						|
  exactSource = source_root: paths:
 | 
						|
    let
 | 
						|
      all_possible_paths =
 | 
						|
        let
 | 
						|
          # Convert all the paths in to relative paths on disk.
 | 
						|
          # ie: stringPaths will contain [ "/home/grahamc/playground/..." ];
 | 
						|
          # instead of /nix/store paths.
 | 
						|
          string_paths = builtins.map toString
 | 
						|
            (requireAllPathsExist paths);
 | 
						|
 | 
						|
          all_paths_with_duplicates = builtins.concatMap
 | 
						|
            recursivelyPopDir
 | 
						|
            string_paths;
 | 
						|
        in
 | 
						|
        dedup all_paths_with_duplicates;
 | 
						|
 | 
						|
      pathIsSpecified = path:
 | 
						|
        builtins.elem path all_possible_paths;
 | 
						|
    in
 | 
						|
    builtins.path {
 | 
						|
      path = source_root;
 | 
						|
      filter = (path: _type: pathIsSpecified path);
 | 
						|
    };
 | 
						|
in
 | 
						|
exactSource
 |