add flake-compat for out-of-tree bc maintainer seems ded

pull/6/head
pegasust 2023-01-14 06:50:50 -07:00
parent 652854db20
commit 820ac199d8
5 changed files with 273 additions and 23 deletions

View File

@ -23,17 +23,14 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1668681692,
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
"type": "github"
"lastModified": 1,
"narHash": "sha256-d6CilJXP+UPv3nF00zBBRhMgRklTCjSCMrjbYtYDuOI=",
"path": "out-of-tree/flake-compat",
"type": "path"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
"path": "out-of-tree/flake-compat",
"type": "path"
}
},
"flake-compat_2": {
@ -159,11 +156,11 @@
},
"locked": {
"dir": "contrib",
"lastModified": 1673504032,
"narHash": "sha256-x4nv7g8+bQXg5PfkFw3vCcr3pYI0Hco0VoSbAy60xek=",
"lastModified": 1673683108,
"narHash": "sha256-zg1W14wyrOCKiTkXU+nGHf/EfqX6wtcUWcMo4O/Q6nY=",
"owner": "neovim",
"repo": "neovim",
"rev": "143d3f1f3224bca02bfef7df0932b9d7524a3ff2",
"rev": "e89c39d6f016a4140293755250e968e839009617",
"type": "github"
},
"original": {
@ -180,11 +177,11 @@
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1673511313,
"narHash": "sha256-QGUT3w1bHclVRqX958EPOd3OxR/R10MoV97N5jx/qbw=",
"lastModified": 1673684013,
"narHash": "sha256-ljfG17g9K5sl7DGounCwOIfQLOGzXF0ffuDGxo3UN1E=",
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
"rev": "5af6fe31f9906e70a1e8985dbbdcc4ae66c7f82d",
"rev": "85b0900729bffa5e0d1817bbc6f024916dc1f38e",
"type": "github"
},
"original": {
@ -220,7 +217,7 @@
},
"locked": {
"lastModified": 1,
"narHash": "sha256-KP+2qdZlhmRkrafuuEofg7YnNdVmGV95ipvpuqmJneI=",
"narHash": "sha256-RkO+8E7MahERHw1C5DNObDjq4xeI+FqaWH9+M7Fv2UE=",
"path": "out-of-tree/nixGL",
"type": "path"
},
@ -262,11 +259,11 @@
},
"nixpkgs_3": {
"locked": {
"lastModified": 1673450908,
"narHash": "sha256-b8em+kwrNtnB7gR8SyVf6WuTyQ+6tHS6dzt9D9wgKF0=",
"lastModified": 1673540789,
"narHash": "sha256-xqnxBOK3qctIeUVxecydrEDbEXjsvHCPGPbvsl63M/U=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6c8644fc37b6e141cbfa6c7dc8d98846c4ff0c2e",
"rev": "0f213d0fee84280d8c3a97f7469b988d6fe5fcdf",
"type": "github"
},
"original": {
@ -311,11 +308,11 @@
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1673490397,
"narHash": "sha256-VCSmIYJy/ZzTvEGjdfITmTYfybXBgZpMjyjDndbou+8=",
"lastModified": 1673662873,
"narHash": "sha256-/YOtiDKPUXKKpIhsAds11llfC42ScGW27bbHnNZebco=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "0833f4d063a2bb75aa31680f703ba594a384ffe6",
"rev": "90163bbbadce526f8b248a5fe545b06c59597108",
"type": "github"
},
"original": {

View File

@ -15,7 +15,7 @@
rust-overlay.url = "github:oxalica/rust-overlay";
# Allows default.nix to call onto flake.nix. Useful for nix eval and automations
flake-compat = {
url = "github:edolstra/flake-compat";
url = "path:out-of-tree/flake-compat";
flake = false;
};
kpcli-py = {

View File

@ -0,0 +1,20 @@
Copyright (c) 2020-2021 Eelco Dolstra and the flake-compat contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,29 @@
# flake-compat
## Usage
To use, add the following to your `flake.nix`:
```nix
inputs.flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
```
Afterwards, create a `default.nix` file containing the following:
```nix
(import
(
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{ src = ./.; }
).defaultNix
```
If you would like a `shell.nix` file, create one containing the above, replacing `defaultNix` with `shellNix`.

View File

@ -0,0 +1,204 @@
# 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').
{ src, system ? builtins.currentSystem or "unknown-system" }:
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 {})
);
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 then {
rev = info.rev;
shortRev = builtins.substring 0 7 info.rev;
} else {
})
else if info.type == "path" then
{ outPath = builtins.path {
path = if builtins.substring 0 1 info.path != "/"
then src + ("/" + info.path) # make this absolute path by prepending ./
else info.path; # it's already an absolute 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
rec {
defaultNix =
(builtins.removeAttrs result ["__functor"])
// (if result ? defaultPackage.${system} then { default = result.defaultPackage.${system}; } else {})
// (if result ? packages.${system}.default then { default = result.packages.${system}.default; } else {});
shellNix =
defaultNix
// (if result ? devShell.${system} then { default = result.devShell.${system}; } else {})
// (if result ? devShells.${system}.default then { default = result.devShells.${system}.default; } else {});
}