2022-02-08 07:03:12 +03:00
|
|
|
{ downloadCargoPackageFromGit
|
|
|
|
, lib
|
|
|
|
, runCommandLocal
|
|
|
|
}:
|
|
|
|
|
|
|
|
{ lockPackages
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
inherit (builtins)
|
|
|
|
any
|
|
|
|
attrNames
|
|
|
|
filter
|
|
|
|
hashString
|
|
|
|
head
|
|
|
|
isString
|
|
|
|
listToAttrs
|
2022-02-10 07:54:56 +03:00
|
|
|
placeholder
|
2022-02-08 07:03:12 +03:00
|
|
|
split;
|
|
|
|
|
|
|
|
inherit (lib)
|
|
|
|
concatMapStrings
|
|
|
|
concatStrings
|
2022-06-08 00:51:20 +03:00
|
|
|
groupBy
|
2022-02-08 07:03:12 +03:00
|
|
|
hasPrefix
|
|
|
|
last
|
|
|
|
mapAttrs'
|
|
|
|
mapAttrsToList
|
|
|
|
nameValuePair
|
|
|
|
removePrefix;
|
|
|
|
|
|
|
|
knownGitParams = [ "branch" "rev" "tag" ];
|
|
|
|
parseGitUrl = lockUrl:
|
|
|
|
let
|
|
|
|
revSplit = split "#" (removePrefix "git+" lockUrl);
|
|
|
|
# uniquely identifies the repo in terms of what cargo can address via
|
|
|
|
# source replacement (e.g. the url along with any branch/tag/rev).
|
|
|
|
id = head revSplit;
|
|
|
|
# NB: this is distict from the `rev` query param which may show up
|
|
|
|
# if the dependency is explicitly listed with a `rev` value.
|
|
|
|
lockedRev = last revSplit;
|
|
|
|
|
|
|
|
querySplit = split "\\?" (head revSplit);
|
|
|
|
git = head querySplit;
|
|
|
|
|
|
|
|
queryParamSplit = filter
|
|
|
|
(qp: (isString qp) && any (p: hasPrefix p qp) knownGitParams)
|
|
|
|
(split "&" (last querySplit));
|
|
|
|
extractedParams = listToAttrs (map
|
|
|
|
(qp:
|
|
|
|
let
|
|
|
|
kvSplit = (split "=" qp);
|
|
|
|
in
|
|
|
|
nameValuePair (head kvSplit) (last kvSplit)
|
|
|
|
)
|
|
|
|
queryParamSplit
|
|
|
|
);
|
|
|
|
in
|
|
|
|
extractedParams // {
|
|
|
|
inherit git id lockedRev;
|
|
|
|
};
|
|
|
|
|
|
|
|
hash = hashString "sha256";
|
|
|
|
|
|
|
|
# Local crates will show up in the lock file with no checksum/source
|
|
|
|
lockedPackagesFromGit = filter
|
|
|
|
(p: hasPrefix "git" (p.source or ""))
|
|
|
|
lockPackages;
|
|
|
|
lockedGitGroups = groupBy (p: p.id) (map
|
|
|
|
(p: (parseGitUrl p.source) // { package = p; })
|
|
|
|
lockedPackagesFromGit
|
|
|
|
);
|
|
|
|
|
2022-02-11 07:32:31 +03:00
|
|
|
sources = mapAttrs'
|
|
|
|
(id: ps:
|
|
|
|
let
|
|
|
|
p = head ps;
|
2022-02-19 04:46:05 +03:00
|
|
|
ref =
|
|
|
|
if p ? tag then "refs/tags/${p.tag}"
|
|
|
|
else if p ? branch then "refs/heads/${p.branch}"
|
|
|
|
else null;
|
2022-02-11 07:32:31 +03:00
|
|
|
in
|
|
|
|
nameValuePair (hash id) (downloadCargoPackageFromGit {
|
2022-02-08 07:03:12 +03:00
|
|
|
inherit (p) git;
|
2022-02-19 04:46:05 +03:00
|
|
|
inherit ref;
|
2022-02-08 07:03:12 +03:00
|
|
|
rev = p.lockedRev;
|
2022-02-11 07:32:31 +03:00
|
|
|
})
|
|
|
|
)
|
2022-02-08 07:03:12 +03:00
|
|
|
lockedGitGroups;
|
|
|
|
|
|
|
|
configLocalSources = concatMapStrings
|
|
|
|
(hashedId: ''
|
|
|
|
[source.nix-sources-${hashedId}]
|
2022-02-10 07:54:56 +03:00
|
|
|
directory = "${placeholder "out"}/${hashedId}"
|
2022-02-08 07:03:12 +03:00
|
|
|
'')
|
|
|
|
(attrNames sources);
|
|
|
|
|
|
|
|
configReplaceGitSources = mapAttrsToList
|
|
|
|
(hashedId: ps:
|
|
|
|
let
|
|
|
|
p = head ps;
|
|
|
|
extractAttr = attr:
|
|
|
|
if p ? ${attr} then ''
|
|
|
|
${attr} = "${p.${attr}}"
|
|
|
|
'' else "";
|
|
|
|
sourceValues = concatMapStrings extractAttr ([ "git" ] ++ knownGitParams);
|
|
|
|
in
|
|
|
|
''
|
2022-02-10 07:22:07 +03:00
|
|
|
[source."${p.id}"]
|
2022-02-08 07:03:12 +03:00
|
|
|
replace-with = "nix-sources-${hash p.id}"
|
|
|
|
${sourceValues}
|
|
|
|
''
|
|
|
|
)
|
|
|
|
lockedGitGroups;
|
|
|
|
in
|
|
|
|
{
|
|
|
|
inherit sources;
|
|
|
|
config = configLocalSources + (concatStrings configReplaceGitSources);
|
|
|
|
}
|