Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{
2 lib,
3 stdenvNoCC,
4 git,
5 git-lfs,
6 cacert,
7}:
8
9let
10 urlToName =
11 url: rev:
12 let
13 shortRev = lib.sources.shortRev rev;
14 appendShort = lib.optionalString ((builtins.match "[a-f0-9]*" rev) != null) "-${shortRev}";
15 in
16 "${lib.sources.urlToName url}${appendShort}";
17in
18
19lib.makeOverridable (
20 lib.fetchers.withNormalizedHash { } (
21 # NOTE Please document parameter additions or changes in
22 # ../../../doc/build-helpers/fetchers.chapter.md
23 {
24 url,
25 tag ? null,
26 rev ? null,
27 name ? urlToName url (lib.revOrTag rev tag),
28 leaveDotGit ? deepClone || fetchTags,
29 outputHash ? lib.fakeHash,
30 outputHashAlgo ? null,
31 fetchSubmodules ? true,
32 deepClone ? false,
33 branchName ? null,
34 sparseCheckout ? [ ],
35 nonConeMode ? false,
36 nativeBuildInputs ? [ ],
37 # Shell code executed before the file has been fetched. This, in
38 # particular, can do things like set NIX_PREFETCH_GIT_CHECKOUT_HOOK to
39 # run operations between the checkout completing and deleting the .git
40 # directory.
41 preFetch ? "",
42 # Shell code executed after the file has been fetched
43 # successfully. This can do things like check or transform the file.
44 postFetch ? "",
45 preferLocalBuild ? true,
46 fetchLFS ? false,
47 # Shell code to build a netrc file for BASIC auth
48 netrcPhase ? null,
49 # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes)
50 # needed for netrcPhase
51 netrcImpureEnvVars ? [ ],
52 meta ? { },
53 allowedRequisites ? null,
54 # fetch all tags after tree (useful for git describe)
55 fetchTags ? false,
56 }:
57
58 /*
59 NOTE:
60 fetchgit has one problem: git fetch only works for refs.
61 This is because fetching arbitrary (maybe dangling) commits creates garbage collection risks
62 and checking whether a commit belongs to a ref is expensive. This may
63 change in the future when some caching is added to git (?)
64 Usually refs are either tags (refs/tags/*) or branches (refs/heads/*)
65 Cloning branches will make the hash check fail when there is an update.
66 But not all patches we want can be accessed by tags.
67
68 The workaround is getting the last n commits so that it's likely that they
69 still contain the hash we want.
70
71 for now : increase depth iteratively (TODO)
72
73 real fix: ask git folks to add a
74 git fetch $HASH contained in $BRANCH
75 facility because checking that $HASH is contained in $BRANCH is less
76 expensive than fetching --depth $N.
77 Even if git folks implemented this feature soon it may take years until
78 server admins start using the new version?
79 */
80
81 assert nonConeMode -> (sparseCheckout != [ ]);
82 assert fetchTags -> leaveDotGit;
83
84 let
85 revWithTag =
86 let
87 warningMsg = "fetchgit requires one of either `rev` or `tag` to be provided (not both).";
88 otherIsNull = other: lib.assertMsg (other == null) warningMsg;
89 in
90 if tag != null then
91 assert (otherIsNull rev);
92 "refs/tags/${tag}"
93 else if rev != null then
94 assert (otherIsNull tag);
95 rev
96 else
97 # FIXME fetching HEAD if no rev or tag is provided is problematic at best
98 "HEAD";
99 in
100
101 if builtins.isString sparseCheckout then
102 # Changed to throw on 2023-06-04
103 throw
104 "Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more."
105 else
106 stdenvNoCC.mkDerivation {
107 inherit name;
108
109 builder = ./builder.sh;
110 fetcher = ./nix-prefetch-git;
111
112 nativeBuildInputs = [
113 git
114 cacert
115 ]
116 ++ lib.optionals fetchLFS [ git-lfs ]
117 ++ nativeBuildInputs;
118
119 inherit outputHash outputHashAlgo;
120 outputHashMode = "recursive";
121
122 # git-sparse-checkout(1) says:
123 # > When the --stdin option is provided, the directories or patterns are read
124 # > from standard in as a newline-delimited list instead of from the arguments.
125 sparseCheckout = builtins.concatStringsSep "\n" sparseCheckout;
126
127 inherit
128 url
129 leaveDotGit
130 fetchLFS
131 fetchSubmodules
132 deepClone
133 branchName
134 nonConeMode
135 preFetch
136 postFetch
137 fetchTags
138 ;
139 rev = revWithTag;
140
141 postHook =
142 if netrcPhase == null then
143 null
144 else
145 ''
146 ${netrcPhase}
147 # required that git uses the netrc file
148 mv {,.}netrc
149 export NETRC=$PWD/.netrc
150 export HOME=$PWD
151 '';
152
153 impureEnvVars =
154 lib.fetchers.proxyImpureEnvVars
155 ++ netrcImpureEnvVars
156 ++ [
157 "GIT_PROXY_COMMAND"
158 "NIX_GIT_SSL_CAINFO"
159 "SOCKS_SERVER"
160
161 # This is a parameter intended to be set by setup hooks or preFetch
162 # scripts that want per-URL control over HTTP proxies used by Git
163 # (if per-URL control isn't needed, `http_proxy` etc. will
164 # suffice). It must be a whitespace-separated (with backslash as an
165 # escape character) list of pairs like this:
166 #
167 # http://domain1/path1 proxy1 https://domain2/path2 proxy2
168 #
169 # where the URLs are as documented in the `git-config` manual page
170 # under `http.<url>.*`, and the proxies are as documented on the
171 # same page under `http.proxy`.
172 "FETCHGIT_HTTP_PROXIES"
173 ];
174
175 inherit preferLocalBuild meta allowedRequisites;
176
177 passthru = {
178 gitRepoUrl = url;
179 inherit tag;
180 };
181 }
182 )
183)