use flake-compat
This commit is contained in:
parent
8d210f27df
commit
13927a91ad
4 changed files with 13 additions and 582 deletions
282
default.nix
282
default.nix
|
@ -1,270 +1,14 @@
|
||||||
# Compatibility function to allow flakes to be used by
|
(
|
||||||
# non-flake-enabled Nix versions. Given a source tree containing a
|
import
|
||||||
# 'flake.nix' and 'flake.lock' file, it fetches the flake inputs and
|
(
|
||||||
# calls the flake's 'outputs' function. It then returns an attrset
|
let
|
||||||
# containing 'defaultNix' (to be used in 'default.nix'), 'shellNix'
|
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
|
||||||
# (to be used in 'shell.nix').
|
in
|
||||||
let
|
fetchTarball {
|
||||||
src = ./.;
|
url = lock.nodes.flake-compat.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||||
system = builtins.currentSystem or "unknown-system";
|
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||||
|
|
||||||
lockFilePath = src + "/flake.lock";
|
|
||||||
|
|
||||||
lockFile = builtins.fromJSON (builtins.readFile lockFilePath);
|
|
||||||
|
|
||||||
fetchTree = info:
|
|
||||||
if info.type == "github"
|
|
||||||
then {
|
|
||||||
outPath =
|
|
||||||
fetchTarball
|
|
||||||
(
|
|
||||||
{url = "https://api.${info.host or "github.com"}/repos/${info.owner}/${info.repo}/tarball/${info.rev}";}
|
|
||||||
// (
|
|
||||||
if info ? narHash
|
|
||||||
then {sha256 = info.narHash;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rev = info.rev;
|
|
||||||
shortRev = builtins.substring 0 7 info.rev;
|
|
||||||
lastModified = info.lastModified;
|
|
||||||
lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
|
|
||||||
narHash = info.narHash;
|
|
||||||
}
|
|
||||||
else if info.type == "git"
|
|
||||||
then
|
|
||||||
{
|
|
||||||
outPath =
|
|
||||||
builtins.fetchGit
|
|
||||||
(
|
|
||||||
{url = info.url;}
|
|
||||||
// (
|
|
||||||
if info ? rev
|
|
||||||
then {inherit (info) rev;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
// (
|
|
||||||
if info ? ref
|
|
||||||
then {inherit (info) ref;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
// (
|
|
||||||
if info ? submodules
|
|
||||||
then {inherit (info) submodules;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
lastModified = info.lastModified;
|
|
||||||
lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
|
|
||||||
narHash = info.narHash;
|
|
||||||
}
|
}
|
||||||
// (
|
)
|
||||||
if info ? rev
|
{src = ./.;}
|
||||||
then {
|
)
|
||||||
rev = info.rev;
|
.defaultNix
|
||||||
shortRev = builtins.substring 0 7 info.rev;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else if info.type == "path"
|
|
||||||
then {
|
|
||||||
outPath = builtins.path {path = info.path;};
|
|
||||||
narHash = info.narHash;
|
|
||||||
}
|
|
||||||
else if info.type == "tarball"
|
|
||||||
then {
|
|
||||||
outPath =
|
|
||||||
fetchTarball
|
|
||||||
(
|
|
||||||
{inherit (info) url;}
|
|
||||||
// (
|
|
||||||
if info ? narHash
|
|
||||||
then {sha256 = info.narHash;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if info.type == "gitlab"
|
|
||||||
then {
|
|
||||||
inherit (info) rev narHash lastModified;
|
|
||||||
outPath =
|
|
||||||
fetchTarball
|
|
||||||
(
|
|
||||||
{url = "https://${info.host or "gitlab.com"}/api/v4/projects/${info.owner}%2F${info.repo}/repository/archive.tar.gz?sha=${info.rev}";}
|
|
||||||
// (
|
|
||||||
if info ? narHash
|
|
||||||
then {sha256 = info.narHash;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
shortRev = builtins.substring 0 7 info.rev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# FIXME: add Mercurial, tarball inputs.
|
|
||||||
throw "flake input has unsupported input type '${info.type}'";
|
|
||||||
|
|
||||||
callFlake4 = flakeSrc: locks: let
|
|
||||||
flake = import (flakeSrc + "/flake.nix");
|
|
||||||
|
|
||||||
inputs = builtins.mapAttrs (n: v:
|
|
||||||
if v.flake or true
|
|
||||||
then callFlake4 (fetchTree (v.locked // v.info)) v.inputs
|
|
||||||
else fetchTree (v.locked // v.info))
|
|
||||||
locks;
|
|
||||||
|
|
||||||
outputs = flakeSrc // (flake.outputs (inputs // {self = outputs;}));
|
|
||||||
in
|
|
||||||
assert flake.edition == 201909; outputs;
|
|
||||||
|
|
||||||
callLocklessFlake = flakeSrc: let
|
|
||||||
flake = import (flakeSrc + "/flake.nix");
|
|
||||||
outputs = flakeSrc // (flake.outputs {self = outputs;});
|
|
||||||
in
|
|
||||||
outputs;
|
|
||||||
|
|
||||||
rootSrc = let
|
|
||||||
# Try to clean the source tree by using fetchGit, if this source
|
|
||||||
# tree is a valid git repository.
|
|
||||||
tryFetchGit = src:
|
|
||||||
if isGit && !isShallow
|
|
||||||
then let
|
|
||||||
res = builtins.fetchGit src;
|
|
||||||
in
|
|
||||||
if res.rev == "0000000000000000000000000000000000000000"
|
|
||||||
then removeAttrs res ["rev" "shortRev"]
|
|
||||||
else res
|
|
||||||
else {outPath = src;};
|
|
||||||
# NB git worktrees have a file for .git, so we don't check the type of .git
|
|
||||||
isGit = builtins.pathExists (src + "/.git");
|
|
||||||
isShallow = builtins.pathExists (src + "/.git/shallow");
|
|
||||||
in
|
|
||||||
{
|
|
||||||
lastModified = 0;
|
|
||||||
lastModifiedDate = formatSecondsSinceEpoch 0;
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if src ? outPath
|
|
||||||
then src
|
|
||||||
else tryFetchGit src
|
|
||||||
);
|
|
||||||
|
|
||||||
# Format number of seconds in the Unix epoch as %Y%m%d%H%M%S.
|
|
||||||
formatSecondsSinceEpoch = t: let
|
|
||||||
rem = x: y: x - x / y * y;
|
|
||||||
days = t / 86400;
|
|
||||||
secondsInDay = rem t 86400;
|
|
||||||
hours = secondsInDay / 3600;
|
|
||||||
minutes = (rem secondsInDay 3600) / 60;
|
|
||||||
seconds = rem t 60;
|
|
||||||
|
|
||||||
# Courtesy of https://stackoverflow.com/a/32158604.
|
|
||||||
z = days + 719468;
|
|
||||||
era =
|
|
||||||
(
|
|
||||||
if z >= 0
|
|
||||||
then z
|
|
||||||
else z - 146096
|
|
||||||
)
|
|
||||||
/ 146097;
|
|
||||||
doe = z - era * 146097;
|
|
||||||
yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
|
|
||||||
y = yoe + era * 400;
|
|
||||||
doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
|
|
||||||
mp = (5 * doy + 2) / 153;
|
|
||||||
d = doy - (153 * mp + 2) / 5 + 1;
|
|
||||||
m =
|
|
||||||
mp
|
|
||||||
+ (
|
|
||||||
if mp < 10
|
|
||||||
then 3
|
|
||||||
else -9
|
|
||||||
);
|
|
||||||
y' =
|
|
||||||
y
|
|
||||||
+ (
|
|
||||||
if m <= 2
|
|
||||||
then 1
|
|
||||||
else 0
|
|
||||||
);
|
|
||||||
|
|
||||||
pad = s:
|
|
||||||
if builtins.stringLength s < 2
|
|
||||||
then "0" + s
|
|
||||||
else s;
|
|
||||||
in "${toString y'}${pad (toString m)}${pad (toString d)}${pad (toString hours)}${pad (toString minutes)}${pad (toString seconds)}";
|
|
||||||
|
|
||||||
allNodes =
|
|
||||||
builtins.mapAttrs
|
|
||||||
(
|
|
||||||
key: node: let
|
|
||||||
sourceInfo =
|
|
||||||
if key == lockFile.root
|
|
||||||
then rootSrc
|
|
||||||
else fetchTree (node.info or {} // removeAttrs node.locked ["dir"]);
|
|
||||||
|
|
||||||
subdir =
|
|
||||||
if key == lockFile.root
|
|
||||||
then ""
|
|
||||||
else node.locked.dir or "";
|
|
||||||
|
|
||||||
flake = import (sourceInfo
|
|
||||||
+ (
|
|
||||||
if subdir != ""
|
|
||||||
then "/"
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
+ subdir
|
|
||||||
+ "/flake.nix");
|
|
||||||
|
|
||||||
inputs =
|
|
||||||
builtins.mapAttrs
|
|
||||||
(inputName: inputSpec: allNodes.${resolveInput inputSpec})
|
|
||||||
(node.inputs or {});
|
|
||||||
|
|
||||||
# Resolve a input spec into a node name. An input spec is
|
|
||||||
# either a node name, or a 'follows' path from the root
|
|
||||||
# node.
|
|
||||||
resolveInput = inputSpec:
|
|
||||||
if builtins.isList inputSpec
|
|
||||||
then getInputByPath lockFile.root inputSpec
|
|
||||||
else inputSpec;
|
|
||||||
|
|
||||||
# Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the
|
|
||||||
# root node, returning the final node.
|
|
||||||
getInputByPath = nodeName: path:
|
|
||||||
if path == []
|
|
||||||
then nodeName
|
|
||||||
else
|
|
||||||
getInputByPath
|
|
||||||
# Since this could be a 'follows' input, call resolveInput.
|
|
||||||
(resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path})
|
|
||||||
(builtins.tail path);
|
|
||||||
|
|
||||||
outputs = flake.outputs (inputs // {self = result;});
|
|
||||||
|
|
||||||
result =
|
|
||||||
outputs
|
|
||||||
// sourceInfo
|
|
||||||
// {
|
|
||||||
inherit inputs;
|
|
||||||
inherit outputs;
|
|
||||||
inherit sourceInfo;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
if node.flake or true
|
|
||||||
then assert builtins.isFunction flake.outputs; result
|
|
||||||
else sourceInfo
|
|
||||||
)
|
|
||||||
lockFile.nodes;
|
|
||||||
|
|
||||||
result =
|
|
||||||
if !(builtins.pathExists lockFilePath)
|
|
||||||
then callLocklessFlake rootSrc
|
|
||||||
else if lockFile.version == 4
|
|
||||||
then callFlake4 rootSrc (lockFile.inputs)
|
|
||||||
else if lockFile.version >= 5 && lockFile.version <= 7
|
|
||||||
then allNodes.${lockFile.root}
|
|
||||||
else throw "lock file '${lockFilePath}' has unsupported version ${toString lockFile.version}";
|
|
||||||
in
|
|
||||||
result.outputs
|
|
||||||
|
|
17
flake.lock
17
flake.lock
|
@ -756,22 +756,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixtoo_2": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1705305545,
|
|
||||||
"narHash": "sha256-MVRHAg37r26AsGhzfAi8Vbx0Feg55ry8Xvh/o+tgn88=",
|
|
||||||
"owner": "DarkKirb",
|
|
||||||
"repo": "nixtoo",
|
|
||||||
"rev": "3497ab586c6ad35d2cd7ed30b74c1299130ef10a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "DarkKirb",
|
|
||||||
"repo": "nixtoo",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"admin-fe": "admin-fe",
|
"admin-fe": "admin-fe",
|
||||||
|
@ -797,7 +781,6 @@
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
"nixos-vscode-server": "nixos-vscode-server",
|
"nixos-vscode-server": "nixos-vscode-server",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixtoo": "nixtoo_2",
|
|
||||||
"rust-overlay": "rust-overlay",
|
"rust-overlay": "rust-overlay",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"systems": "systems_2"
|
"systems": "systems_2"
|
||||||
|
|
|
@ -9,21 +9,18 @@ rec {
|
||||||
inputs.devshell.follows = "devshell";
|
inputs.devshell.follows = "devshell";
|
||||||
inputs.flake-parts.follows = "flake-parts";
|
inputs.flake-parts.follows = "flake-parts";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.nixtoo.follows = "nixtoo";
|
|
||||||
};
|
};
|
||||||
akkoma = {
|
akkoma = {
|
||||||
url = "github:DarkKirb/akkoma";
|
url = "github:DarkKirb/akkoma";
|
||||||
inputs.devshell.follows = "devshell";
|
inputs.devshell.follows = "devshell";
|
||||||
inputs.flake-parts.follows = "flake-parts";
|
inputs.flake-parts.follows = "flake-parts";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.nixtoo.follows = "nixtoo";
|
|
||||||
};
|
};
|
||||||
akkoma-fe = {
|
akkoma-fe = {
|
||||||
url = "github:DarkKirb/akkoma-fe";
|
url = "github:DarkKirb/akkoma-fe";
|
||||||
inputs.devshell.follows = "devshell";
|
inputs.devshell.follows = "devshell";
|
||||||
inputs.flake-parts.follows = "flake-parts";
|
inputs.flake-parts.follows = "flake-parts";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.nixtoo.follows = "nixtoo";
|
|
||||||
};
|
};
|
||||||
attic = {
|
attic = {
|
||||||
url = "github:DarkKirb/attic";
|
url = "github:DarkKirb/attic";
|
||||||
|
@ -63,7 +60,6 @@ rec {
|
||||||
inputs.devshell.follows = "devshell";
|
inputs.devshell.follows = "devshell";
|
||||||
inputs.flake-parts.follows = "flake-parts";
|
inputs.flake-parts.follows = "flake-parts";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.nixtoo.follows = "nixtoo";
|
|
||||||
};
|
};
|
||||||
firefox = {
|
firefox = {
|
||||||
url = "github:nix-community/flake-firefox-nightly";
|
url = "github:nix-community/flake-firefox-nightly";
|
||||||
|
@ -121,8 +117,6 @@ rec {
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs";
|
nixpkgs.url = "github:NixOS/nixpkgs";
|
||||||
nixtoo.url = "github:DarkKirb/nixtoo";
|
|
||||||
nixtoo.flake = false;
|
|
||||||
rust-overlay = {
|
rust-overlay = {
|
||||||
url = "github:oxalica/rust-overlay";
|
url = "github:oxalica/rust-overlay";
|
||||||
inputs.flake-utils.follows = "flake-utils";
|
inputs.flake-utils.follows = "flake-utils";
|
||||||
|
|
290
resolve-jobs.nix
290
resolve-jobs.nix
|
@ -1,290 +0,0 @@
|
||||||
# Compatibility function to allow flakes to be used by
|
|
||||||
# non-flake-enabled Nix versions. Given a source tree containing a
|
|
||||||
# 'flake.nix' and 'flake.lock' file, it fetches the flake inputs and
|
|
||||||
# calls the flake's 'outputs' function. It then returns an attrset
|
|
||||||
# containing 'defaultNix' (to be used in 'default.nix'), 'shellNix'
|
|
||||||
# (to be used in 'shell.nix').
|
|
||||||
let
|
|
||||||
inherit (builtins) attrNames listToAttrs;
|
|
||||||
|
|
||||||
mapAttrs' = f: set:
|
|
||||||
listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
|
|
||||||
|
|
||||||
flake_compat = src: let
|
|
||||||
lockFilePath = src + "/flake.lock";
|
|
||||||
|
|
||||||
lockFile = builtins.fromJSON (builtins.readFile lockFilePath);
|
|
||||||
|
|
||||||
fetchTree = info:
|
|
||||||
if info.type == "github"
|
|
||||||
then {
|
|
||||||
outPath =
|
|
||||||
fetchTarball
|
|
||||||
(
|
|
||||||
{url = "https://api.${info.host or "github.com"}/repos/${info.owner}/${info.repo}/tarball/${info.rev}";}
|
|
||||||
// (
|
|
||||||
if info ? narHash
|
|
||||||
then {sha256 = info.narHash;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
inherit (info) rev;
|
|
||||||
shortRev = builtins.substring 0 7 info.rev;
|
|
||||||
inherit (info) lastModified;
|
|
||||||
lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
|
|
||||||
inherit (info) narHash;
|
|
||||||
}
|
|
||||||
else if info.type == "git"
|
|
||||||
then
|
|
||||||
{
|
|
||||||
outPath =
|
|
||||||
builtins.fetchGit
|
|
||||||
(
|
|
||||||
{inherit (info) url;}
|
|
||||||
// (
|
|
||||||
if info ? rev
|
|
||||||
then {inherit (info) rev;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
// (
|
|
||||||
if info ? ref
|
|
||||||
then {inherit (info) ref;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
// (
|
|
||||||
if info ? submodules
|
|
||||||
then {inherit (info) submodules;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
inherit (info) lastModified;
|
|
||||||
lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
|
|
||||||
inherit (info) narHash;
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if info ? rev
|
|
||||||
then {
|
|
||||||
inherit (info) rev;
|
|
||||||
shortRev = builtins.substring 0 7 info.rev;
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
else if info.type == "path"
|
|
||||||
then {
|
|
||||||
outPath = builtins.path {inherit (info) path;};
|
|
||||||
inherit (info) narHash;
|
|
||||||
}
|
|
||||||
else if info.type == "tarball"
|
|
||||||
then {
|
|
||||||
outPath =
|
|
||||||
fetchTarball
|
|
||||||
(
|
|
||||||
{inherit (info) url;}
|
|
||||||
// (
|
|
||||||
if info ? narHash
|
|
||||||
then {sha256 = info.narHash;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if info.type == "gitlab"
|
|
||||||
then {
|
|
||||||
inherit (info) rev narHash lastModified;
|
|
||||||
outPath =
|
|
||||||
fetchTarball
|
|
||||||
(
|
|
||||||
{url = "https://${info.host or "gitlab.com"}/api/v4/projects/${info.owner}%2F${info.repo}/repository/archive.tar.gz?sha=${info.rev}";}
|
|
||||||
// (
|
|
||||||
if info ? narHash
|
|
||||||
then {sha256 = info.narHash;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
shortRev = builtins.substring 0 7 info.rev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# FIXME: add Mercurial, tarball inputs.
|
|
||||||
throw "flake input has unsupported input type '${info.type}'";
|
|
||||||
|
|
||||||
callFlake4 = flakeSrc: locks: let
|
|
||||||
flake = import (flakeSrc + "/flake.nix");
|
|
||||||
|
|
||||||
inputs =
|
|
||||||
builtins.mapAttrs
|
|
||||||
(n: v:
|
|
||||||
if v.flake or true
|
|
||||||
then callFlake4 (fetchTree (v.locked // v.info)) v.inputs
|
|
||||||
else fetchTree (v.locked // v.info))
|
|
||||||
locks;
|
|
||||||
|
|
||||||
outputs = flakeSrc // (flake.outputs (inputs // {self = outputs;}));
|
|
||||||
in
|
|
||||||
assert flake.edition == 201909; outputs;
|
|
||||||
|
|
||||||
callLocklessFlake = flakeSrc: let
|
|
||||||
flake = import (flakeSrc + "/flake.nix");
|
|
||||||
outputs = flakeSrc // (flake.outputs {self = outputs;});
|
|
||||||
in
|
|
||||||
outputs;
|
|
||||||
|
|
||||||
rootSrc = let
|
|
||||||
# Try to clean the source tree by using fetchGit, if this source
|
|
||||||
# tree is a valid git repository.
|
|
||||||
tryFetchGit = src:
|
|
||||||
if isGit && !isShallow
|
|
||||||
then let
|
|
||||||
res = builtins.fetchGit src;
|
|
||||||
in
|
|
||||||
if res.rev == "0000000000000000000000000000000000000000"
|
|
||||||
then removeAttrs res ["rev" "shortRev"]
|
|
||||||
else res
|
|
||||||
else {outPath = src;};
|
|
||||||
# NB git worktrees have a file for .git, so we don't check the type of .git
|
|
||||||
isGit = builtins.pathExists (src + "/.git");
|
|
||||||
isShallow = builtins.pathExists (src + "/.git/shallow");
|
|
||||||
in
|
|
||||||
{
|
|
||||||
lastModified = 0;
|
|
||||||
lastModifiedDate = formatSecondsSinceEpoch 0;
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if src ? outPath
|
|
||||||
then src
|
|
||||||
else tryFetchGit src
|
|
||||||
);
|
|
||||||
|
|
||||||
# Format number of seconds in the Unix epoch as %Y%m%d%H%M%S.
|
|
||||||
formatSecondsSinceEpoch = t: let
|
|
||||||
rem = x: y: x - x / y * y;
|
|
||||||
days = t / 86400;
|
|
||||||
secondsInDay = rem t 86400;
|
|
||||||
hours = secondsInDay / 3600;
|
|
||||||
minutes = (rem secondsInDay 3600) / 60;
|
|
||||||
seconds = rem t 60;
|
|
||||||
|
|
||||||
# Courtesy of https://stackoverflow.com/a/32158604.
|
|
||||||
z = days + 719468;
|
|
||||||
era =
|
|
||||||
(
|
|
||||||
if z >= 0
|
|
||||||
then z
|
|
||||||
else z - 146096
|
|
||||||
)
|
|
||||||
/ 146097;
|
|
||||||
doe = z - era * 146097;
|
|
||||||
yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
|
|
||||||
y = yoe + era * 400;
|
|
||||||
doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
|
|
||||||
mp = (5 * doy + 2) / 153;
|
|
||||||
d = doy - (153 * mp + 2) / 5 + 1;
|
|
||||||
m =
|
|
||||||
mp
|
|
||||||
+ (
|
|
||||||
if mp < 10
|
|
||||||
then 3
|
|
||||||
else -9
|
|
||||||
);
|
|
||||||
y' =
|
|
||||||
y
|
|
||||||
+ (
|
|
||||||
if m <= 2
|
|
||||||
then 1
|
|
||||||
else 0
|
|
||||||
);
|
|
||||||
|
|
||||||
pad = s:
|
|
||||||
if builtins.stringLength s < 2
|
|
||||||
then "0" + s
|
|
||||||
else s;
|
|
||||||
in "${toString y'}${pad (toString m)}${pad (toString d)}${pad (toString hours)}${pad (toString minutes)}${pad (toString seconds)}";
|
|
||||||
|
|
||||||
allNodes =
|
|
||||||
builtins.mapAttrs
|
|
||||||
(
|
|
||||||
key: node: let
|
|
||||||
sourceInfo =
|
|
||||||
if key == lockFile.root
|
|
||||||
then rootSrc
|
|
||||||
else fetchTree (node.info or {} // removeAttrs node.locked ["dir"]);
|
|
||||||
|
|
||||||
subdir =
|
|
||||||
if key == lockFile.root
|
|
||||||
then ""
|
|
||||||
else node.locked.dir or "";
|
|
||||||
|
|
||||||
flake = import (sourceInfo
|
|
||||||
+ (
|
|
||||||
if subdir != ""
|
|
||||||
then "/"
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
+ subdir
|
|
||||||
+ "/flake.nix");
|
|
||||||
|
|
||||||
inputs =
|
|
||||||
builtins.mapAttrs
|
|
||||||
(inputName: inputSpec: allNodes.${resolveInput inputSpec})
|
|
||||||
(node.inputs or {});
|
|
||||||
|
|
||||||
# Resolve a input spec into a node name. An input spec is
|
|
||||||
# either a node name, or a 'follows' path from the root
|
|
||||||
# node.
|
|
||||||
resolveInput = inputSpec:
|
|
||||||
if builtins.isList inputSpec
|
|
||||||
then getInputByPath lockFile.root inputSpec
|
|
||||||
else inputSpec;
|
|
||||||
|
|
||||||
# Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the
|
|
||||||
# root node, returning the final node.
|
|
||||||
getInputByPath = nodeName: path:
|
|
||||||
if path == []
|
|
||||||
then nodeName
|
|
||||||
else
|
|
||||||
getInputByPath
|
|
||||||
# Since this could be a 'follows' input, call resolveInput.
|
|
||||||
(resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path})
|
|
||||||
(builtins.tail path);
|
|
||||||
|
|
||||||
outputs = flake.outputs (inputs // {self = result;});
|
|
||||||
|
|
||||||
result =
|
|
||||||
outputs
|
|
||||||
// sourceInfo
|
|
||||||
// {
|
|
||||||
inherit inputs;
|
|
||||||
inherit outputs;
|
|
||||||
inherit sourceInfo;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
if node.flake or true
|
|
||||||
then assert builtins.isFunction flake.outputs; result
|
|
||||||
else sourceInfo
|
|
||||||
)
|
|
||||||
lockFile.nodes;
|
|
||||||
|
|
||||||
result =
|
|
||||||
if !(builtins.pathExists lockFilePath)
|
|
||||||
then callLocklessFlake rootSrc
|
|
||||||
else if lockFile.version == 4
|
|
||||||
then callFlake4 rootSrc lockFile.inputs
|
|
||||||
else if lockFile.version >= 5 && lockFile.version <= 7
|
|
||||||
then allNodes.${lockFile.root}
|
|
||||||
else throw "lock file '${lockFilePath}' has unsupported version ${toString lockFile.version}";
|
|
||||||
in
|
|
||||||
result.hydraJobs;
|
|
||||||
|
|
||||||
prs = builtins.fromJSON (builtins.readFile <prs>);
|
|
||||||
srcs =
|
|
||||||
mapAttrs'
|
|
||||||
(n: value: {
|
|
||||||
name = "pr${n}";
|
|
||||||
value =
|
|
||||||
builtins.fetchGit
|
|
||||||
{
|
|
||||||
url = "https://github.com/${value.head.repo.owner.login}/${value.head.repo.name}.git";
|
|
||||||
ref = "${value.head.ref}";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
prs;
|
|
||||||
in
|
|
||||||
builtins.mapAttrs (_: flake_compat) srcs
|
|
Loading…
Reference in a new issue