Files
rust-overlay/lib/manifests.nix

162 lines
4.7 KiB
Nix

# Manifests which describe the content of each version.
{ lib, distRoot }:
let
inherit (builtins) match isString toString;
inherit (lib)
attrNames
concatMap
elemAt
filter
hasAttr
mapAttrs
mapAttrs'
removeSuffix
;
targets = import ../manifests/targets.nix // {
_ = "*";
};
renamesList = import ../manifests/renames.nix;
profilesList = import ../manifests/profiles.nix;
# Extensions for mixed `rust` pkg.
components = [
"rustc"
"rust-std"
"cargo"
];
singleTargetExtensions = [
"clippy-preview"
"miri-preview"
"rls-preview"
"rust-analyzer-preview"
"rustfmt-preview"
"llvm-tools-preview"
"rust-analysis"
];
multiTargetExtensions = [
"rust-std"
"rustc-dev"
"rustc-docs"
"rust-src" # This has only one special target `*`
];
rustPkgExtra =
pkgs: target:
let
singleTargetTups = map (pkg: { inherit pkg target; }) (
filter (p: hasAttr p pkgs && hasAttr target pkgs.${p}.target) singleTargetExtensions
);
multiTargetTups = concatMap (
pkg: map (target: { inherit pkg target; }) (attrNames pkgs.${pkg}.target)
) (filter (p: hasAttr p pkgs) multiTargetExtensions);
in
{
components = map (pkg: { inherit pkg target; }) components;
extensions = singleTargetTups ++ multiTargetTups;
};
# Uncompress the compressed manifest to the original one
# (not complete but has enough information to make up the toolchain).
uncompressManifest =
channel: version:
{
v, # Rustc version
d, # Date
r, # Renames index
p ? null, # Profiles index
...
}@manifest:
rec {
# Version used for derivation.
version =
if match ".*(nightly|beta).*" v != null then
"${v}-${d}" # 1.51.0-nightly-2021-01-01, 1.52.0-beta.2-2021-03-27
else
v; # 1.51.0
date = d;
renames = mapAttrs (from: to: { inherit to; }) (elemAt renamesList r);
pkg =
mapAttrs
(
pkgName:
{
# Version appears in URL
u ? null,
...
}@hashes:
{
# We use rustc version for all components to reduce manifest size.
# This version is just used for component derivation name.
version = "${v} (000000000 ${d})"; # "<version> (<commit-hash> yyyy-mm-dd)"
target =
let
results = mapAttrs' (
targetIdx: hash:
let
target = targets.${targetIdx};
pkgNameStripped = removeSuffix "-preview" pkgName;
targetTail = if targetIdx == "_" then "" else "-" + target;
urlVersion =
if u != null then
u # Use specified version for URL if exists.
else if channel == "stable" then
v # For stable channel, default to be rustc version.
else
channel; # Otherwise, for beta/nightly channel, default to be "beta"/"nightly".
in
{
name = target;
value =
# Normally, hash is just the hash.
if isString hash then
{
xz_url = "${distRoot}/${date}/${pkgNameStripped}-${urlVersion}${targetTail}.tar.xz";
xz_hash = hash;
}
// (if pkgName == "rust" then rustPkgExtra pkg target else { })
# But hash can be an integer to forward to another URL.
# This occurs in aarch64-apple-darwin rust-docs on 2022-02-02.
else
results.${targets."_${toString hash}"};
}
) (removeAttrs hashes [ "u" ]);
in
results;
}
)
(
removeAttrs manifest [
"v"
"d"
"r"
"p"
]
);
profiles = if p == null then { } else elemAt profilesList p;
targetComponentsList = [
"rust-std"
"rustc-dev"
"rustc-docs"
];
};
uncompressManifestSet =
channel: set:
let
ret = mapAttrs (uncompressManifest channel) (removeAttrs set [ "latest" ]);
in
ret // { latest = ret.${set.latest}; };
in
{
stable = uncompressManifestSet "stable" (import ../manifests/stable);
beta = uncompressManifestSet "beta" (import ../manifests/beta);
nightly = uncompressManifestSet "nightly" (import ../manifests/nightly);
}