Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

101 linhas
4.2 KiB

  1. # Functions for copying sources to the Nix store.
  2. { lib }:
  3. rec {
  4. # Returns the type of a path: regular (for file), symlink, or directory
  5. pathType = p: with builtins; getAttr (baseNameOf p) (readDir (dirOf p));
  6. # Returns true if the path exists and is a directory, false otherwise
  7. pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false;
  8. # Bring in a path as a source, filtering out all Subversion and CVS
  9. # directories, as well as backup files (*~).
  10. cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! (
  11. # Filter out Subversion and CVS directories.
  12. (type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
  13. # Filter out editor backup / swap files.
  14. lib.hasSuffix "~" baseName ||
  15. builtins.match "^\\.sw[a-z]$" baseName != null ||
  16. builtins.match "^\\..*\\.sw[a-z]$" baseName != null ||
  17. # Filter out generates files.
  18. lib.hasSuffix ".o" baseName ||
  19. lib.hasSuffix ".so" baseName ||
  20. # Filter out nix-build result symlinks
  21. (type == "symlink" && lib.hasPrefix "result" baseName)
  22. );
  23. cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };
  24. # Like `builtins.filterSource`, except it will compose with itself,
  25. # allowing you to chain multiple calls together without any
  26. # intermediate copies being put in the nix store.
  27. #
  28. # lib.cleanSourceWith f (lib.cleanSourceWith g ./.) # Succeeds!
  29. # builtins.filterSource f (builtins.filterSource g ./.) # Fails!
  30. cleanSourceWith = { filter, src }:
  31. let
  32. isFiltered = src ? _isLibCleanSourceWith;
  33. origSrc = if isFiltered then src.origSrc else src;
  34. filter' = if isFiltered then name: type: filter name type && src.filter name type else filter;
  35. in {
  36. inherit origSrc;
  37. filter = filter';
  38. outPath = builtins.filterSource filter' origSrc;
  39. _isLibCleanSourceWith = true;
  40. };
  41. # Filter sources by a list of regular expressions.
  42. #
  43. # E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
  44. sourceByRegex = src: regexes: cleanSourceWith {
  45. filter = (path: type:
  46. let relPath = lib.removePrefix (toString src + "/") (toString path);
  47. in lib.any (re: builtins.match re relPath != null) regexes);
  48. inherit src;
  49. };
  50. # Get all files ending with the specified suffices from the given
  51. # directory or its descendants. E.g. `sourceFilesBySuffices ./dir
  52. # [".xml" ".c"]'.
  53. sourceFilesBySuffices = path: exts:
  54. let filter = name: type:
  55. let base = baseNameOf (toString name);
  56. in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
  57. in cleanSourceWith { inherit filter; src = path; };
  58. # Get the commit id of a git repo
  59. # Example: commitIdFromGitRepo <nixpkgs/.git>
  60. commitIdFromGitRepo =
  61. let readCommitFromFile = path: file:
  62. with builtins;
  63. let fileName = toString path + "/" + file;
  64. packedRefsName = toString path + "/packed-refs";
  65. in if lib.pathExists fileName
  66. then
  67. let fileContent = lib.fileContents fileName;
  68. # Sometimes git stores the commitId directly in the file but
  69. # sometimes it stores something like: «ref: refs/heads/branch-name»
  70. matchRef = match "^ref: (.*)$" fileContent;
  71. in if isNull matchRef
  72. then fileContent
  73. else readCommitFromFile path (lib.head matchRef)
  74. # Sometimes, the file isn't there at all and has been packed away in the
  75. # packed-refs file, so we have to grep through it:
  76. else if lib.pathExists packedRefsName
  77. then
  78. let fileContent = readFile packedRefsName;
  79. matchRef = match (".*\n([^\n ]*) " + file + "\n.*") fileContent;
  80. in if isNull matchRef
  81. then throw ("Could not find " + file + " in " + packedRefsName)
  82. else lib.head matchRef
  83. else throw ("Not a .git directory: " + path);
  84. in lib.flip readCommitFromFile "HEAD";
  85. pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir);
  86. canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
  87. }