flakelike

This commit is contained in:
Wroclaw 2024-06-17 07:54:59 +02:00
parent 9cd9d8fe3c
commit ba94153c3b
8 changed files with 221 additions and 0 deletions

51
default.nix Normal file
View file

@ -0,0 +1,51 @@
# if evaluating outside of the store, copy the current directory to the store and import it
# filtering out .gitignore files and .git directories
# if evaluating inside the store, import the outputs.nix file
let
contains = str: substr: let
str_length = builtins.stringLength str;
substr_length = builtins.stringLength substr;
listOfPossibleSubstrings = builtins.genList (i: builtins.substring i substr_length str) (str_length - substr_length + 1);
in if substr_length > str_length then false else builtins.any (x: x == substr) listOfPossibleSubstrings;
endsWith = str: substr: let
str_length = builtins.stringLength str;
substr_length = builtins.stringLength substr;
in if substr_length > str_length then false else builtins.substring (str_length - substr_length) str_length str == substr;
gitignore = builtins.filter (v:
# ignore comments and empty lines
if !(builtins.isString v) then false
else if !builtins.isNull(builtins.match "^#.*" v) then false
else if !builtins.isNull(builtins.match "^$" v) then false
else true
) (builtins.split "\n" (builtins.readFile ./.gitignore));
# checks if a given path matches a gitignore pattern
# string -> bool
matchesGitIgnore = path: builtins.any (pattern:
let
patternLength = builtins.stringLength pattern;
unsupportedPatternMessage = "matchesGitIgnore: Unsupported pattern: ${pattern}";
in
if pattern == "*" then true
else if pattern == ".*" then true
else if pattern == "*.*" then true
else if builtins.substring 0 2 pattern == "*." then endsWith path (builtins.substring 0 2 pattern)
else if contains pattern "*" then abort unsupportedPatternMessage
else if patternLength > 2 && builtins.substring 0 2 pattern == "./" then abort unsupportedPatternMessage
else if patternLength > 1 && builtins.substring 0 1 pattern == "/" then abort unsupportedPatternMessage
else contains path pattern
) gitignore;
currentFilePath = (builtins.unsafeGetAttrPos "any" { any = "any"; }).file;
storePathLength = builtins.stringLength (builtins.toString builtins.storeDir);
evaluatingInStore = (builtins.substring 0 storePathLength currentFilePath) == builtins.storeDir;
selfInStore = builtins.filterSource (path: type:
type != "unknown" && builtins.baseNameOf path != ".git" && !matchesGitIgnore path
) ./.;
in
if !(evaluatingInStore) then import selfInStore
else import ./outputs.nix

10
inputs.nix Normal file
View file

@ -0,0 +1,10 @@
let self = {
lock ? import ./lock.nix
, lib ? import "${(self {}).nixpkgs}/lib"
}:
{
inherit lock;
nixpkgs = builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/${lock.nixpkgs}.tar.gz";
};
in self

View file

@ -0,0 +1,8 @@
{ inputs ? import ../../inputs.nix {} }:
selfLib: superLib: {
trivial = superLib.trivial // {
versionSuffix = ".git.${builtins.substring 0 12 inputs.lock.nixpkgs}";
revisionWithDefault = default: inputs.lock.nixpkgs or default;
};
}

3
lock.nix Normal file
View file

@ -0,0 +1,3 @@
{
nixpkgs = "2975732531b5fa6e728f837c6f090335cbef5285" /*git revision*/;
}

53
outputs.nix Normal file
View file

@ -0,0 +1,53 @@
{ inputs ? import ./inputs.nix {}
, selfPath ? builtins.toString ./.
}:
let
lib = (import "${inputs.nixpkgs}/lib").extend (import ./lib/overlays/version-info-fixup.nix { inherit inputs; });
self = {
inherit lib;
modifiedNixpkgs = import ./pkgs/top-level/impure.nix;
modifiedNixpkgsPure = import ./pkgs/top-level/default.nix;
overlays = {
selfExpr = import ./pkgs/overlays/selfExpr.nix { nixpkgsPath = inputs.nixpkgs; };
unstable = import ./pkgs/overlays/unstable.nix;
versionInfoFixup = import ./pkgs/overlays/version-info-fixup.nix { inherit inputs; };
};
nixosConfigurations = let
dir = builtins.readDir ./hosts;
# list nix file paths in ./hosts to attributes in nixosConfigurations
filePaths = lib.mapAttrsToList (name: _: name) (lib.filterAttrs (name: type:
# filter out non-nix files
type == "regular"
# filter out files that don't end in .nix
&& lib.hasSuffix ".nix" name
# filter out files that start with .
&& ! lib.hasPrefix "." name
) dir
);
nixosSystem = import "${inputs.nixpkgs}/nixos/lib/eval-config.nix";
in
# mapped list of nix file paths to attrSet with initialized NixOS configurations,
# whose names are derived from file names
builtins.listToAttrs (builtins.map (name: {
name = builtins.substring 0 (builtins.stringLength name - 4) name;
value = nixosSystem {
inherit lib;
modules = [
./hosts/${name}
{
config.nixpkgs.overlays = [
( import ./pkgs/overlays/selfExpr.nix { nixpkgsPath = ./pkgs/top-level/impure.nix; } )
self.overlays.versionInfoFixup
];
}
];
specialArgs = { inherit self inputs; };
};
}) filePaths
);
};
in self

View file

@ -0,0 +1,5 @@
{ inputs ? import ../../inputs.nix {} }:
self: super: {
lib = super.lib.extend (import ../../lib/overlays/version-info-fixup.nix { inherit inputs; });
}

View file

@ -0,0 +1,21 @@
{ inputs ? import ../../inputs.nix {}
, uninitializedNixpkgs ? import "${inputs.nixpkgs}/pkgs/top-level/default.nix"
, ...
} @ args:
let
attrsToRemove = [
"inputs"
"overlays"
"uninitializedNixpkgs"
];
options = (builtins.removeAttrs args attrsToRemove) // {
overlays = (args.overlays or []) ++ [
( import ../overlays/selfExpr.nix { nixpkgsPath = ./impure.nix; } )
( import ../overlays/unstable.nix )
( import ../overlays/version-info-fixup.nix { inherit inputs; } )
];
};
in
uninitializedNixpkgs options

70
pkgs/top-level/impure.nix Normal file
View file

@ -0,0 +1,70 @@
# Modified copy of github:NixOS/nixpkgs pkgs/top-level/impure.nix
# as of commit 242522b8fed8d63f262fd6e747ba1e4372b59a8e
# I wish I could just import from nixpkgs and set different path to entry point.
let
homeDir = builtins.getEnv "HOME";
# Return x if it evaluates, or def if it throws an exception.
try = x: def: let res = builtins.tryEval x; in if res.success then res.value else def;
in
{ localSystem ? { system = args.system or builtins.currentSystem; }
, system ? localSystem.system
, crossSystem ? localSystem
, config ? let
configFile = builtins.getEnv "NIXPKGS_CONFIG";
configFile2 = homeDir + "/.config/nixpkgs/config.nix";
configFile3 = homeDir + "/.nixpkgs/config.nix"; # obsolete
in
if configFile != "" && builtins.pathExists configFile then import configFile
else if homeDir != "" && builtins.pathExists configFile2 then import configFile2
else if homeDir != "" && builtins.pathExists configFile3 then import configFile3
else {}
, overlays ? let
isDir = path: builtins.pathExists (path + "/.");
pathOverlays = try (toString <nixpkgs-overlays>) "";
homeOverlaysFile = homeDir + "/.config/nixpkgs/overlays.nix";
homeOverlaysDir = homeDir + "/.config/nixpkgs/overlays";
overlays = path:
# check if the path is a directory or a file
if isDir path then
# it's a directory, so the set of overlays from the directory, ordered lexicographically
let content = builtins.readDir path; in
map (n: import (path + ("/" + n)))
(builtins.filter
(n:
(builtins.match ".*\\.nix" n != null &&
# ignore Emacs lock files (.#foo.nix)
builtins.match "\\.#.*" n == null) ||
builtins.pathExists (path + ("/" + n + "/default.nix")))
(builtins.attrNames content))
else
# it's a file, so the result is the contents of the file itself
import path;
in
if pathOverlays != "" && builtins.pathExists pathOverlays then overlays pathOverlays
else if builtins.pathExists homeOverlaysFile && builtins.pathExists homeOverlaysDir then
throw ''
Nixpkgs overlays can be specified with ${homeOverlaysFile} or ${homeOverlaysDir}, but not both.
Please remove one of them and try again.
''
else if builtins.pathExists homeOverlaysFile then
if isDir homeOverlaysFile then
throw (homeOverlaysFile + " should be a file")
else overlays homeOverlaysFile
else if builtins.pathExists homeOverlaysDir then
if !(isDir homeOverlaysDir) then
throw (homeOverlaysDir + " should be a directory")
else overlays homeOverlaysDir
else []
, crossOverlays ? []
, ...
} @ args:
# Assertion checked in called nixpkgs upstream, thus removed here
import ./. (builtins.removeAttrs args [ "system" ] // {
inherit config overlays localSystem;
})