From 96bd37dc3488b608cac0b1fd180102ae8880ff5f Mon Sep 17 00:00:00 2001 From: Aldo <82811+aldoborrero@users.noreply.github.com> Date: Tue, 26 Sep 2023 12:11:31 +0200 Subject: [PATCH] Flake organization improvements (#376) --- .envrc | 2 +- checks.nix | 38 ++++++ default.nix | 16 +-- flake-compat.nix | 16 +++ nix/shell.nix => flake-shell.nix | 8 +- flake.lock | 23 +++- flake.nix | 37 ++++-- nix/formatter.nix => formatter.nix | 12 +- lib.nix | 186 +++++++++++++++++++++++++++++ mkdocs.nix | 2 +- modules/testing.nix | 4 +- nix/checks.nix | 41 ------- nix/default.nix | 9 -- nix/lib/default.nix | 6 - nix/lib/flake.nix | 39 ------ nix/lib/fs.nix | 45 ------- packages/default.nix | 10 +- shell.nix | 16 +-- 18 files changed, 306 insertions(+), 204 deletions(-) create mode 100644 checks.nix create mode 100644 flake-compat.nix rename nix/shell.nix => flake-shell.nix (62%) rename nix/formatter.nix => formatter.nix (79%) create mode 100644 lib.nix delete mode 100644 nix/checks.nix delete mode 100644 nix/default.nix delete mode 100644 nix/lib/default.nix delete mode 100644 nix/lib/flake.nix delete mode 100644 nix/lib/fs.nix diff --git a/.envrc b/.envrc index 5d480b3b..3851773c 100644 --- a/.envrc +++ b/.envrc @@ -1,5 +1,5 @@ if ! has nix_direnv_version || ! nix_direnv_version 2.2.0; then source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.0/direnvrc" "sha256-5EwyKnkJNQeXrRkYbwwRBcXbibosCJqyIUuz9Xq+LRc=" fi -nix_direnv_watch_file ./nix/shell.nix +nix_direnv_watch_file ./flake-shell.nix use flake diff --git a/checks.nix b/checks.nix new file mode 100644 index 00000000..0bb3895b --- /dev/null +++ b/checks.nix @@ -0,0 +1,38 @@ +{inputs, ...}: { + perSystem = { + pkgs, + config, + ... + }: { + checks = let + devour-flake = pkgs.callPackage inputs.devour-flake {}; + in + { + nix-build-all = pkgs.writeShellApplication { + name = "nix-build-all"; + runtimeInputs = [ + pkgs.nix + devour-flake + ]; + text = '' + # Make sure that flake.lock is sync + nix flake lock --no-update-lock-file + + # Do a full nix build (all outputs) + devour-flake . "$@" + ''; + }; + } + # mix in tests + // config.testing.checks; + + devshells.default.commands = [ + { + category = "Tools"; + name = "check"; + help = "Checks the source tree"; + command = "nix flake check"; + } + ]; + }; +} diff --git a/default.nix b/default.nix index 56cade6e..8d145ff0 100644 --- a/default.nix +++ b/default.nix @@ -1,16 +1,4 @@ -{system ? builtins.currentSystem}: let - lock = builtins.fromJSON (builtins.readFile ./flake.lock); - - inherit (lock.nodes.flake-compat.locked) owner repo rev narHash; - - flake-compat = fetchTarball { - url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; - sha256 = narHash; - }; - - flake = import flake-compat { - inherit system; - src = ./.; - }; +let + flake = import ./flake-compat.nix {}; in flake.defaultNix diff --git a/flake-compat.nix b/flake-compat.nix new file mode 100644 index 00000000..a16be684 --- /dev/null +++ b/flake-compat.nix @@ -0,0 +1,16 @@ +{ + system ? builtins.currentSystem, + flakeLockPath ? ./flake.lock, + src ? ./., +}: let + lock = builtins.fromJSON (builtins.readFile flakeLockPath); + inherit (lock.nodes.flake-compat.locked) owner repo rev narHash; + + flake-compat = fetchTarball { + url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; + sha256 = narHash; + }; +in + import flake-compat { + inherit system src; + } diff --git a/nix/shell.nix b/flake-shell.nix similarity index 62% rename from nix/shell.nix rename to flake-shell.nix index 3441f63a..21e94481 100644 --- a/nix/shell.nix +++ b/flake-shell.nix @@ -1,14 +1,12 @@ { perSystem = { pkgs, - inputs', + pkgsUnstable, ... - }: let - inherit (inputs'.nixpkgs-unstable.legacyPackages) nix-update statix mkdocs; - in { + }: { devshells.default = { name = "ethereum.nix"; - packages = [ + packages = with pkgsUnstable; [ nix-update statix mkdocs diff --git a/flake.lock b/flake.lock index a5df5580..a5a3a0dd 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,21 @@ { "nodes": { + "devour-flake": { + "flake": false, + "locked": { + "lastModified": 1694098737, + "narHash": "sha256-O51F4YFOzlaQAc9b6xjkAqpvrvCtw/Os2M7TU0y4SKQ=", + "owner": "srid", + "repo": "devour-flake", + "rev": "30a34036b29b0d12989ef6c8be77aa949d85aef5", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "devour-flake", + "type": "github" + } + }, "devshell": { "inputs": { "nixpkgs": [ @@ -285,6 +301,7 @@ }, "root": { "inputs": { + "devour-flake": "devour-flake", "devshell": "devshell", "flake-compat": "flake-compat", "flake-parts": "flake-parts", @@ -318,11 +335,11 @@ ] }, "locked": { - "lastModified": 1695290086, - "narHash": "sha256-ol6licpIAzc9oMsEai/9YZhgSMcrnlnD/3ulMLGNKL0=", + "lastModified": 1694528738, + "narHash": "sha256-aWMEjib5oTqEzF9f3WXffC1cwICo6v/4dYKjwNktV8k=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "e951529be2e7c669487de78f5aef8597bbae5fca", + "rev": "7a49c388d7a6b63bb551b1ddedfa4efab8f400d8", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 55577288..778d5099 100644 --- a/flake.nix +++ b/flake.nix @@ -34,6 +34,10 @@ inputs.nixpkgs.follows = "nixpkgs"; }; flake-compat.url = "github:nix-community/flake-compat"; + devour-flake = { + url = "github:srid/devour-flake"; + flake = false; + }; }; outputs = inputs @ { @@ -41,22 +45,25 @@ nixpkgs, ... }: let - lib = nixpkgs.lib.extend (final: _: import ./nix/lib final); + lib = nixpkgs.lib.extend (final: _: import ./lib.nix final); in flake-parts.lib.mkFlake { inherit inputs; - specialArgs = { - inherit lib; # make custom lib available to parent functions - }; + specialArgs = {inherit lib;}; } rec { imports = [ - {_module.args.lib = lib;} # make custom lib available to all `perSystem` functions - ./nix - ./packages - ./modules - ./mkdocs.nix + inputs.devshell.flakeModule + inputs.flake-parts.flakeModules.easyOverlay + inputs.flake-root.flakeModule inputs.hercules-ci-effects.flakeModule + inputs.treefmt-nix.flakeModule + ./checks.nix + ./flake-shell.nix + ./formatter.nix + ./mkdocs.nix + ./modules + ./packages ]; systems = [ "x86_64-linux" @@ -64,6 +71,18 @@ "x86_64-darwin" "aarch64-darwin" ]; + perSystem = {system, ...}: { + _module.args = { + pkgs = lib.mkNixpkgs { + inherit system; + inherit (inputs) nixpkgs; + }; + pkgsUnstable = lib.mkNixpkgs { + inherit system; + nixpkgs = inputs.nixpkgs-unstable; + }; + }; + }; herculesCI.ciSystems = with builtins; filter (system: (match ".*-darwin" system) == null) systems; }; } diff --git a/nix/formatter.nix b/formatter.nix similarity index 79% rename from nix/formatter.nix rename to formatter.nix index eae90eda..809cf71b 100644 --- a/nix/formatter.nix +++ b/formatter.nix @@ -1,8 +1,4 @@ -{inputs, ...}: { - imports = [ - inputs.treefmt-nix.flakeModule - ]; - +{ perSystem = { config, pkgs, @@ -11,11 +7,13 @@ treefmt.config = { inherit (config.flake-root) projectRootFile; package = pkgs.treefmt; - + flakeFormatter = true; + flakeCheck = true; programs = { alejandra.enable = true; deadnix.enable = true; prettier.enable = true; + statix.enable = true; }; }; @@ -27,7 +25,5 @@ command = "nix fmt"; } ]; - - formatter = config.treefmt.build.wrapper; }; } diff --git a/lib.nix b/lib.nix new file mode 100644 index 00000000..50f4b144 --- /dev/null +++ b/lib.nix @@ -0,0 +1,186 @@ +lib: rec { + /* + Function: platformPkgs + Synopsis: Filters Nix packages based on the target system platform. + + Parameters: + - system (string): Target system platform (e.g., "x86_64-linux"). + + Returns: + - A filtered attribute set of Nix packages compatible with the target system. + */ + platformPkgs = system: + with lib; + filterAttrs + (_: value: let + platforms = attrByPath ["meta" "platforms"] [] value; + in + elem system platforms); + + /* + Function: buildApps + Synopsis: Constructs attribute set of applications from Nix packages and custom apps specification. + + Parameters: + - packages (attrset): An attribute set of Nix packages. + - apps (attrset): Custom apps specification. + + Returns: + - An attribute set representing built applications. + */ + buildApps = packages: apps: + with lib; + listToAttrs + (collect (attrs: builtins.attrNames attrs == ["name" "value"]) + (mapAttrsRecursiveCond builtins.isAttrs (path: v: let + drvName = head path; + drv = packages.${drvName}; + name = last (init path); + exePath = "/bin/${v}"; + in + nameValuePair name {inherit drv name exePath;}) + apps)); + + /* + Function: platformApps + Synopsis: Filters and builds platform-specific applications. + + Parameters: + - packages (attrset): An attribute set of Nix packages. + - apps (attrset): Custom apps specification. + + Returns: + - An attribute set of platform-specific applications. + */ + platformApps = packages: apps: + with lib; let + apps' = filterAttrs (name: _: elem name (attrNames packages)) apps; + bapps = buildApps packages apps'; + in + mapAttrs (_: mkApp) bapps; + + /* + Function: mkApp + Synopsis: Creates an "app" type for Nix flakes. + + Parameters: + - drv (derivation): The Nix derivation. + - name (string, optional): Name of the application. + - exePath (string, optional): Executable path. + + Returns: + - An "app" type attribute with 'type' and 'program' keys. + */ + mkApp = { + drv, + name ? drv.pname or drv.name, + exePath ? drv.passthru.exePath or "/bin/${name}", + }: { + type = "app"; + program = "${drv}${exePath}"; + }; + + /* + Function: flattenTree + Synopsis: Flattens a nested attribute set (tree) into a single-level attribute set. + + Parameters: + - tree (attrset): A nested attribute set + + Returns: + - An attribute set where keys are constructed in reverse DNS notation, based on the nesting. + + Example: + Input: { a = { b = { c = ; }; }; } + Output: { "a.b.c" = ; } + + Description: + The function traverses the nested attribute set and produces a flattened attribute set. + It uses dot-based reverse DNS notation to concatenate the nested keys. + */ + flattenTree = { + tree, + separator ? ".", + }: let + op = sum: path: val: let + pathStr = builtins.concatStringsSep separator path; + in + if builtins.isPath val + then + (sum + // { + "${pathStr}" = val; + }) + else if builtins.isAttrs val + then + # recurse into that attribute set + (recurse sum path val) + else + # ignore that value + sum; + + recurse = sum: path: val: + builtins.foldl' + (sum: key: op sum (path ++ [key]) val.${key}) + sum + (builtins.attrNames val); + in + recurse {} [] tree; + + /* + Function: rakeLeaves + Synopsis: Recursively collects `.nix` files from a directory into an attribute set. + + Parameters: + - dirPath (string): The directory path to collect `.nix` files from. + + Returns: + - An attribute set mapping filenames (without the `.nix` suffix) to their paths. + */ + rakeLeaves = dirPath: let + collect = file: type: { + name = lib.removeSuffix ".nix" file; + value = let + path = dirPath + "/${file}"; + in + if (type == "regular") + then path + else rakeLeaves path; + }; + + files = builtins.readDir dirPath; + in + lib.filterAttrs (_n: v: v != {}) (lib.mapAttrs' collect files); + + /* + Function: mkNixpkgs + Synopsis: Creates a custom Nixpkgs configuration. + + Parameters: + - system (string): Target system, e.g., "x86_64-linux". + - inputs (attrset, optional): Custom inputs for the Nixpkgs configuration. + - overlays (list, optional): List of overlays to apply. + - nixpkgs (path, optional): Path to the Nixpkgs repository. Defaults to inputs.nixpkgs. + - config (attrset, optional): Additional Nixpkgs configuration settings. + + Returns: + - A configured Nixpkgs environment suitable for importing. + + Example: + mkNixpkgs { + system = "x86_64-linux"; + overlays = [ myOverlay ]; + } + + Description: + The function imports a Nixpkgs environment with the specified target system, custom inputs, + and overlays. It also accepts additional Nixpkgs configuration settings. + */ + mkNixpkgs = { + system, + nixpkgs, + overlays ? [], + config ? {allowUnfree = true;}, + }: + import nixpkgs {inherit system config overlays;}; +} diff --git a/mkdocs.nix b/mkdocs.nix index 7fa3659e..f23a04d4 100644 --- a/mkdocs.nix +++ b/mkdocs.nix @@ -30,7 +30,7 @@ eachOptions = with lib; filterAttrs (_: hasSuffix "options.nix") - (fs.flattenTree {tree = fs.rakeLeaves ./modules;}); + (flattenTree {tree = rakeLeaves ./modules;}); eachOptionsDoc = with lib; mapAttrs' ( diff --git a/modules/testing.nix b/modules/testing.nix index f5c2fc24..ee1ba705 100644 --- a/modules/testing.nix +++ b/modules/testing.nix @@ -37,8 +37,8 @@ eachTest = filterAttrs (_: (hasSuffix ".test.nix")) - (fs.flattenTree { - tree = fs.rakeLeaves ./.; + (flattenTree { + tree = rakeLeaves ./.; separator = "-"; }); diff --git a/nix/checks.nix b/nix/checks.nix deleted file mode 100644 index 66310ba7..00000000 --- a/nix/checks.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - self, - lib, - ... -}: { - perSystem = { - self', - inputs', - pkgs, - config, - ... - }: { - checks = let - inherit (inputs'.nixpkgs-unstable.legacyPackages) statix; - in - { - statix = - pkgs.runCommand "statix" { - nativeBuildInputs = [statix]; - } '' - cp --no-preserve=mode -r ${self} source - cd source - HOME=$TMPDIR statix check - touch $out - ''; - } - # mix in tests - // config.testing.checks - # merge in the package derivations to force a build of all packages during a `nix flake check` - // (with lib; mapAttrs' (n: nameValuePair "package-${n}") self'.packages); - - devshells.default.commands = [ - { - category = "Tools"; - name = "check"; - help = "Checks the source tree"; - command = "nix flake check"; - } - ]; - }; -} diff --git a/nix/default.nix b/nix/default.nix deleted file mode 100644 index c8a38ab9..00000000 --- a/nix/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{inputs, ...}: { - imports = [ - inputs.flake-root.flakeModule - inputs.devshell.flakeModule - ./checks.nix - ./formatter.nix - ./shell.nix - ]; -} diff --git a/nix/lib/default.nix b/nix/lib/default.nix deleted file mode 100644 index e49c864b..00000000 --- a/nix/lib/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -lib: let - fs = import ./fs.nix lib; - flake = import ./flake.nix lib; -in { - inherit fs flake; -} diff --git a/nix/lib/flake.nix b/nix/lib/flake.nix deleted file mode 100644 index fe45326e..00000000 --- a/nix/lib/flake.nix +++ /dev/null @@ -1,39 +0,0 @@ -lib: rec { - platformPkgs = system: - with lib; - filterAttrs - (_: value: let - platforms = attrByPath ["meta" "platforms"] [] value; - in - elem system platforms); - - buildApps = packages: apps: - with lib; - listToAttrs - (collect (attrs: builtins.attrNames attrs == ["name" "value"]) - (mapAttrsRecursiveCond builtins.isAttrs (path: v: let - drvName = head path; - drv = packages.${drvName}; - name = last (init path); - exePath = "/bin/${v}"; - in - nameValuePair name {inherit drv name exePath;}) - apps)); - - platformApps = packages: apps: - with lib; let - apps' = filterAttrs (name: _: elem name (attrNames packages)) apps; - bapps = buildApps packages apps'; - in - mapAttrs (_: mkApp) bapps; - - # Taken from flake-utils: https://github.com/numtide/flake-utils/blob/5aed5285a952e0b949eb3ba02c12fa4fcfef535f/default.nix#L195 - mkApp = { - drv, - name ? drv.pname or drv.name, - exePath ? drv.passthru.exePath or "/bin/${name}", - }: { - type = "app"; - program = "${drv}${exePath}"; - }; -} diff --git a/nix/lib/fs.nix b/nix/lib/fs.nix deleted file mode 100644 index 8b98ed5a..00000000 --- a/nix/lib/fs.nix +++ /dev/null @@ -1,45 +0,0 @@ -lib: rec { - flattenTree = { - tree, - separator ? ".", - }: let - op = sum: path: val: let - pathStr = builtins.concatStringsSep separator path; - in - if builtins.isPath val - then - (sum - // { - "${pathStr}" = val; - }) - else if builtins.isAttrs val - then - # recurse into that attribute set - (recurse sum path val) - else - # ignore that value - sum; - - recurse = sum: path: val: - builtins.foldl' - (sum: key: op sum (path ++ [key]) val.${key}) - sum - (builtins.attrNames val); - in - recurse {} [] tree; - - rakeLeaves = dirPath: let - collect = file: type: { - name = lib.removeSuffix ".nix" file; - value = let - path = dirPath + "/${file}"; - in - if (type == "regular") - then path - else rakeLeaves path; - }; - - files = builtins.readDir dirPath; - in - lib.filterAttrs (_n: v: v != {}) (lib.mapAttrs' collect files); -} diff --git a/packages/default.nix b/packages/default.nix index b239d127..0a80873b 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -3,20 +3,16 @@ lib, ... }: { - imports = [ - inputs.flake-parts.flakeModules.easyOverlay - ]; - perSystem = { self', - inputs', pkgs, + pkgsUnstable, system, ... }: let inherit (pkgs) callPackage; - inherit (lib.flake) platformPkgs platformApps; - callPackageUnstable = inputs'.nixpkgs-unstable.legacyPackages.callPackage; + inherit (lib) platformPkgs platformApps; + callPackageUnstable = pkgsUnstable.callPackage; in { packages = platformPkgs system rec { # Consensus Clients diff --git a/shell.nix b/shell.nix index 9a6ecad9..b1484554 100644 --- a/shell.nix +++ b/shell.nix @@ -1,16 +1,4 @@ -{system ? builtins.currentSystem}: let - lock = builtins.fromJSON (builtins.readFile ./flake.lock); - - inherit (lock.nodes.flake-compat.locked) owner repo rev narHash; - - flake-compat = fetchTarball { - url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; - sha256 = narHash; - }; - - flake = import flake-compat { - inherit system; - src = ./.; - }; +let + flake = import ./flake-compat.nix {}; in flake.shellNix