194 lines
4.3 KiB
Nix
194 lines
4.3 KiB
Nix
{
|
|
lib,
|
|
stdenv,
|
|
fetchurl,
|
|
fetchzip,
|
|
}@args:
|
|
|
|
let
|
|
lib = import ../extra-lib.nix {
|
|
inherit (args) lib;
|
|
};
|
|
|
|
inherit (lib)
|
|
attrNames
|
|
fakeSha256
|
|
filter
|
|
findFirst
|
|
head
|
|
isAttrs
|
|
isPath
|
|
isString
|
|
last
|
|
length
|
|
optionalAttrs
|
|
pathExists
|
|
pred
|
|
sort
|
|
switch
|
|
switch-if
|
|
versionAtLeast
|
|
versions
|
|
;
|
|
|
|
inherit (lib.strings) match split;
|
|
|
|
default-fetcher =
|
|
{
|
|
domain ? "github.com",
|
|
owner ? "",
|
|
repo,
|
|
rev,
|
|
name ? "source",
|
|
sha256 ? null,
|
|
artifact ? null,
|
|
...
|
|
}@args:
|
|
let
|
|
kind =
|
|
switch-if
|
|
[
|
|
{
|
|
cond = artifact != null;
|
|
out = {
|
|
ext = "tbz";
|
|
fmt = "tbz";
|
|
fetchfun = fetchurl;
|
|
};
|
|
}
|
|
{
|
|
cond = args ? sha256;
|
|
out = {
|
|
ext = "zip";
|
|
fmt = "zip";
|
|
fetchfun = fetchzip;
|
|
};
|
|
}
|
|
]
|
|
{
|
|
ext = "tar.gz";
|
|
fmt = "tarball";
|
|
fetchfun = builtins.fetchTarball;
|
|
};
|
|
in
|
|
with kind;
|
|
let
|
|
pr = match "^#(.*)$" rev;
|
|
url = switch-if [
|
|
{
|
|
cond = pr == null && (match "^github.*" domain) != null && artifact != null;
|
|
out = "https://github.com/${owner}/${repo}/releases/download/${rev}/${artifact}";
|
|
}
|
|
{
|
|
cond = pr == null && (match "^github.*" domain) != null;
|
|
out = "https://${domain}/${owner}/${repo}/archive/${rev}.${ext}";
|
|
}
|
|
{
|
|
cond = pr != null && (match "^github.*" domain) != null;
|
|
out = "https://api.${domain}/repos/${owner}/${repo}/${fmt}/pull/${head pr}/head";
|
|
}
|
|
{
|
|
cond = pr == null && (match "^gitlab.*" domain) != null;
|
|
out = "https://${domain}/${owner}/${repo}/-/archive/${rev}/${repo}-${rev}.${ext}";
|
|
}
|
|
{
|
|
cond = (match "(www.)?mpi-sws.org" domain) != null;
|
|
out = "https://www.mpi-sws.org/~${owner}/${repo}/download/${repo}-${rev}.${ext}";
|
|
}
|
|
] (throw "meta-fetch: no fetcher found for domain ${domain} on ${rev}");
|
|
fetch = x: fetchfun (if args ? sha256 then (x // { inherit sha256; }) else x);
|
|
in
|
|
fetch { inherit url; };
|
|
in
|
|
{
|
|
fetcher ? default-fetcher,
|
|
location,
|
|
release ? { },
|
|
releaseRev ? (v: v),
|
|
releaseArtifact ? (v: null),
|
|
}:
|
|
let
|
|
isVersion = x: isString x && match "^/.*" x == null && release ? ${x};
|
|
shortVersion =
|
|
x:
|
|
if (isString x && match "^/.*" x == null) then
|
|
findFirst (v: versions.majorMinor v == x) null (sort versionAtLeast (attrNames release))
|
|
else
|
|
null;
|
|
isShortVersion = x: shortVersion x != null;
|
|
isPathString = x: isString x && match "^/.*" x != null && pathExists x;
|
|
in
|
|
arg:
|
|
switch arg [
|
|
{
|
|
case = isNull;
|
|
out = {
|
|
version = "broken";
|
|
src = "";
|
|
broken = true;
|
|
};
|
|
}
|
|
{
|
|
case = isPathString;
|
|
out = {
|
|
version = "dev";
|
|
src = arg;
|
|
};
|
|
}
|
|
{
|
|
case = pred.union isVersion isShortVersion;
|
|
out =
|
|
let
|
|
v = if isVersion arg then arg else shortVersion arg;
|
|
given-sha256 = release.${v}.sha256 or "";
|
|
sha256 = if given-sha256 == "" then fakeSha256 else given-sha256;
|
|
rv = release.${v} // {
|
|
inherit sha256;
|
|
};
|
|
in
|
|
{
|
|
version = rv.version or v;
|
|
src = rv.src or fetcher (
|
|
location
|
|
// {
|
|
rev = releaseRev v;
|
|
artifact = releaseArtifact v;
|
|
}
|
|
// rv
|
|
);
|
|
};
|
|
}
|
|
{
|
|
case = isString;
|
|
out =
|
|
let
|
|
splitted = filter isString (split ":" arg);
|
|
rev = last splitted;
|
|
has-owner = length splitted > 1;
|
|
version = "dev";
|
|
in
|
|
{
|
|
inherit version;
|
|
src = fetcher (
|
|
location // { inherit rev; } // (optionalAttrs has-owner { owner = head splitted; })
|
|
);
|
|
};
|
|
}
|
|
{
|
|
case = isAttrs;
|
|
out = {
|
|
version = arg.version or "dev";
|
|
src = (arg.fetcher or fetcher) (location // (arg.location or { }));
|
|
};
|
|
}
|
|
{
|
|
case = isPath;
|
|
out = {
|
|
version = "dev";
|
|
src = builtins.path {
|
|
path = arg;
|
|
name = location.name or "source";
|
|
};
|
|
};
|
|
}
|
|
] (throw "not a valid source description")
|