1# Functions for copying sources to the Nix store.
2
3let lib = import ./default.nix; in
4
5rec {
6
7 # Returns the type of a path: regular (for file), symlink, or directory
8 pathType = p: with builtins; getAttr (baseNameOf p) (readDir (dirOf p));
9
10 # Returns true if the path exists and is a directory, false otherwise
11 pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false;
12
13 # Bring in a path as a source, filtering out all Subversion and CVS
14 # directories, as well as backup files (*~).
15 cleanSource =
16 let filter = name: type: let baseName = baseNameOf (toString name); in ! (
17 # Filter out Subversion and CVS directories.
18 (type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
19 # Filter out backup files.
20 lib.hasSuffix "~" baseName ||
21 # Filter out generates files.
22 lib.hasSuffix ".o" baseName ||
23 lib.hasSuffix ".so" baseName ||
24 # Filter out nix-build result symlinks
25 (type == "symlink" && lib.hasPrefix "result" baseName)
26 );
27 in src: builtins.filterSource filter src;
28
29
30 # Get all files ending with the specified suffices from the given
31 # directory or its descendants. E.g. `sourceFilesBySuffices ./dir
32 # [".xml" ".c"]'.
33 sourceFilesBySuffices = path: exts:
34 let filter = name: type:
35 let base = baseNameOf (toString name);
36 in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
37 in builtins.filterSource filter path;
38
39
40 # Get the commit id of a git repo
41 # Example: commitIdFromGitRepo <nixpkgs/.git>
42 commitIdFromGitRepo =
43 let readCommitFromFile = path: file:
44 with builtins;
45 let fileName = toString path + "/" + file;
46 packedRefsName = toString path + "/packed-refs";
47 in if lib.pathExists fileName
48 then
49 let fileContent = lib.fileContents fileName;
50 # Sometimes git stores the commitId directly in the file but
51 # sometimes it stores something like: «ref: refs/heads/branch-name»
52 matchRef = match "^ref: (.*)$" fileContent;
53 in if isNull matchRef
54 then fileContent
55 else readCommitFromFile path (lib.head matchRef)
56 # Sometimes, the file isn't there at all and has been packed away in the
57 # packed-refs file, so we have to grep through it:
58 else if lib.pathExists packedRefsName
59 then
60 let fileContent = readFile packedRefsName;
61 matchRef = match (".*\n([^\n ]*) " + file + "\n.*") fileContent;
62 in if isNull matchRef
63 then throw ("Could not find " + file + " in " + packedRefsName)
64 else lib.head matchRef
65 else throw ("Not a .git directory: " + path);
66 in lib.flip readCommitFromFile "HEAD";
67}