From e34fcedfc799e31449ec0a0b87b031e14c454a39 Mon Sep 17 00:00:00 2001 From: zimbatm Date: Sun, 23 Aug 2020 15:28:05 +0200 Subject: [PATCH] add lib.simpleFlake (#5) --- README.md | 77 +++++++++++++++++---- default.nix | 27 +++++--- {example => examples/each-system}/flake.nix | 0 examples/simple-flake/flake.nix | 13 ++++ examples/simple-flake/overlay.nix | 11 +++ examples/simple-flake/shell.nix | 4 ++ simpleFlake.nix | 65 +++++++++++++++++ 7 files changed, 174 insertions(+), 23 deletions(-) rename {example => examples/each-system}/flake.nix (100%) create mode 100644 examples/simple-flake/flake.nix create mode 100644 examples/simple-flake/overlay.nix create mode 100644 examples/simple-flake/shell.nix create mode 100644 simpleFlake.nix diff --git a/README.md b/README.md index b1991fb..0f94df8 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,36 @@ eachSystem allSystems (system: { hello = 42; }) `eachSystem` pre-populated with `defaultSystems`. +#### Example + +[$ examples/each-system/flake.nix](examples/each-system/flake.nix) as nix +```nix +{ + description = "Flake utils demo"; + + inputs.flake-utils.url = "github:numtide/flake-utils"; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let pkgs = nixpkgs.legacyPackages.${system}; in + rec { + packages = flake-utils.lib.flattenTree { + hello = pkgs.hello; + gitAndTools = pkgs.gitAndTools; + }; + defaultPackage = packages.hello; + apps.hello = flake-utils.lib.mkApp { drv = packages.hello; }; + defaultApp = apps.hello; + } + ); +} +``` + ### `mkApp { drv, name ? drv.pname or drv.name, execPath ? drv.passthru.execPath or "/bin/${name}"` A small utility that builds the structure expected by the special `apps` and `defaultApp` prefixes. + ### `flattenTree -> attrs -> attrs` Nix flakes insists on having a flat attribute set of derivations in @@ -78,27 +104,54 @@ Returns: } ``` -## Example +### `simpleFlake -> attrs -> attrs` + +This function should be useful for most common use-cases where you have a +simple flake that builds a package. It takes nixpkgs and a bunch of other +parameters and outputs a value that is compatible as a flake output. + +Input: +```nix +{ + # pass an instance of self + self +, # pass an instance of the nixpkgs flake + nixpkgs +, # we assume that the name maps to the project name, and also that the + # overlay has an attribute with the `name` prefix that contains all of the + # project's packages. + name +, # nixpkgs config + config ? { } +, # pass either a function or a file + overlay ? null +, # use this to load other flakes overlays to supplement nixpkgs + preOverlays ? [ ] +, # maps to the devShell output. Pass in a shell.nix file or function. + shell ? null +, # pass the list of supported systems + systems ? [ "x86_64-linux" ] +}: null +``` + +#### Example Here is how it looks like in practice: -[$ example/flake.nix](example/flake.nix) as nix +[$ examples/simple-flake/flake.nix](examples/simple-flake/flake.nix) as nix ```nix { description = "Flake utils demo"; - inputs.flake-utils.url = "github:numtide/flake-utils"; + inputs.flake-utils.url = "github:numtide/flake-utils/simple-flake"; outputs = { self, nixpkgs, flake-utils }: - flake-utils.lib.eachDefaultSystem (system: - let pkgs = nixpkgs.legacyPackages.${system}; in - rec { - packages.hello = pkgs.hello; - defaultPackage = packages.hello; - apps.hello = flake-utils.lib.mkApp { drv = packages.hello; }; - defaultApp = apps.hello; - } - ); + flake-utils.lib.simpleFlake { + inherit self nixpkgs; + name = "simple-flake"; + overlay = ./overlay.nix; + shell = ./shell.nix; + }; } ``` diff --git a/default.nix b/default.nix index ceaad1d..f30f13e 100644 --- a/default.nix +++ b/default.nix @@ -117,15 +117,20 @@ let type = "app"; program = "${drv}${exePath}"; }; -in -{ - inherit - allSystems - defaultSystems - eachDefaultSystem - eachSystem - flattenTree - mkApp - ; -} + # This function tries to capture a common flake pattern. + simpleFlake = import ./simpleFlake.nix { inherit lib; }; + + lib = { + inherit + allSystems + defaultSystems + eachDefaultSystem + eachSystem + flattenTree + mkApp + simpleFlake + ; + }; +in +lib diff --git a/example/flake.nix b/examples/each-system/flake.nix similarity index 100% rename from example/flake.nix rename to examples/each-system/flake.nix diff --git a/examples/simple-flake/flake.nix b/examples/simple-flake/flake.nix new file mode 100644 index 0000000..a027b51 --- /dev/null +++ b/examples/simple-flake/flake.nix @@ -0,0 +1,13 @@ +{ + description = "Flake utils demo"; + + inputs.flake-utils.url = "github:numtide/flake-utils"; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.simpleFlake { + inherit self nixpkgs; + name = "simple-flake"; + overlay = ./overlay.nix; + shell = ./shell.nix; + }; +} diff --git a/examples/simple-flake/overlay.nix b/examples/simple-flake/overlay.nix new file mode 100644 index 0000000..772e417 --- /dev/null +++ b/examples/simple-flake/overlay.nix @@ -0,0 +1,11 @@ +final: prev: +{ + # this key should be the same as the simpleFlake name attribute. + simple-flake = { + # assuming that hello is a project-specific package; + hello = prev.hello; + + # demonstrating recursive packages + terraform-providers = prev.terraform-providers; + }; +} diff --git a/examples/simple-flake/shell.nix b/examples/simple-flake/shell.nix new file mode 100644 index 0000000..b96bfda --- /dev/null +++ b/examples/simple-flake/shell.nix @@ -0,0 +1,4 @@ +{ pkgs ? import }: +pkgs.mkShell { + buildInputs = [ pkgs.jq ]; +} diff --git a/simpleFlake.nix b/simpleFlake.nix new file mode 100644 index 0000000..b3d497c --- /dev/null +++ b/simpleFlake.nix @@ -0,0 +1,65 @@ +{ lib }: +# This function returns a flake outputs-compatible schema. +{ + # pass an instance of self + self +, # pass an instance of the nixpkgs flake + nixpkgs +, # we assume that the name maps to the project name, and also that the + # overlay has an attribute with the `name` prefix that contains all of the + # project's packages. + name +, # nixpkgs config + config ? { } +, # pass either a function or a file + overlay ? null +, # use this to load other flakes overlays to supplement nixpkgs + preOverlays ? [ ] +, # maps to the devShell output. Pass in a shell.nix file or function. + shell ? null +, # pass the list of supported systems + systems ? [ "x86_64-linux" ] +}: +let + loadOverlay = obj: + if obj == null then + [ ] + else + [ (maybeImport obj) ] + ; + + maybeImport = obj: + if (builtins.typeOf obj == "path") || (builtins.typeOf obj == "string") then + import obj + else + obj + ; + + overlays = preOverlays ++ (loadOverlay overlay); + + shell_ = maybeImport shell; + + outputs = lib.eachSystem systems (system: + let + pkgs = import nixpkgs { + inherit + config + overlays + system + ; + }; + + packages = pkgs.${name} or { }; + in + { + legacyPackages = packages; + + # Flake expects a flat attrset containing only derivations as values + packages = lib.flattenTree packages; + } // (if shell == null then { } else { + devShell = shell_ { inherit pkgs; }; + }) + ); + +in +outputs