nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 fetchurl,
5 fetchzip,
6}@args:
7
8let
9 lib = import ../extra-lib.nix {
10 inherit (args) lib;
11 };
12
13 inherit (lib)
14 attrNames
15 fakeSha256
16 filter
17 findFirst
18 head
19 isAttrs
20 isPath
21 isString
22 last
23 length
24 optionalAttrs
25 pathExists
26 pred
27 sort
28 switch
29 switch-if
30 versionOlder
31 versions
32 ;
33
34 inherit (lib.strings) match split;
35
36 default-fetcher =
37 {
38 domain ? "github.com",
39 owner ? "",
40 repo,
41 rev,
42 name ? "source",
43 sha256 ? null,
44 artifact ? null,
45 ...
46 }@args:
47 let
48 kind =
49 switch-if
50 [
51 {
52 cond = artifact != null;
53 out = {
54 ext = "tbz";
55 fmt = "tbz";
56 fetchfun = fetchurl;
57 };
58 }
59 {
60 cond = args ? sha256;
61 out = {
62 ext = "zip";
63 fmt = "zip";
64 fetchfun = fetchzip;
65 };
66 }
67 ]
68 {
69 ext = "tar.gz";
70 fmt = "tarball";
71 fetchfun = builtins.fetchTarball;
72 };
73 in
74 with kind;
75 let
76 pr = match "^#(.*)$" rev;
77 url = switch-if [
78 {
79 cond = pr == null && (match "^github.*" domain) != null && artifact != null;
80 out = "https://github.com/${owner}/${repo}/releases/download/${rev}/${artifact}";
81 }
82 {
83 cond = pr == null && (match "^github.*" domain) != null;
84 out = "https://${domain}/${owner}/${repo}/archive/${rev}.${ext}";
85 }
86 {
87 cond = pr != null && (match "^github.*" domain) != null;
88 out = "https://api.${domain}/repos/${owner}/${repo}/${fmt}/pull/${head pr}/head";
89 }
90 {
91 cond = pr == null && (match "^gitlab.*" domain) != null;
92 out = "https://${domain}/${owner}/${repo}/-/archive/${rev}/${repo}-${rev}.${ext}";
93 }
94 {
95 cond = (match "(www.)?mpi-sws.org" domain) != null;
96 out = "https://www.mpi-sws.org/~${owner}/${repo}/download/${repo}-${rev}.${ext}";
97 }
98 ] (throw "meta-fetch: no fetcher found for domain ${domain} on ${rev}");
99 fetch = x: fetchfun (if args ? sha256 then (x // { inherit sha256; }) else x);
100 in
101 fetch { inherit url; };
102in
103{
104 fetcher ? default-fetcher,
105 location,
106 release ? { },
107 releaseRev ? (v: v),
108 releaseArtifact ? (v: null),
109}:
110let
111 isVersion = x: isString x && match "^/.*" x == null && release ? ${x};
112 shortVersion =
113 x:
114 if (isString x && match "^/.*" x == null) then
115 findFirst (v: versions.majorMinor v == x) null (sort (l: r: versionOlder r l) (attrNames release))
116 else
117 null;
118 isShortVersion = x: shortVersion x != null;
119 isPathString = x: isString x && match "^/.*" x != null && pathExists x;
120in
121arg:
122switch arg [
123 {
124 case = isNull;
125 out = {
126 version = "broken";
127 src = "";
128 broken = true;
129 };
130 }
131 {
132 case = isPathString;
133 out = {
134 version = "dev";
135 src = arg;
136 };
137 }
138 {
139 case = pred.union isVersion isShortVersion;
140 out =
141 let
142 v = if isVersion arg then arg else shortVersion arg;
143 given-sha256 = release.${v}.sha256 or "";
144 sha256 = if given-sha256 == "" then fakeSha256 else given-sha256;
145 rv = release.${v} // {
146 inherit sha256;
147 };
148 in
149 {
150 version = rv.version or v;
151 src =
152 rv.src or (fetcher (
153 location
154 // {
155 rev = releaseRev v;
156 artifact = releaseArtifact v;
157 }
158 // rv
159 ));
160 };
161 }
162 {
163 case = isString;
164 out =
165 let
166 splitted = filter isString (split ":" arg);
167 rev = last splitted;
168 has-owner = length splitted > 1;
169 version = "dev";
170 in
171 {
172 inherit version;
173 src = fetcher (
174 location // { inherit rev; } // (optionalAttrs has-owner { owner = head splitted; })
175 );
176 };
177 }
178 {
179 case = isAttrs;
180 out = {
181 version = arg.version or "dev";
182 src = (arg.fetcher or fetcher) (location // (arg.location or { }));
183 };
184 }
185 {
186 case = isPath;
187 out = {
188 version = "dev";
189 src = builtins.path {
190 path = arg;
191 name = location.name or "source";
192 };
193 };
194 }
195] (throw "not a valid source description")