on iko/ghcjs-patch-master help sign in
Use `subDir` not `src` to construct default names (#506)

When no name is provided to `cleanSourceWith` or `cleanGit` we currently use `baseNameOf src` as a default. This was cute, but it lead to cache misses. For instance if `x = cleanSourceWith { src = ./.; }` then `baseName src` will be different when `src` resolves to "/nix/store/X" than when it is in a local directory. If people use git worktrees they also may wind up with different values for `name`. Anything that depends on `x.name` will propagate the issue. This change uses `subDir` if present or if it is not it encourages adding a suitable `name` with a warning message.

commit0aa17d8afc083e20e529766349f09ff9ffcd1b1e authorHamish Mackenzie <Hamish.Mackenzie@iohk.io> dateWed 25 Mar 2020, 13:45 (7 years ago) parentda071af
2 files changed+45−10
lib/clean-git.nix+6 lib/clean-source-with.nix+39−10
lib/clean-git.nix+6
@@ -59,6 +59,8 @@ then
5959
6060 # Identify the .git directory and filter just the files that we need.
6161 gitDir = cleanSourceWith ({
62+ caller = "cleanGit";
63+ name = (if name == null then "" else name + "-") + "gitFiles";
6264 filter = path: type:
6365 type == "directory" ||
6466 lib.any (i: (lib.hasSuffix i path)) [
@@ -102,6 +104,8 @@ then
102104 gitModules = builtins.path { name = "gitmodules"; path = gitModulesStr; };
103105
104106 gitSubmoduleFiles = cleanSourceWith {
107+ caller = "cleanGit";
108+ name = (if name == null then "" else name + "-") + "gitSubmoduleFiles";
105109 inherit src;
106110 filter = path: type:
107111 type == "directory" # TODO get sudmodule directories from `.gitmodules`
@@ -143,12 +147,14 @@ then
143147 filter = filter_from_list src whitelist;
144148 in
145149 cleanSourceWith {
150+ caller = "cleanGit";
146151 inherit name src subDir filter;
147152 }
148153
149154else
150155 trace "gitSource.nix: ${toString src} does not seem to be a git repository,\nassuming it is a clean checkout." (
151156 cleanSourceWith {
157+ caller = "cleanGit";
152158 inherit name src subDir;
153159 }
154160 )
lib/clean-source-with.nix+39−10
@@ -32,18 +32,25 @@
3232 # https://nixos.org/nix/manual/#builtin-filterSource
3333 #
3434 # subDir: Descend into a subdirectory in a way that will compose.
35− # It will be ase if `src = src + "/${subDir}` and filters
35+ # It will be as if `src = src + "/${subDir}` and filters
3636 # already applied to `src` will be respected.
3737 #
3838 # name: Optional name to use as part of the store path.
39− # This defaults `src.name` or otherwise `baseNameOf src`.
40− # We recommend setting `name` whenever `src` is syntactically `./.`.
41− # Otherwise, you depend on `./.`'s name in the parent directory,
42− # which can cause inconsistent names, defeating caching.
39+ # If you do not provide a `name` it wil be derived
40+ # from the `subDir`. You should provide `name` or
41+ # `subDir`. If you do not a warning will be displayed
42+ # and the name used will be `source`.
4343 #
44− cleanSourceWith = { filter ? _path: _type: true, src, subDir ? "", name ? null }:
44+ # caller: Name of the function used in warning message.
45+ # Functions that are implemented using `cleanSourceWith`
46+ # (and forward a `name` argument) can use this to make
47+ # the message to the use more meaningful.
48+ #
49+ cleanSourceWith = { filter ? _path: _type: true, src, subDir ? "", name ? null
50+ , caller ? "cleanSourceWith" }:
4551 let
4652 subDir' = if subDir == "" then "" else "/" + subDir;
53+ subDirName = __replaceStrings ["/"] ["-"] subDir;
4754 # In case this is mixed with older versions of cleanSourceWith
4855 isFiltered = src ? _isLibCleanSourceWith;
4956 isFilteredEx = src ? _isLibCleanSourceWithEx;
@@ -62,10 +69,32 @@
6269 && (filter path type && parentFilter path type));
6370 name' = if name != null
6471 then name
65− else (if isFiltered && src ? name
66− then src.name
67− else baseNameOf src)
68− + (lib.optionalString (origSubDir != "") ("--" + baseNameOf origSubDir));
72+ else
73+ if subDirName != ""
74+ then if src ? name
75+ then src.name + "-" + subDirName
76+ else "source-" + subDirName
77+ else if src ? name
78+ then src.name
79+ else
80+ # No name was provided and one could not be constructed from
81+ # the `subDirName`.
82+
83+ # We used to use `baseNameOf src` as a default here.
84+ # This was cute, but it lead to cache misses. For instance if
85+ # `x = cleanSourceWith { src = ./.; }` then `baseName src`
86+ # will be different when `src` resolves to "/nix/store/X"
87+ # than when it is in a local directory. If people use
88+ # git worktrees they also may wind up with different
89+ # values for `name`. Anything that depends on `x.name` will
90+ # propagate the issue.
91+
92+ # Encourage adding a suitable `name` with:
93+ # * A warning message.
94+ # * A default name that gives a hint as to why there is no name.
95+ __trace (
96+ "WARNING: `${caller}` called on ${toString src} without a `name`. "
97+ + "Consider adding `name = \"${baseNameOf src};\"`") "source";
6998 in {
7099 inherit origSrc origSubDir origSrcSubDir;
71100 filter = filter';