2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# Functions for copying sources to the Nix store.
							 | 
						
					
						
							
								
									
										
										
										
											2017-07-28 20:05:35 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{ lib }:
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								let
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  inherit (builtins)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    hasContext
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    match
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    readDir
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-30 23:15:07 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    split
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    storeDir
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    tryEval
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  inherit (lib)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    filter
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    getAttr
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    isString
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    pathExists
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-22 13:57:23 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    readFile
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    ;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								in
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								rec {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-06-02 16:03:35 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  # Returns the type of a path: regular (for file), symlink, or directory
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  pathType = p: getAttr (baseNameOf p) (readDir (dirOf p));
							 | 
						
					
						
							
								
									
										
										
										
											2016-06-02 16:03:35 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Returns true if the path exists and is a directory, false otherwise
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  pathIsDirectory = p: if pathExists p then (pathType p) == "directory" else false;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-10 21:24:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  # Returns true if the path exists and is a regular file, false otherwise
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  pathIsRegularFile = p: if pathExists p then (pathType p) == "regular" else false;
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-10 21:24:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Bring in a path as a source, filtering out all Subversion and CVS
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # directories, as well as backup files (*~).
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-17 22:21:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! (
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-02 18:01:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # Filter out version control software files/directories
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    (baseName == ".git" || type == "directory" && (baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-12 14:50:12 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # Filter out editor backup / swap files.
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-17 22:21:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    lib.hasSuffix "~" baseName ||
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    match "^\\.sw[a-z]$" baseName != null ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    match "^\\..*\\.sw[a-z]$" baseName != null ||
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-29 20:27:04 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-17 22:21:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # Filter out generates files.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib.hasSuffix ".o" baseName ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib.hasSuffix ".so" baseName ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Filter out nix-build result symlinks
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    (type == "symlink" && lib.hasPrefix "result" baseName)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-30 18:13:16 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  # Filters a source tree removing version control files and directories using cleanSourceWith
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Example:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #          cleanSource ./.
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-02 00:29:20 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Like `builtins.filterSource`, except it will compose with itself,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # allowing you to chain multiple calls together without any
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # intermediate copies being put in the nix store.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-03 10:36:57 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  #     lib.cleanSourceWith {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #       filter = f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #       src = lib.cleanSourceWith {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #         filter = g;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #         src = ./.;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #       };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #     }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #     # Succeeds!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #     builtins.filterSource f (builtins.filterSource g ./.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #     # Fails!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Parameters:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #   src:      A path or cleanSourceWith result to filter and/or rename.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #   filter:   A function (path -> type -> bool)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #             Optional with default value: constant true (include everything)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #             The function will be combined with the && operator such
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #             that src.filter is called lazily.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #             For implementing a filter, see
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #             https://nixos.org/nix/manual/#builtin-filterSource
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #   name:     Optional name to use as part of the store path.
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												cleanSourceWith: don't use baseNameOf
Currently, not providing `name` to `cleanSourceWith` will use the name
of the imported directory. However, a common case is for this to be the
top level of some repository. In that case, the name will be the name of
the checkout on the current machine, which is not necessarily
reproducible across different settings, and can lead to e.g. cache
misses in CI.
This is documented in the comment on `cleanSourceWith`, but this does
not stop it being a subtle trap for users.
There are different tradeoffs in each case:
1. If `cleanSourceWith` defaults to `"source"`, then we may end up with a
user not knowing what directory a source store path corresponds to.
However, it being called "unnamed" may give them a clue that there is a
way for them to name it, and lead them to the definition of the
function, which has a clear `name` parameter.
2. If `cleanSoureWith` defaults to the directory name, then a user may face
occasional loss of caching, which is hard to notice, and hard to track
down. Tracking it down likely requires use of more advanced tools like
`nix-diff`, and reading the source of a lot of nix code.
I think the downside of the status quo is worse.
This is really another iteration of
https://github.com/NixOS/nix/issues/1305: that led to adding the `name`
argument in the first place, this just makes us use a better default
`name`.
											
										 
										
											2020-03-23 09:26:12 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  #             This defaults to `src.name` or otherwise `"source"`.
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-03 10:36:57 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  cleanSourceWith = { filter ? _path: _type: true, src, name ? null }:
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-02 00:29:20 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      isFiltered = src ? _isLibCleanSourceWith;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      origSrc = if isFiltered then src.origSrc else src;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      filter' = if isFiltered then name: type: filter name type && src.filter name type else filter;
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												cleanSourceWith: don't use baseNameOf
Currently, not providing `name` to `cleanSourceWith` will use the name
of the imported directory. However, a common case is for this to be the
top level of some repository. In that case, the name will be the name of
the checkout on the current machine, which is not necessarily
reproducible across different settings, and can lead to e.g. cache
misses in CI.
This is documented in the comment on `cleanSourceWith`, but this does
not stop it being a subtle trap for users.
There are different tradeoffs in each case:
1. If `cleanSourceWith` defaults to `"source"`, then we may end up with a
user not knowing what directory a source store path corresponds to.
However, it being called "unnamed" may give them a clue that there is a
way for them to name it, and lead them to the definition of the
function, which has a clear `name` parameter.
2. If `cleanSoureWith` defaults to the directory name, then a user may face
occasional loss of caching, which is hard to notice, and hard to track
down. Tracking it down likely requires use of more advanced tools like
`nix-diff`, and reading the source of a lot of nix code.
I think the downside of the status quo is worse.
This is really another iteration of
https://github.com/NixOS/nix/issues/1305: that led to adding the `name`
argument in the first place, this just makes us use a better default
`name`.
											
										 
										
											2020-03-23 09:26:12 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      name' = if name != null then name else if isFiltered then src.name else "source";
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-02 00:29:20 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    in {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      inherit origSrc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      filter = filter';
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-03 10:36:57 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      outPath = builtins.path { filter = filter'; path = origSrc; name = name'; };
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-02 00:29:20 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      _isLibCleanSourceWith = true;
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-03 10:36:57 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      name = name';
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-02 00:29:20 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-17 18:56:39 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  # Filter sources by a list of regular expressions.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-19 16:23:11 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  sourceByRegex = src: regexes:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      isFiltered = src ? _isLibCleanSourceWith;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      origSrc = if isFiltered then src.origSrc else src;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    in lib.cleanSourceWith {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      filter = (path: type:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        let relPath = lib.removePrefix (toString origSrc + "/") (toString path);
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        in lib.any (re: match re relPath != null) regexes);
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-19 16:23:11 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      inherit src;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Get all files ending with the specified suffices from the given
							 | 
						
					
						
							
								
									
										
										
										
											2014-08-25 14:33:17 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  # directory or its descendants.  E.g. `sourceFilesBySuffices ./dir
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # [".xml" ".c"]'.
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  sourceFilesBySuffices = path: exts:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let filter = name: type:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      let base = baseNameOf (toString name);
							 | 
						
					
						
							
								
									
										
										
										
											2014-08-25 14:33:17 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-02 00:29:20 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    in cleanSourceWith { inherit filter; src = path; };
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  pathIsGitRepo = path: (tryEval (commitIdFromGitRepo path)).success;
							 | 
						
					
						
							
								
									
										
										
										
											2016-06-02 16:03:35 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-24 23:34:28 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  # Get the commit id of a git repo
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Example: commitIdFromGitRepo <nixpkgs/.git>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  commitIdFromGitRepo =
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-07 09:07:42 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let readCommitFromFile = file: path:
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-24 23:34:28 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        let fileName       = toString path + "/" + file;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            packedRefsName = toString path + "/packed-refs";
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-14 21:08:38 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            absolutePath   = base: path:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              if lib.hasPrefix "/" path
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              then path
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              else toString (/. + "${base}/${path}");
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-10 21:24:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        in if pathIsRegularFile path
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           # Resolve git worktrees. See gitrepository-layout(5)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           then
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								             let m   = match "^gitdir: (.*)$" (lib.fileContents path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								             in if m == null
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                then throw ("File contains no gitdir reference: " + path)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-27 21:16:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                  let gitDir      = absolutePath (dirOf path) (lib.head m);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      commonDir'' = if pathIsRegularFile "${gitDir}/commondir"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    then lib.fileContents "${gitDir}/commondir"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    else gitDir;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      commonDir'  = lib.removeSuffix "/" commonDir'';
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      commonDir   = absolutePath gitDir commonDir';
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      refFile     = lib.removePrefix "${commonDir}/" "${gitDir}/${file}";
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-10 21:24:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                  in readCommitFromFile refFile commonDir
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           else if pathIsRegularFile fileName
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           # Sometimes git stores the commitId directly in the file but
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           # sometimes it stores something like: «ref: refs/heads/branch-name»
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-24 23:34:28 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								           then
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-31 21:58:54 +09:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								             let fileContent = lib.fileContents fileName;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                 matchRef    = match "^ref: (.*)$" fileContent;
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-10 21:24:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								             in if  matchRef == null
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-31 21:58:54 +09:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                then fileContent
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-07 09:07:42 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                else readCommitFromFile (lib.head matchRef) path
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-10 21:24:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           else if pathIsRegularFile packedRefsName
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-24 23:34:28 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								           # Sometimes, the file isn't there at all and has been packed away in the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           # packed-refs file, so we have to grep through it:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           then
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-27 15:44:26 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								             let fileContent = readFile packedRefsName;
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                 matchRef = match "([a-z0-9]+) ${file}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                 isRef = s: isString s && (matchRef s) != null;
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-17 10:38:38 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                 # there is a bug in libstdc++ leading to stackoverflow for long strings:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                 # https://github.com/NixOS/nix/issues/2147#issuecomment-659868795
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                 refs = filter isRef (split "\n" fileContent);
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-17 10:38:38 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								             in if refs == []
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-27 15:44:26 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                then throw ("Could not find " + file + " in " + packedRefsName)
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-17 10:38:38 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                else lib.head (matchRef (lib.head refs))
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-10 21:24:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-24 23:34:28 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								           else throw ("Not a .git directory: " + path);
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-07 09:07:42 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    in readCommitFromFile "HEAD";
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 10:17:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-20 13:47:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  pathHasContext = builtins.hasContext or (lib.hasPrefix storeDir);
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 10:17:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |