npins/sources.nix: format

This commit is contained in:
alfarel 2026-01-15 00:04:46 +00:00
commit c7dddbb387
No known key found for this signature in database

View file

@ -12,16 +12,21 @@ let
# Backwards-compatibly make something that previously didn't take any arguments take some
# The function must return an attrset, and will unfortunately be eagerly evaluated
# Same thing, but it catches eval errors on the default argument so that one may still call it with other arguments
mkFunctor =
fn:
let
mkFunctor = fn: let
e = builtins.tryEval (fn {});
in
(if e.success then e.value else { error = fn { }; }) // { __functor = _self: fn; };
(
if e.success
then e.value
else {error = fn {};}
)
// {__functor = _self: fn;};
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
range =
first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1);
range = first: last:
if first > last
then []
else builtins.genList (n: first + n) (last - first + 1);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
@ -33,45 +38,39 @@ let
# If the environment variable NPINS_OVERRIDE_${name} is set, then use
# the path directly as opposed to the fetched source.
# (Taken from Niv for compatibility)
mayOverride =
name: path:
let
mayOverride = name: path: let
envVarName = "NPINS_OVERRIDE_${saneName}";
saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name;
saneName = stringAsChars (c:
if (builtins.match "[a-zA-Z0-9]" c) == null
then "_"
else c)
name;
ersatz = builtins.getEnv envVarName;
in
if ersatz == "" then
path
if ersatz == ""
then path
else
# this turns the string into an actual Nix path (for both absolute and
# relative paths)
builtins.trace "Overriding path of \"${name}\" with \"${ersatz}\" due to set \"${envVarName}\"" (
if builtins.substring 0 1 ersatz == "/" then
/. + ersatz
else
/. + builtins.getEnv "PWD" + "/${ersatz}"
if builtins.substring 0 1 ersatz == "/"
then /. + ersatz
else /. + builtins.getEnv "PWD" + "/${ersatz}"
);
mkSource =
name: spec:
{
pkgs ? null,
}:
assert spec ? type;
let
mkSource = name: spec: {pkgs ? null}:
assert spec ? type; let
# Unify across builtin and pkgs fetchers.
# `fetchGit` requires a wrapper because of slight API differences.
fetchers =
if pkgs == null then
{
if pkgs == null
then {
inherit (builtins) fetchTarball fetchurl;
# For some fucking reason, fetchGit has a different signature than the other builtin fetchers …
fetchGit = args: (builtins.fetchGit args).outPath;
}
else
{
fetchTarball =
{
else {
fetchTarball = {
url,
sha256,
}:
@ -80,8 +79,7 @@ let
extension = "tar";
};
inherit (pkgs) fetchurl;
fetchGit =
{
fetchGit = {
url,
submodules,
rev,
@ -97,30 +95,27 @@ let
# Dispatch to the correct code path based on the type
path =
if spec.type == "Git" then
mkGitSource fetchers spec
else if spec.type == "GitRelease" then
mkGitSource fetchers spec
else if spec.type == "PyPi" then
mkPyPiSource fetchers spec
else if spec.type == "Channel" then
mkChannelSource fetchers spec
else if spec.type == "Tarball" then
mkTarballSource fetchers spec
else if spec.type == "Container" then
mkContainerSource pkgs spec
else
builtins.throw "Unknown source type ${spec.type}";
if spec.type == "Git"
then mkGitSource fetchers spec
else if spec.type == "GitRelease"
then mkGitSource fetchers spec
else if spec.type == "PyPi"
then mkPyPiSource fetchers spec
else if spec.type == "Channel"
then mkChannelSource fetchers spec
else if spec.type == "Tarball"
then mkTarballSource fetchers spec
else if spec.type == "Container"
then mkContainerSource pkgs spec
else builtins.throw "Unknown source type ${spec.type}";
in
spec // {outPath = mayOverride name path;};
mkGitSource =
{
mkGitSource = {
fetchTarball,
fetchGit,
...
}:
{
}: {
repository,
revision,
url ? null,
@ -131,34 +126,37 @@ let
assert repository ? type;
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
# In the latter case, there we will always be an url to the tarball
if url != null && !submodules then
if url != null && !submodules
then
fetchTarball {
inherit url;
sha256 = hash;
}
else
let
else let
url =
if repository.type == "Git" then
repository.url
else if repository.type == "GitHub" then
"https://github.com/${repository.owner}/${repository.repo}.git"
else if repository.type == "GitLab" then
"${repository.server}/${repository.repo_path}.git"
else if repository.type == "Forgejo" then
"${repository.server}/${repository.owner}/${repository.repo}.git"
else
throw "Unrecognized repository type ${repository.type}";
urlToName =
url: rev:
let
if repository.type == "Git"
then repository.url
else if repository.type == "GitHub"
then "https://github.com/${repository.owner}/${repository.repo}.git"
else if repository.type == "GitLab"
then "${repository.server}/${repository.repo_path}.git"
else if repository.type == "Forgejo"
then "${repository.server}/${repository.owner}/${repository.repo}.git"
else throw "Unrecognized repository type ${repository.type}";
urlToName = url: rev: let
matched = builtins.match "^.*/([^/]*)(\\.git)?$" url;
short = builtins.substring 0 7 rev;
appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else "";
in
"${if matched == null then "source" else builtins.head matched}${appendShort}";
appendShort =
if (builtins.match "[a-f0-9]*" rev) != null
then "-${short}"
else "";
in "${
if matched == null
then "source"
else builtins.head matched
}${appendShort}";
name = urlToName url revision;
in
fetchGit {
@ -168,9 +166,7 @@ let
inherit name submodules url;
};
mkPyPiSource =
{ fetchurl, ... }:
{
mkPyPiSource = {fetchurl, ...}: {
url,
hash,
...
@ -180,9 +176,7 @@ let
sha256 = hash;
};
mkChannelSource =
{ fetchTarball, ... }:
{
mkChannelSource = {fetchTarball, ...}: {
url,
hash,
...
@ -192,9 +186,7 @@ let
sha256 = hash;
};
mkTarballSource =
{ fetchTarball, ... }:
{
mkTarballSource = {fetchTarball, ...}: {
url,
locked_url ? url,
hash,
@ -205,16 +197,14 @@ let
sha256 = hash;
};
mkContainerSource =
pkgs:
{
mkContainerSource = pkgs: {
image_name,
image_tag,
image_digest,
...
}:
if pkgs == null then
builtins.throw "container sources require passing in a Nixpkgs value: https://github.com/andir/npins/blob/master/README.md#using-the-nixpkgs-fetchers"
if pkgs == null
then builtins.throw "container sources require passing in a Nixpkgs value: https://github.com/andir/npins/blob/master/README.md#using-the-nixpkgs-fetchers"
else
pkgs.dockerTools.pullImage {
imageName = image_name;
@ -223,27 +213,22 @@ let
};
in
mkFunctor (
{
input ? ./sources.json,
}:
let
{input ? ./sources.json}: let
data =
if builtins.isPath input then
if builtins.isPath input
then
# while `readFile` will throw an error anyways if the path doesn't exist,
# we still need to check beforehand because *our* error can be caught but not the one from the builtin
# *piegames sighs*
if builtins.pathExists input then
builtins.fromJSON (builtins.readFile input)
else
throw "Input path ${toString input} does not exist"
else if builtins.isAttrs input then
input
else
throw "Unsupported input type ${builtins.typeOf input}, must be a path or an attrset";
if builtins.pathExists input
then builtins.fromJSON (builtins.readFile input)
else throw "Input path ${toString input} does not exist"
else if builtins.isAttrs input
then input
else throw "Unsupported input type ${builtins.typeOf input}, must be a path or an attrset";
version = data.version;
in
if version == 7 then
builtins.mapAttrs (name: spec: mkFunctor (mkSource name spec)) data.pins
else
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
if version == 7
then builtins.mapAttrs (name: spec: mkFunctor (mkSource name spec)) data.pins
else throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
)