From 9b9145e52f49b02d9896e19982b963d9d4787b8b Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 07:52:44 -0700 Subject: [PATCH 01/90] update flake-utils for filterPackages fixups --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index eaa6295b..974429ba 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-utils": { "locked": { - "lastModified": 1618217525, - "narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=", + "lastModified": 1619345332, + "narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=", "owner": "numtide", "repo": "flake-utils", - "rev": "c6169a2772643c4a93a0b5ac1c61e296cba68544", + "rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28", "type": "github" }, "original": { From 7418d2ca5adff110c13defcab26cd349d0f3cea8 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Wed, 21 Apr 2021 23:40:24 -0500 Subject: [PATCH 02/90] imp: provide per channel modules paths to make it easy to "backport" a module. imports = [ ${myChannelModulesPathk}/installer/... Signed-off-by: David Arnold --- .../configurations/Morty.host.nix | 8 ++++++-- systemFlake.nix | 17 +++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/fully-featured/configurations/Morty.host.nix b/examples/fully-featured/configurations/Morty.host.nix index 1f0fabe2..16a1c13c 100644 --- a/examples/fully-featured/configurations/Morty.host.nix +++ b/examples/fully-featured/configurations/Morty.host.nix @@ -1,4 +1,8 @@ -{ ... }: { +# auto-special args ModulesPath for easy backporting of modules +{ unstableModulesPath, ... }: { + + imports = [ "${unstableModulesPath}/installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ]; + disabledModules = [ "installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ]; + boot.loader.grub.devices = [ "nodev" ]; - fileSystems."/" = { device = "test"; fsType = "ext4"; }; } diff --git a/systemFlake.nix b/systemFlake.nix index 3feda486..ada45260 100644 --- a/systemFlake.nix +++ b/systemFlake.nix @@ -30,7 +30,7 @@ let inherit (flake-utils-plus.lib) eachSystem patchChannel; - inherit (builtins) foldl' mapAttrs removeAttrs attrValues isAttrs isList; + inherit (builtins) foldl' mapAttrs removeAttrs attrValues attrNames isAttrs isList; # set defaults and validate host arguments evalHostArgs = @@ -42,7 +42,9 @@ let , extraArgs ? { } # These are not part of the module system, so they can be used in `imports` lines without infinite recursion , specialArgs ? { } - }: { inherit channelName system output builder modules extraArgs specialArgs; }; + }: { + inherit channelName system output builder modules extraArgs specialArgs; + }; # recursively merge attribute sets and lists up to a certain depth mergeAny = lhs: rhs: @@ -91,8 +93,15 @@ let lib = selectedNixpkgs.lib; # Use nixos modules from patched nixpkgs baseModules = import (patchedChannel + "/nixos/modules/module-list.nix"); - # Override `modulesPath` because otherwise imports from there will not use patched nixpkgs - specialArgs = { modulesPath = builtins.toString (patchedChannel + "/nixos/modules"); } // host.specialArgs; + specialArgs = let + f = channelName: + { "${channelName}ModulesPath" = builtins.toString (channels.${channelName}.input + "/nixos/modules"); }; + in + # Add `ModulesPath`s + (foldl' (lhs: rhs: lhs // rhs) {} (map f (attrNames channels))) + # Override `modulesPath` because otherwise imports from there will not use patched nixpkgs + // { modulesPath = builtins.toString (patchedChannel + "/nixos/modules"); } + // host.specialArgs; # The only way to find out if a host has `nixpkgs.config` set to # the non-default value is by evalling most of the config. hostConfig = (lib.evalModules { From 4eb7af83fb32f3970d1eb80922daa63cff702e55 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sun, 25 Apr 2021 14:42:08 -0500 Subject: [PATCH 03/90] fix test --- systemFlake.nix | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/systemFlake.nix b/systemFlake.nix index ada45260..b790ef4e 100644 --- a/systemFlake.nix +++ b/systemFlake.nix @@ -93,12 +93,13 @@ let lib = selectedNixpkgs.lib; # Use nixos modules from patched nixpkgs baseModules = import (patchedChannel + "/nixos/modules/module-list.nix"); - specialArgs = let - f = channelName: - { "${channelName}ModulesPath" = builtins.toString (channels.${channelName}.input + "/nixos/modules"); }; - in + specialArgs = + let + f = channelName: + { "${channelName}ModulesPath" = builtins.toString (channels.${channelName}.input + "/nixos/modules"); }; + in # Add `ModulesPath`s - (foldl' (lhs: rhs: lhs // rhs) {} (map f (attrNames channels))) + (foldl' (lhs: rhs: lhs // rhs) { } (map f (attrNames channels))) # Override `modulesPath` because otherwise imports from there will not use patched nixpkgs // { modulesPath = builtins.toString (patchedChannel + "/nixos/modules"); } // host.specialArgs; @@ -158,9 +159,9 @@ let ]; }) ] ++ host.modules; - specialArgs = host.specialArgs; + inherit specialArgs; } // (optionalAttrs (host.output == "nixosConfigurations") { - inherit lib baseModules specialArgs; + inherit lib baseModules; })); } ); From f6c13a7f92ce72477aaeaa2d7da0b49127cbbe86 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sat, 24 Apr 2021 21:08:07 -0700 Subject: [PATCH 04/90] overlays exporter: use pkgs and inputs use pkgs to collect overlays from each channel, since user only passes overlaysBuilder for each channel. Also filter out any overlays defined in inputs --- overlaysFromChannelsExporter.nix | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/overlaysFromChannelsExporter.nix b/overlaysFromChannelsExporter.nix index 8b33722a..8eb4536e 100644 --- a/overlaysFromChannelsExporter.nix +++ b/overlaysFromChannelsExporter.nix @@ -1,11 +1,13 @@ { flake-utils-plus }: let - overlaysFromChannelsExporter = channels: + overlaysFromChannelsExporter = { pkgs, inputs ? { } }: /** - Synopsis: overlaysFromChannelsExporter _channels_ + Synopsis: overlaysFromChannelsExporter _{ pkgs, inputs }_ - channels: channels..overlays + pkgs: self.pkgs + + inputs: flake inputs to sort out external overlays Returns an attribute set of all packages defined in an overlay by any channel intended to be passed to be exported via _self.overlays_. This method of @@ -21,6 +23,11 @@ let In the case of the unstable channel, this information is still of varying usefulness, as effective cut dates can vary heavily between repositories. + To ensure only overlays that originate from the flake are exported you can optionally pass + a set of flake inputs and any overlay which is taken from an input will be filtered out. + Optimally this would be done by detecting flake ownership of each overlay, but that is not + possible yet, so this is the next best workaround. + Example: overlays = [ @@ -31,14 +38,23 @@ let **/ let - inherit (builtins) mapAttrs attrNames concatMap listToAttrs; + inherit (builtins) mapAttrs foldl' filter head attrNames attrValues concatMap listToAttrs elem; nameValuePair = name: value: { inherit name value; }; + # just pull out one arch from the system-spaced pkgs to get access to channels + # overlays can be safely evaluated on any arch + channels = head (attrValues pkgs); + pathStr = path: builtins.concatStringsSep "/" path; channelNames = attrNames channels; overlayNames = overlay: attrNames (overlay null null); + # get all overlays from inputs + inputOverlays = mapAttrs (_: v: [ v.overlay or (_: _: { }) ] ++ attrValues v.overlays or { }) inputs; + # use overlayNames as a way to identify overlays + flattenedInputOverlays = map overlayNames (foldl' (a: b: a ++ b) [ ] (attrValues inputOverlays)); + extractAndNamespaceEachOverlay = channelName: overlay: map (overlayName: @@ -50,6 +66,11 @@ let ) (overlayNames overlay); + filterOverlays = channel: + filter + (overlay: !elem (overlayNames overlay) flattenedInputOverlays) + channel.overlays; + in listToAttrs ( concatMap @@ -58,7 +79,7 @@ let (overlay: extractAndNamespaceEachOverlay channelName overlay ) - channels.${channelName}.overlays + (filterOverlays channels.${channelName}) ) channelNames ); From 052909fa78c65a3e4ae2e1c6f5a6966ee57633a0 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sat, 24 Apr 2021 21:08:17 -0700 Subject: [PATCH 05/90] packagesBuilder constructor: take set of overlays This is intended to be self.overlays which allows a cleaner api to pass what overlays should be collected and used to create packages export --- packagesFromOverlaysBuilderConstructor.nix | 106 +++++++++------------ 1 file changed, 47 insertions(+), 59 deletions(-) diff --git a/packagesFromOverlaysBuilderConstructor.nix b/packagesFromOverlaysBuilderConstructor.nix index f042abc3..ac78ac00 100644 --- a/packagesFromOverlaysBuilderConstructor.nix +++ b/packagesFromOverlaysBuilderConstructor.nix @@ -1,92 +1,80 @@ { flake-utils-plus }: let - overlayFromPackagesBuilderConstructor = channels: + packagesFromOverlaysBuilderConstructor = overlays: let - # channels: channels..overlays + # overlays: self.overlays - overlayFromPackagesBuilder = pkgs: + packagesFromOverlaysBuilder = channels: /** - Synopsis: overlayFromPackagesBuilder _pkgs_ + Synopsis: packagesFromOverlaysBuilder _channels_ - pkgs: pkgs.. + channels: builder `channels` argument Returns valid packges that have been defined within an overlay so they can be shared via _self.packages_ with the world. This is especially useful over sharing one's art via _self.overlays_ in case you have a binary cache running from which third parties could benefit. - First, flattens an arbitrarily nested _pkgs_ tree for each system into a flat - key in which nesting is aproximated by a "/" (e.g. "development/kakoune"). - Also filter the resulting packages for attributes that _trivially_ would - fail flake checks (broken, system not supported or not a derivation). - - Second, collects all overlays' packages' keys of all channels into a flat list. - - Finally, only passes packages through the seive that are prefixed with a top level - key exposed by any of the overlays. Since overlays override (and do not emrge) - top level attributes, by filtering on the prefix, an overlay's entire packages - tree will be correctly captured. - - Example: - - pkgs'. = { - "development/kakoune" = { ... }; - "development/vim" = { ... }; - }; - - overlays' = [ - "development" - ]; - - overlays' will pass both pkgs' through the sieve. + Steps: + 1. merge all channels into one nixpkgs attribute set + 2. collect all overlays' packages' keys into one flat list + 3. pick out each package from the nixpkgs set into one packages set + $. flatten package set and filter out disallowed packages - by flake check requirements + + example input and output: + ``` + overlays = { + "unstable/firefox" = prev: final: { + firefox = prev.override { privacySupport = true; }; + }; + } + + self.packages = { + firefox = *firefox derivation with privacySupport*; + } + ``` **/ let inherit (flake-utils-plus.lib) flattenTree filterPackages; - inherit (builtins) attrNames mapAttrs listToAttrs attrValues concatStringSep concatMap any; + inherit (builtins) foldl' attrNames mapAttrs listToAttrs + attrValues concatStringSep concatMap any head; nameValuePair = name: value: { inherit name value; }; - filterAttrs = pred: set: - listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [ (nameValuePair name v) ] else [ ]) (attrNames set)); - hasPrefix = - pref: - str: builtins.substring 0 (builtins.stringLength pref) str == pref; - - # first, flatten and filter on valid packages (by nix flake check criterion) flattenedPackages = - let - f = system: tree: (filterPackages system (flattenTree tree)); - in - mapAttrs f pkgs; + # merge all channels into one package set + foldl' (a: b: a // b) { } (attrValues channels); - # second, flatten all overlays' packages' keys into a single list - flattendOverlaysNames = + # flatten all overlays' packages' keys into a single list + flattenedOverlaysNames = let - allOverlays = concatMap (c: c.overlays) (attrValues channels); + allOverlays = attrValues overlays; overlayNamesList = overlay: attrNames (overlay null null); in - concatMap (o: overlayNamesList o) allOverlays; + concatMap overlayNamesList allOverlays; + + # create list of single-attribute sets that contain each package + exportPackagesList = map + (name: + { ${name} = flattenedPackages.${name}; } + ) + flattenedOverlaysNames; + + # fold list into one attribute set + exportPackages = foldl' (lhs: rhs: lhs // rhs) { } exportPackagesList; + + system = (head (attrValues channels)).system; in - # finally, only retain those packages defined by overlays - # pkgs'.. - # overlays' = [ "prefix" ... ]; - mapAttrs - (_: pkgs: - filterAttrs - (pkgName: - any (overlayName: hasPrefix pkgName overlayName) flattendOverlaysNames - ) - pkgs - ) - flattenedPackages; + # flatten nested sets with "/" delimiter then drop disallowed packages + filterPackages system (flattenTree exportPackages); in - overlayFromPackagesBuilder; + packagesFromOverlaysBuilder; in -overlayFromPackagesBuilderConstructor +packagesFromOverlaysBuilderConstructor From e3ba66785fd37d0dc8f96750fcfe928687ad29c4 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sat, 24 Apr 2021 21:02:25 -0700 Subject: [PATCH 06/90] examples: demonstrate updated exporters/builders specifically packagesFromOverlaysBuilderConstructor and overlaysFromChannelsExporter --- examples/somewhat-realistic/flake.nix | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/examples/somewhat-realistic/flake.nix b/examples/somewhat-realistic/flake.nix index 9981cf07..be1165d8 100644 --- a/examples/somewhat-realistic/flake.nix +++ b/examples/somewhat-realistic/flake.nix @@ -11,10 +11,11 @@ url = github:nix-community/home-manager/release-20.09; inputs.nixpkgs.follows = "nixpkgs"; }; + agenix.url = github:ryantm/agenix; }; - outputs = inputs@{ self, nixpkgs, unstable, utils, nix-darwin, home-manager }: + outputs = inputs@{ self, nixpkgs, unstable, utils, nix-darwin, home-manager, agenix }: utils.lib.systemFlake { # `self` and `inputs` arguments are REQUIRED!!!!!!!!!!!!!! @@ -40,8 +41,9 @@ channels.nixpkgs.overlaysBuilder = channels: [ (final: prev: { # Overwrites specified packages to be used from unstable channel. - inherit (channels.unstable) alacritty ranger jdk15_headless; + inherit (channels.unstable) alacritty ranger; }) + agenix.overlay ]; @@ -103,6 +105,13 @@ + # export overlays automatically for all packages defined in overlaysBuilder of each channel + overlays = utils.lib.exporter.overlaysFromChannelsExporter { + inherit (self) pkgs inputs; + }; + + # construct packagesBuilder to export all packages defined in overlays + packagesBuilder = utils.lib.builder.packagesFromOverlaysBuilderConstructor self.overlays; overlay = import ./overlays; From 4439748db44d598639bb7ae73e923d078f9e2799 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 09:30:43 -0700 Subject: [PATCH 07/90] pass channel to hosts as channel specialArg add name and input to each channel --- systemFlake.nix | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/systemFlake.nix b/systemFlake.nix index b790ef4e..3010bc83 100644 --- a/systemFlake.nix +++ b/systemFlake.nix @@ -89,20 +89,23 @@ let selectedNixpkgs = getNixpkgs host; host = evalHostArgs (mergeAny hostDefaults host'); patchedChannel = selectedNixpkgs.path; + + specialArgs = host.specialArgs // { channel = selectedNixpkgs; }; + + /* nixos specific arguments */ # Use lib from patched nixpkgs lib = selectedNixpkgs.lib; # Use nixos modules from patched nixpkgs baseModules = import (patchedChannel + "/nixos/modules/module-list.nix"); - specialArgs = + nixosSpecialArgs = let f = channelName: - { "${channelName}ModulesPath" = builtins.toString (channels.${channelName}.input + "/nixos/modules"); }; + { "${channelName}ModulesPath" = toString (channels.${channelName}.input + "/nixos/modules"); }; in # Add `ModulesPath`s (foldl' (lhs: rhs: lhs // rhs) { } (map f (attrNames channels))) # Override `modulesPath` because otherwise imports from there will not use patched nixpkgs - // { modulesPath = builtins.toString (patchedChannel + "/nixos/modules"); } - // host.specialArgs; + // { modulesPath = toString (patchedChannel + "/nixos/modules"); }; # The only way to find out if a host has `nixpkgs.config` set to # the non-default value is by evalling most of the config. hostConfig = (lib.evalModules { @@ -110,7 +113,7 @@ let check = false; modules = baseModules ++ host.modules; args = { inherit inputs; } // host.extraArgs; - inherit specialArgs; + specialArgs = nixosSpecialArgs // specialArgs; }).config; in { @@ -162,6 +165,7 @@ let inherit specialArgs; } // (optionalAttrs (host.output == "nixosConfigurations") { inherit lib baseModules; + specialArgs = nixosSpecialArgs // specialArgs; })); } ); @@ -172,11 +176,11 @@ mergeAny otherArguments ( eachSystem supportedSystems (system: let - importChannel = name: value: import (patchChannel system value.input (value.patches or [ ])) { + importChannel = name: value: (import (patchChannel system value.input (value.patches or [ ])) { inherit system; overlays = sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]); config = channelsConfig // (value.config or { }); - }; + }) // { inherit name; inherit (value) input; }; pkgs = mapAttrs importChannel channels; From 1245b7ecb1c56ef64a45853204eb786978623b42 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 22:43:25 -0700 Subject: [PATCH 08/90] fix Rick host build by making it separate --- examples/fully-featured/configurations/Rick.host.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) mode change 120000 => 100644 examples/fully-featured/configurations/Rick.host.nix diff --git a/examples/fully-featured/configurations/Rick.host.nix b/examples/fully-featured/configurations/Rick.host.nix deleted file mode 120000 index 6e58fce7..00000000 --- a/examples/fully-featured/configurations/Rick.host.nix +++ /dev/null @@ -1 +0,0 @@ -Morty.host.nix \ No newline at end of file diff --git a/examples/fully-featured/configurations/Rick.host.nix b/examples/fully-featured/configurations/Rick.host.nix new file mode 100644 index 00000000..ab42de77 --- /dev/null +++ b/examples/fully-featured/configurations/Rick.host.nix @@ -0,0 +1,4 @@ +{ + boot.loader.grub.devices = [ "nodev" ]; + fileSystems."/" = { device = "test"; fsType = "ext4"; }; +} From b6083768884ee2a605cd4d6739103dce24e7180c Mon Sep 17 00:00:00 2001 From: David Arnold Date: Fri, 16 Apr 2021 12:55:01 -0500 Subject: [PATCH 09/90] add simple devshell & align dev and ci environment --- .github/workflows/ci.yaml | 42 +++++++++++----------- .gitignore | 1 + devshell.toml | 74 +++++++++++++++++++++++++++++++++++++++ flake.nix | 2 ++ shell.nix | 21 +++++++++++ 5 files changed, 119 insertions(+), 21 deletions(-) create mode 100644 devshell.toml create mode 100644 shell.nix diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 758069ef..09223743 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,35 +17,35 @@ jobs: extra_nix_config: experimental-features = nix-command flakes - name: Check Nix parsing - run: find . -name "*.nix" -exec nix-instantiate --parse --quiet {} >/dev/null + + run: nix develop --command evalnix - - name: Run `nix flake check` - run: cd examples/fully-featured && nix flake check --show-trace + - name: Check Nix formatting + run: nix develop --command fmt --check - - name: Run `nix flake show` - run: cd examples/fully-featured && nix flake show --show-trace + - name: Run `nix flake check` (fully featured example) + run: nix develop --command "nix-flake-check-ff --show-trace" - - name: Build Morty configuration - run: cd examples/fully-featured && nix build .#nixosConfigurations.Morty.config.system.build.toplevel --dry-run + - name: Run `nix flake show` (fully featured example) + run: nix develop --command "nix-flake-show-ff show --show-trace" - - name: Build Rick configuration - run: cd examples/fully-featured && nix build .#someConfigurations.Rick.config.system.build.toplevel --dry-run + - name: Build Morty configuration (fully featured example) + run: nix develop --command nix-build-morty-ff - - name: Build Summer checks - run: cd examples/fully-featured && nix build .#checks.x86_64-linux.summerHasUnfreeConfigured && nix build .#checks.x86_64-linux.summerHasPackageOverridesConfigured && nix build .#checks.x86_64-linux.summerHasCustomModuleConfigured + - name: Build Rick configuration (fully featured example) + run: nix develop --command nix-build-rick-ff - - name: Run `nix flake check` - run: cd examples/somewhat-realistic && nix flake check --show-trace + - name: Build Summer checks (fully featured example) + run: nix develop --command nix-build-summer-ff - - name: Run `nix flake show` - run: cd examples/somewhat-realistic && nix flake show --show-trace + - name: Run `nix flake check` (somewhat realistic example) + run: nix develop --command "nix-flake-check-rr-example --show-trace" - - name: Build HostnameOne configuration - run: cd examples/somewhat-realistic && nix build .#nixosConfigurations.HostnameOne.config.system.build.toplevel --dry-run + - name: Run `nix flake show` (somewhat realistic example) + run: nix develop --command "nix-flake-show-rr-example --show-trace" - - name: Check Nix formatting - run: nix shell nixpkgs\#nixpkgs-fmt -c nixpkgs-fmt --check . + - name: Build HostnameOne configuration (somewhat realistic example) + run: nix develop --command nix-build-hostnameone-rr-example - - name: Build HostnameThree configuration - run: cd examples/somewhat-realistic && nix build .#darwinConfigurations.HostnameThree.config.system.build.toplevel --dry-run + - name: Build HostnameThree configuration (somewhat realistic example) + run: nix develop --command nix-build-hostnamethree-rr-example diff --git a/.gitignore b/.gitignore index 31d263bf..4a406d3e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ examples/*/flake.lock +examples/*/result diff --git a/devshell.toml b/devshell.toml new file mode 100644 index 00000000..e7ab3cb7 --- /dev/null +++ b/devshell.toml @@ -0,0 +1,74 @@ +[devshell] +name = "flake-utils-plus" +packages = [ + "fd", + "nixpkgs-fmt", +] + +[[commands]] +name = "fmt" +help = "Check Nix formatting" +category = "checks" +command = "nixpkgs-fmt ${@} ." + +[[commands]] +name = "evalnix" +help = "Check Nix parsing" +category = "checks" +command = "fd --extension nix --exec nix-instantiate --parse --quiet {} >/dev/null" + +# Checks for fully featured example +[[commands]] +name = "nix-flake-check-ff" +help = "Run 'nix flake check'" +category = "checks (fully featured example)" +command = "cd ./examples/fully-featured && nix flake check ${@}" + +[[commands]] +name = "nix-flake-show-ff" +help = "Run 'nix flake show'" +category = "checks (fully featured example)" +command = "cd ./examples/fully-featured && nix flake show ${@}" + +[[commands]] +name = "nix-build-morty-ff" +help = "Build Morty configuration" +category = "checks (fully featured example)" +command = "cd ./examples/fully-featured && nix build .#nixosConfigurations.Morty.config.system.build.toplevel --dry-run" + +[[commands]] +name = "nix-build-rick-ff" +help = "Build Rick configuration" +category = "checks (fully featured example)" +command = "cd ./examples/fully-featured && nix build .#someConfigurations.Rick.config.system.build.toplevel --dry-run" + +[[commands]] +name = "nix-build-summer-ff" +help = "Build Summer configuration" +category = "checks (fully featured example)" +command = "cd ./examples/fully-featured && nix build .#checks.x86_64-linux.summerHasUnfreeConfigured && nix build .#checks.x86_64-linux.summerHasPackageOverridesConfigured && nix build .#checks.x86_64-linux.summerHasCustomModuleConfigured" + +# Checks for somewhat realistic example +[[commands]] +name = "nix-flake-check-sr" +help = "Run 'nix flake check'" +category = "checks (somewhat realistic example)" +command = "cd ./examples/somewhat-realistic && nix flake check ${@}" + +[[commands]] +name = "nix-flake-show-sr" +help = "Run 'nix flake show'" +category = "checks (somewhat realistic example)" +command = "cd ./examples/somewhat-realistic && nix flake show ${@}" + +[[commands]] +name = "nix-build-hostnameone-sr" +help = "Build HostnameOne configuration" +category = "checks (somewhat realistic example)" +command = "cd ./examples/somewhat-realistic && nix build .#nixosConfigurations.HostnameOne.config.system.build.toplevel --dry-run" + +[[commands]] +name = "nix-build-hostnamethree-sr" +help = "Build HostnameThree (darwin) configuration" +category = "checks (somewhat realistic example)" +command = "cd ./examples/somewhat-realistic && nix build .#darwinConfigurations.HostnameThree.config.system.build.toplevel --dry-run" diff --git a/flake.nix b/flake.nix index 3e25d69e..95bb64da 100644 --- a/flake.nix +++ b/flake.nix @@ -15,6 +15,8 @@ nixosModules.saneFlakeDefaults = import ./modules/saneFlakeDefaults.nix; + devShell.x86_64-linux = import ./shell.nix { system = "x86_64-linux"; }; + lib = flake-utils.lib // { # modulesFromList is deprecated, will be removed in future releases inherit systemFlake modulesFromList; diff --git a/shell.nix b/shell.nix new file mode 100644 index 00000000..10427a03 --- /dev/null +++ b/shell.nix @@ -0,0 +1,21 @@ +{ system ? builtins.currentSystem }: +let + # nixpkgs / devshell is only used for development. Don't add it to the flake.lock. + nixpkgsGitRev = "5268ee2ebacbc73875be42d71e60c2b5c1b5a1c7"; + devshellGitRev = "709fe4d04a9101c9d224ad83f73416dce71baf21"; + + nixpkgsSrc = fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsGitRev}.tar.gz"; + sha256 = "080fvmg0i6z01h6adddfrjp1bbbjhhqk32ks6ch9gv689645ccfq"; + }; + + devshellSrc = fetchTarball { + url = "https://github.com/numtide/devshell/archive/${devshellGitRev}.tar.gz"; + sha256 = "1px9cqfshfqs1b7ypyxch3s3ymr4xgycy1krrcg7b97rmmszvsqr"; + }; + + pkgs = import nixpkgsSrc { inherit system; }; + devshell = import devshellSrc { inherit system pkgs; }; + +in +devshell.fromTOML ./devshell.toml From 80b53eeda3102bb5aed31ec818c6485e35caffc3 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Tue, 20 Apr 2021 12:14:58 -0500 Subject: [PATCH 10/90] fixups / cleanups devshell --- .github/workflows/ci.yaml | 12 ++++++------ devshell.toml | 8 ++++---- examples/somewhat-realistic/flake.nix | 12 ++++++------ .../somewhat-realistic/hosts/{One.nix => Alice.nix} | 0 .../somewhat-realistic/hosts/{Two.nix => Bob.nix} | 0 .../somewhat-realistic/hosts/{Three.nix => Carl.nix} | 0 6 files changed, 16 insertions(+), 16 deletions(-) rename examples/somewhat-realistic/hosts/{One.nix => Alice.nix} (100%) rename examples/somewhat-realistic/hosts/{Two.nix => Bob.nix} (100%) rename examples/somewhat-realistic/hosts/{Three.nix => Carl.nix} (100%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 09223743..f2cf67e5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,14 +38,14 @@ jobs: run: nix develop --command nix-build-summer-ff - name: Run `nix flake check` (somewhat realistic example) - run: nix develop --command "nix-flake-check-rr-example --show-trace" + run: nix develop --command "nix-flake-check-rr --show-trace" - name: Run `nix flake show` (somewhat realistic example) - run: nix develop --command "nix-flake-show-rr-example --show-trace" + run: nix develop --command "nix-flake-show-rr --show-trace" - - name: Build HostnameOne configuration (somewhat realistic example) - run: nix develop --command nix-build-hostnameone-rr-example + - name: Build Alice configuration (somewhat realistic example) + run: nix develop --command nix-build-alice-rr - - name: Build HostnameThree configuration (somewhat realistic example) - run: nix develop --command nix-build-hostnamethree-rr-example + - name: Build Carl (darwin) configuration (somewhat realistic example) + run: nix develop --command nix-build-carl-rr diff --git a/devshell.toml b/devshell.toml index e7ab3cb7..85e264e4 100644 --- a/devshell.toml +++ b/devshell.toml @@ -62,13 +62,13 @@ category = "checks (somewhat realistic example)" command = "cd ./examples/somewhat-realistic && nix flake show ${@}" [[commands]] -name = "nix-build-hostnameone-sr" -help = "Build HostnameOne configuration" +name = "nix-build-alice-sr" +help = "Build Alice configuration" category = "checks (somewhat realistic example)" command = "cd ./examples/somewhat-realistic && nix build .#nixosConfigurations.HostnameOne.config.system.build.toplevel --dry-run" [[commands]] -name = "nix-build-hostnamethree-sr" -help = "Build HostnameThree (darwin) configuration" +name = "nix-build-carl-sr" +help = "Build Carl (darwin) configuration" category = "checks (somewhat realistic example)" command = "cd ./examples/somewhat-realistic && nix build .#darwinConfigurations.HostnameThree.config.system.build.toplevel --dry-run" diff --git a/examples/somewhat-realistic/flake.nix b/examples/somewhat-realistic/flake.nix index be1165d8..bda46264 100644 --- a/examples/somewhat-realistic/flake.nix +++ b/examples/somewhat-realistic/flake.nix @@ -66,24 +66,24 @@ # Profiles, gets parsed into `nixosConfigurations` - hosts.HostnameOne.modules = [ + hosts.Alice.modules = [ home-manager.nixosModules.home-manager - ./hosts/One.nix + ./hosts/Alice.nix ]; - hosts.HostnameTwo = { + hosts.Bob = { # This host uses `channels.unstable.{input,overlaysBuilder,config,patches}` attributes instead of `channels.nixpkgs.<...>` channelName = "unstable"; # Host specific configuration. modules = [ home-manager.nixosModules.home-manager - ./hosts/Two.nix + ./hosts/Bob.nix ]; }; - hosts."HostnameThree" = { + hosts."Carl" = { # This host will be exported under the flake's `darwinConfigurations` output output = "darwinConfigurations"; @@ -98,7 +98,7 @@ # Host specific configuration. modules = [ home-manager.darwinModules.home-manager - ./hosts/Three.nix + ./hosts/Carl.nix ]; }; diff --git a/examples/somewhat-realistic/hosts/One.nix b/examples/somewhat-realistic/hosts/Alice.nix similarity index 100% rename from examples/somewhat-realistic/hosts/One.nix rename to examples/somewhat-realistic/hosts/Alice.nix diff --git a/examples/somewhat-realistic/hosts/Two.nix b/examples/somewhat-realistic/hosts/Bob.nix similarity index 100% rename from examples/somewhat-realistic/hosts/Two.nix rename to examples/somewhat-realistic/hosts/Bob.nix diff --git a/examples/somewhat-realistic/hosts/Three.nix b/examples/somewhat-realistic/hosts/Carl.nix similarity index 100% rename from examples/somewhat-realistic/hosts/Three.nix rename to examples/somewhat-realistic/hosts/Carl.nix From be032a4396ad4cd7ea9bb733db8e456ec339ac9c Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 16:42:19 -0700 Subject: [PATCH 11/90] prevent infinite recursion in overlays exporter sometimes the inputs argument might contain "self", so drop that if it does. This is just for safety, it usually won't contain self --- overlaysFromChannelsExporter.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/overlaysFromChannelsExporter.nix b/overlaysFromChannelsExporter.nix index 8eb4536e..ccaed14e 100644 --- a/overlaysFromChannelsExporter.nix +++ b/overlaysFromChannelsExporter.nix @@ -51,7 +51,9 @@ let overlayNames = overlay: attrNames (overlay null null); # get all overlays from inputs - inputOverlays = mapAttrs (_: v: [ v.overlay or (_: _: { }) ] ++ attrValues v.overlays or { }) inputs; + inputOverlays = mapAttrs + (_: v: [ v.overlay or (_: _: { }) ] ++ attrValues v.overlays or { }) + (removeAttrs inputs [ "self" ]); # use overlayNames as a way to identify overlays flattenedInputOverlays = map overlayNames (foldl' (a: b: a ++ b) [ ] (attrValues inputOverlays)); From 8eb7f9206713a528174c20c5133521dc37e2bfb1 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 23:45:51 -0700 Subject: [PATCH 12/90] export mergeAny in public lib --- flake.nix | 11 +++++++++++ systemFlake.nix | 14 ++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/flake.nix b/flake.nix index 95bb64da..faa664ff 100644 --- a/flake.nix +++ b/flake.nix @@ -5,6 +5,7 @@ outputs = { self, flake-utils }: let + inherit (builtins) isList isAttrs mapAttrs; fupArgs = { flake-utils-plus = self; }; systemFlake = import ./systemFlake.nix fupArgs; packagesFromOverlaysBuilderConstructor = import ./packagesFromOverlaysBuilderConstructor.nix fupArgs; @@ -31,6 +32,16 @@ repl = ./repl.nix; + # merge nested attribute sets and lists + mergeAny = lhs: rhs: + lhs // mapAttrs + (name: value: + if isAttrs value then lhs.${name} or { } // value + else if isList value then lhs.${name} or [ ] ++ value + else value + ) + rhs; + patchChannel = system: channel: patches: if patches == [ ] then channel else (import channel { inherit system; }).pkgs.applyPatches { diff --git a/systemFlake.nix b/systemFlake.nix index 3010bc83..2222eb78 100644 --- a/systemFlake.nix +++ b/systemFlake.nix @@ -29,8 +29,8 @@ }@args: let - inherit (flake-utils-plus.lib) eachSystem patchChannel; - inherit (builtins) foldl' mapAttrs removeAttrs attrValues attrNames isAttrs isList; + inherit (flake-utils-plus.lib) eachSystem patchChannel mergeAny; + inherit (builtins) foldl' mapAttrs removeAttrs attrValues attrNames; # set defaults and validate host arguments evalHostArgs = @@ -46,16 +46,6 @@ let inherit channelName system output builder modules extraArgs specialArgs; }; - # recursively merge attribute sets and lists up to a certain depth - mergeAny = lhs: rhs: - lhs // mapAttrs - (name: value: - if isAttrs value then lhs.${name} or { } // value - else if isList value then lhs.${name} or [ ] ++ value - else value - ) - rhs; - foldHosts = foldl' mergeAny { }; optionalAttrs = check: value: if check then value else { }; From 7c085ed23f56e8e3bcbb8b0c8278f08eb556c7c6 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Tue, 27 Apr 2021 22:12:18 +0300 Subject: [PATCH 13/90] Add 'srcs' to overlays --- systemFlake.nix | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/systemFlake.nix b/systemFlake.nix index 2222eb78..bc27b8b1 100644 --- a/systemFlake.nix +++ b/systemFlake.nix @@ -30,7 +30,12 @@ let inherit (flake-utils-plus.lib) eachSystem patchChannel mergeAny; - inherit (builtins) foldl' mapAttrs removeAttrs attrValues attrNames; + inherit (builtins) foldl' mapAttrs removeAttrs attrValues attrNames listToAttrs concatMap; + + filterAttrs = pred: set: + listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); + + srcs = filterAttrs (_: value: !value ? outputs) inputs; # set defaults and validate host arguments evalHostArgs = @@ -168,7 +173,7 @@ mergeAny otherArguments ( let importChannel = name: value: (import (patchChannel system value.input (value.patches or [ ])) { inherit system; - overlays = sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]); + overlays = [ (final: prev: { inherit srcs; }) ] ++ sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]); config = channelsConfig // (value.config or { }); }) // { inherit name; inherit (value) input; }; From 1d2be7304d54214c66ab824b32e5adff16c879b2 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Wed, 28 Apr 2021 10:11:50 -0700 Subject: [PATCH 14/90] Add ability to create non-exported overlays with the __dontExport property --- examples/somewhat-realistic/flake.nix | 7 +++++++ overlaysFromChannelsExporter.nix | 11 +++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/examples/somewhat-realistic/flake.nix b/examples/somewhat-realistic/flake.nix index bda46264..8504e144 100644 --- a/examples/somewhat-realistic/flake.nix +++ b/examples/somewhat-realistic/flake.nix @@ -43,6 +43,13 @@ # Overwrites specified packages to be used from unstable channel. inherit (channels.unstable) alacritty ranger; }) + (final: prev: { + lib = prev.lib.extend (lfinal: lprev: { + utils = utils.lib; + }); + # As long as the attribute exists, overlaysFromChannelsExporter won't export it + __dontExport = true; + }) agenix.overlay ]; diff --git a/overlaysFromChannelsExporter.nix b/overlaysFromChannelsExporter.nix index ccaed14e..3c2e9480 100644 --- a/overlaysFromChannelsExporter.nix +++ b/overlaysFromChannelsExporter.nix @@ -9,6 +9,8 @@ let inputs: flake inputs to sort out external overlays + Overlays with an attribute named "__dontExport" will be filtered out. + Returns an attribute set of all packages defined in an overlay by any channel intended to be passed to be exported via _self.overlays_. This method of sharing has the advantage over _self.packages_, that the user will instantiate @@ -68,10 +70,11 @@ let ) (overlayNames overlay); - filterOverlays = channel: - filter - (overlay: !elem (overlayNames overlay) flattenedInputOverlays) - channel.overlays; + checkOverlay = overlay: + (!elem (overlayNames overlay) flattenedInputOverlays) + && (!elem "__dontExport" (overlayNames overlay)); + + filterOverlays = channel: filter checkOverlay channel.overlays; in listToAttrs ( From 1630b591a12d30fbeb58a193edee5bb3614a761f Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 2 May 2021 08:44:50 -0700 Subject: [PATCH 15/90] always use self.pkgs instead of channels this allows systemFlake to be called multiple times without having to pass `channels` each time. As long as it just uses self.pkgs, nixpkgs will only get evaluated once and all systemFlake calls use the same channels set --- systemFlake.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/systemFlake.nix b/systemFlake.nix index bc27b8b1..6af31421 100644 --- a/systemFlake.nix +++ b/systemFlake.nix @@ -42,7 +42,7 @@ let { channelName ? "nixpkgs" , system ? "x86_64-linux" , output ? "nixosConfigurations" - , builder ? channels.${channelName}.input.lib.nixosSystem + , builder ? (getChannels system).${channelName}.input.lib.nixosSystem , modules ? [ ] , extraArgs ? { } # These are not part of the module system, so they can be used in `imports` lines without infinite recursion @@ -77,13 +77,15 @@ let "checksBuilder" ]; - getNixpkgs = host: self.pkgs."${host.system}"."${host.channelName}"; + getChannels = system: self.pkgs.${system}; + getNixpkgs = host: (getChannels host.system).${host.channelName}; configurationBuilder = hostname: host': ( let selectedNixpkgs = getNixpkgs host; host = evalHostArgs (mergeAny hostDefaults host'); patchedChannel = selectedNixpkgs.path; + channels = getChannels host.system; specialArgs = host.specialArgs // { channel = selectedNixpkgs; }; From f325752250124ead1302523cb479b4b9a83cb836 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 2 May 2021 08:51:35 -0700 Subject: [PATCH 16/90] set __dontExport to srcs overlay This doesn't hurt in any way, but prevents export for those who use overlaysFromChannelsExporter --- systemFlake.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/systemFlake.nix b/systemFlake.nix index bc27b8b1..7129e66d 100644 --- a/systemFlake.nix +++ b/systemFlake.nix @@ -173,7 +173,12 @@ mergeAny otherArguments ( let importChannel = name: value: (import (patchChannel system value.input (value.patches or [ ])) { inherit system; - overlays = [ (final: prev: { inherit srcs; }) ] ++ sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]); + overlays = [ + (final: prev: { + __dontExport = true; # in case user uses overlaysFromChannelsExporter, doesn't hurt for others + inherit srcs; + }) + ] ++ sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]); config = channelsConfig // (value.config or { }); }) // { inherit name; inherit (value) input; }; From 1a742047f3f7c97b22768ba7738ac5a01052099e Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 11 May 2021 23:32:21 -0700 Subject: [PATCH 17/90] flake: update flake-utils input includes filterPackages improvements --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 974429ba..2387309c 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-utils": { "locked": { - "lastModified": 1619345332, - "narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=", + "lastModified": 1620759905, + "narHash": "sha256-WiyWawrgmyN0EdmiHyG2V+fqReiVi8bM9cRdMaKQOFg=", "owner": "numtide", "repo": "flake-utils", - "rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28", + "rev": "b543720b25df6ffdfcf9227afafc5b8c1fabfae8", "type": "github" }, "original": { From f4d05364b87c64f32f2c395d1be88ef188265fac Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sat, 15 May 2021 16:47:15 +0300 Subject: [PATCH 18/90] Work on tests and restructoring (#54) * Add tests/derivation-outputs * Remove cases covered by tests * Add channel patching test cases * Remove patching code leftovers as part of the example * Remove Summer CI * Add tests/overlays-flow * Fix devshell root path * Fix overlays tests * Cleanup tests * Work on hosts config test * Add rm-locks command * Add validation for host options inheritance * Evaluate builder * Add examples/minimal-multichannel * Add examples/home-manager+nur+neovim * Add examples/exporters * Remove examples/fully-featured * Remove devshell.toml * Moving files around * Fix rm-locks command and add exporters build * Improve devshell --- .github/workflows/ci.yaml | 46 ++--- devShell.nix | 83 +++++++++ devshell.toml | 74 -------- examples/exporters/flake.nix | 43 +++++ .../Alice.nix => exporters/hosts/Morty.nix} | 0 examples/exporters/overlays/default.nix | 3 + .../configurations/Morty.host.nix | 8 - .../configurations/Summer.host.nix | 6 - examples/fully-featured/flake.nix | 170 ------------------ examples/fully-featured/modules/default.nix | 1 - examples/home-manager+nur+neovim/flake.nix | 55 ++++++ .../hosts/Rick.nix} | 3 +- .../sharedConfigurationBetweenHosts.nix | 11 ++ .../overlays/default.nix | 0 examples/minimal-multichannel/flake.nix | 49 +++++ .../minimal-multichannel/hosts/Hostname1.nix | 5 + .../minimal-multichannel/hosts/Hostname2.nix | 1 + .../sharedConfigurationBetweenHosts.nix | 2 + examples/somewhat-realistic/flake.nix | 127 ------------- examples/somewhat-realistic/hosts/Bob.nix | 1 - examples/somewhat-realistic/hosts/Carl.nix | 1 - .../somewhat-realistic/modules/default.nix | 1 - .../somewhat-realistic/overlays/default.nix | 1 - flake.nix | 23 ++- shell.nix | 21 --- .../fromOverlays.nix | 0 .../internalOverlays.nix | 0 .../modulesFromList.nix | 0 repl.nix => src/repl.nix | 0 {modules => src}/saneFlakeDefaults.nix | 0 systemFlake.nix => src/systemFlake.nix | 13 +- tests/channel-patching/flake.nix | 81 +++++++++ .../channel-patching}/myNixpkgsPatch.patch | 0 tests/derivation-outputs/flake.nix | 94 ++++++++++ tests/hosts-config/flake.nix | 111 ++++++++++++ tests/overlays-flow/flake.nix | 96 ++++++++++ tests/testing-utils.nix | 19 ++ 37 files changed, 688 insertions(+), 461 deletions(-) create mode 100644 devShell.nix delete mode 100644 devshell.toml create mode 100644 examples/exporters/flake.nix rename examples/{somewhat-realistic/hosts/Alice.nix => exporters/hosts/Morty.nix} (100%) create mode 100644 examples/exporters/overlays/default.nix delete mode 100644 examples/fully-featured/configurations/Morty.host.nix delete mode 100644 examples/fully-featured/configurations/Summer.host.nix delete mode 100644 examples/fully-featured/flake.nix delete mode 100644 examples/fully-featured/modules/default.nix create mode 100644 examples/home-manager+nur+neovim/flake.nix rename examples/{fully-featured/configurations/Rick.host.nix => home-manager+nur+neovim/hosts/Rick.nix} (51%) create mode 100644 examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix rename examples/{fully-featured => home-manager+nur+neovim}/overlays/default.nix (100%) create mode 100644 examples/minimal-multichannel/flake.nix create mode 100644 examples/minimal-multichannel/hosts/Hostname1.nix create mode 120000 examples/minimal-multichannel/hosts/Hostname2.nix create mode 100644 examples/minimal-multichannel/modules/sharedConfigurationBetweenHosts.nix delete mode 100644 examples/somewhat-realistic/flake.nix delete mode 120000 examples/somewhat-realistic/hosts/Bob.nix delete mode 100644 examples/somewhat-realistic/hosts/Carl.nix delete mode 100644 examples/somewhat-realistic/modules/default.nix delete mode 100644 examples/somewhat-realistic/overlays/default.nix delete mode 100644 shell.nix rename packagesFromOverlaysBuilderConstructor.nix => src/fromOverlays.nix (100%) rename overlaysFromChannelsExporter.nix => src/internalOverlays.nix (100%) rename moduleFromListExporter.nix => src/modulesFromList.nix (100%) rename repl.nix => src/repl.nix (100%) rename {modules => src}/saneFlakeDefaults.nix (100%) rename systemFlake.nix => src/systemFlake.nix (95%) create mode 100644 tests/channel-patching/flake.nix rename {examples/fully-featured => tests/channel-patching}/myNixpkgsPatch.patch (100%) create mode 100644 tests/derivation-outputs/flake.nix create mode 100644 tests/hosts-config/flake.nix create mode 100644 tests/overlays-flow/flake.nix create mode 100644 tests/testing-utils.nix diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f2cf67e5..ee13d49a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,7 +6,7 @@ on: types: [opened] jobs: - quality-gate: + tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 @@ -16,36 +16,20 @@ jobs: install_url: https://github.com/numtide/nix-flakes-installer/releases/download/nix-3.0pre20201007_5257a25/install extra_nix_config: experimental-features = nix-command flakes - - name: Check Nix parsing - run: nix develop --command evalnix + # Quick eval + - run: nix develop --command evalnix - - name: Check Nix formatting - run: nix develop --command fmt --check + # Execute /tests/* + - run: nix develop --command check-derivation-outputs + - run: nix develop --command check-channel-patching + - run: nix develop --command check-overlays-flow + - run: nix develop --command check-hosts-config - - name: Run `nix flake check` (fully featured example) - run: nix develop --command "nix-flake-check-ff --show-trace" - - - name: Run `nix flake show` (fully featured example) - run: nix develop --command "nix-flake-show-ff show --show-trace" - - - name: Build Morty configuration (fully featured example) - run: nix develop --command nix-build-morty-ff - - - name: Build Rick configuration (fully featured example) - run: nix develop --command nix-build-rick-ff - - - name: Build Summer checks (fully featured example) - run: nix develop --command nix-build-summer-ff - - - name: Run `nix flake check` (somewhat realistic example) - run: nix develop --command "nix-flake-check-rr --show-trace" - - - name: Run `nix flake show` (somewhat realistic example) - run: nix develop --command "nix-flake-show-rr --show-trace" - - - name: Build Alice configuration (somewhat realistic example) - run: nix develop --command nix-build-alice-rr - - - name: Build Carl (darwin) configuration (somewhat realistic example) - run: nix develop --command nix-build-carl-rr + # Build /examples/* + - run: nix develop --command build-home-manager+nur+neovim-Rick + - run: nix develop --command build-minimal-multichannel-Hostname1 + - run: nix develop --command build-minimal-multichannel-Hostname2 + - run: nix develop --command build-exporters-Morty + # Check formatting + - run: nix develop --command fmt --check diff --git a/devShell.nix b/devShell.nix new file mode 100644 index 00000000..428ef72b --- /dev/null +++ b/devShell.nix @@ -0,0 +1,83 @@ +{ system ? builtins.currentSystem }: +let + # nixpkgs / devshell is only used for development. Don't add it to the flake.lock. + nixpkgsGitRev = "5268ee2ebacbc73875be42d71e60c2b5c1b5a1c7"; + devshellGitRev = "709fe4d04a9101c9d224ad83f73416dce71baf21"; + + nixpkgsSrc = fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsGitRev}.tar.gz"; + sha256 = "080fvmg0i6z01h6adddfrjp1bbbjhhqk32ks6ch9gv689645ccfq"; + }; + + devshellSrc = fetchTarball { + url = "https://github.com/numtide/devshell/archive/${devshellGitRev}.tar.gz"; + sha256 = "1px9cqfshfqs1b7ypyxch3s3ymr4xgycy1krrcg7b97rmmszvsqr"; + }; + + pkgs = import nixpkgsSrc { inherit system; }; + devshell = import devshellSrc { inherit system pkgs; }; + + withCategory = category: attrset: attrset // { inherit category; }; + util = withCategory "utils"; + + test = name: withCategory "tests" { + name = "check-${name}"; + help = "Checks ${name} testcases"; + command = '' + set -e + cd $DEVSHELL_ROOT/tests/${name} + nix flake lock --update-input utils + nix flake show + nix flake check + git rm -f flake.lock + ''; + }; + + dry-nixos-build = example: host: withCategory "dry-build" { + name = "build-${example}-${host}"; + command = '' + set -e + cd $DEVSHELL_ROOT/examples/${example} + nix flake lock --update-input utils + nix flake show + nix build .#nixosConfigurations.${host}.config.system.build.toplevel --dry-run + git rm -f flake.lock + ''; + }; + +in +devshell.mkShell { + name = "flake-utils-plus"; + packages = with pkgs; [ + fd + nixpkgs-fmt + ]; + + commands = [ + { + command = "git rm --ignore-unmatch -f $DEVSHELL_ROOT/{tests,examples}/*/flake.lock"; + help = "Remove all lock files"; + name = "rm-locks"; + } + { + name = "fmt"; + help = "Check Nix formatting"; + command = "nixpkgs-fmt \${@} $DEVSHELL_ROOT"; + } + { + name = "evalnix"; + help = "Check Nix parsing"; + command = "fd --extension nix --exec nix-instantiate --parse --quiet {} >/dev/null"; + } + + (test "channel-patching") + (test "derivation-outputs") + (test "hosts-config") + (test "overlays-flow") + (dry-nixos-build "minimal-multichannel" "Hostname1") + (dry-nixos-build "minimal-multichannel" "Hostname2") + (dry-nixos-build "home-manager+nur+neovim" "Rick") + (dry-nixos-build "exporters" "Morty") + ]; + +} diff --git a/devshell.toml b/devshell.toml deleted file mode 100644 index 85e264e4..00000000 --- a/devshell.toml +++ /dev/null @@ -1,74 +0,0 @@ -[devshell] -name = "flake-utils-plus" -packages = [ - "fd", - "nixpkgs-fmt", -] - -[[commands]] -name = "fmt" -help = "Check Nix formatting" -category = "checks" -command = "nixpkgs-fmt ${@} ." - -[[commands]] -name = "evalnix" -help = "Check Nix parsing" -category = "checks" -command = "fd --extension nix --exec nix-instantiate --parse --quiet {} >/dev/null" - -# Checks for fully featured example -[[commands]] -name = "nix-flake-check-ff" -help = "Run 'nix flake check'" -category = "checks (fully featured example)" -command = "cd ./examples/fully-featured && nix flake check ${@}" - -[[commands]] -name = "nix-flake-show-ff" -help = "Run 'nix flake show'" -category = "checks (fully featured example)" -command = "cd ./examples/fully-featured && nix flake show ${@}" - -[[commands]] -name = "nix-build-morty-ff" -help = "Build Morty configuration" -category = "checks (fully featured example)" -command = "cd ./examples/fully-featured && nix build .#nixosConfigurations.Morty.config.system.build.toplevel --dry-run" - -[[commands]] -name = "nix-build-rick-ff" -help = "Build Rick configuration" -category = "checks (fully featured example)" -command = "cd ./examples/fully-featured && nix build .#someConfigurations.Rick.config.system.build.toplevel --dry-run" - -[[commands]] -name = "nix-build-summer-ff" -help = "Build Summer configuration" -category = "checks (fully featured example)" -command = "cd ./examples/fully-featured && nix build .#checks.x86_64-linux.summerHasUnfreeConfigured && nix build .#checks.x86_64-linux.summerHasPackageOverridesConfigured && nix build .#checks.x86_64-linux.summerHasCustomModuleConfigured" - -# Checks for somewhat realistic example -[[commands]] -name = "nix-flake-check-sr" -help = "Run 'nix flake check'" -category = "checks (somewhat realistic example)" -command = "cd ./examples/somewhat-realistic && nix flake check ${@}" - -[[commands]] -name = "nix-flake-show-sr" -help = "Run 'nix flake show'" -category = "checks (somewhat realistic example)" -command = "cd ./examples/somewhat-realistic && nix flake show ${@}" - -[[commands]] -name = "nix-build-alice-sr" -help = "Build Alice configuration" -category = "checks (somewhat realistic example)" -command = "cd ./examples/somewhat-realistic && nix build .#nixosConfigurations.HostnameOne.config.system.build.toplevel --dry-run" - -[[commands]] -name = "nix-build-carl-sr" -help = "Build Carl (darwin) configuration" -category = "checks (somewhat realistic example)" -command = "cd ./examples/somewhat-realistic && nix build .#darwinConfigurations.HostnameThree.config.system.build.toplevel --dry-run" diff --git a/examples/exporters/flake.nix b/examples/exporters/flake.nix new file mode 100644 index 00000000..0699b882 --- /dev/null +++ b/examples/exporters/flake.nix @@ -0,0 +1,43 @@ +{ + description = "A highly awesome system configuration."; + + inputs = { + nixpkgs.url = github:nixos/nixpkgs/release-20.09; + utils.url = path:../../; + }; + + + outputs = inputs@{ self, nixpkgs, utils }: + let + inherit (utils.lib.exporters) internalOverlays fromOverlays modulesFromList; + in + utils.lib.systemFlake { + inherit self inputs; + + channels.nixpkgs.input = nixpkgs; + + hosts.Morty.modules = with self.nixosModules; [ + Morty + ]; + + sharedOverlays = [ + self.overlay + ]; + + nixosModules = modulesFromList [ + ./hosts/Morty.nix + ]; + + # export overlays automatically for all packages defined in overlaysBuilder of each channel + overlays = internalOverlays { + inherit (self) pkgs inputs; + }; + + # construct packagesBuilder to export all packages defined in overlays + #packagesBuilder = fromOverlays self.overlays; + + overlay = import ./overlays; + + }; +} + diff --git a/examples/somewhat-realistic/hosts/Alice.nix b/examples/exporters/hosts/Morty.nix similarity index 100% rename from examples/somewhat-realistic/hosts/Alice.nix rename to examples/exporters/hosts/Morty.nix diff --git a/examples/exporters/overlays/default.nix b/examples/exporters/overlays/default.nix new file mode 100644 index 00000000..ed2c3da0 --- /dev/null +++ b/examples/exporters/overlays/default.nix @@ -0,0 +1,3 @@ +final: prev: { + inherit (prev) coreutils; +} diff --git a/examples/fully-featured/configurations/Morty.host.nix b/examples/fully-featured/configurations/Morty.host.nix deleted file mode 100644 index 16a1c13c..00000000 --- a/examples/fully-featured/configurations/Morty.host.nix +++ /dev/null @@ -1,8 +0,0 @@ -# auto-special args ModulesPath for easy backporting of modules -{ unstableModulesPath, ... }: { - - imports = [ "${unstableModulesPath}/installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ]; - disabledModules = [ "installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ]; - - boot.loader.grub.devices = [ "nodev" ]; -} diff --git a/examples/fully-featured/configurations/Summer.host.nix b/examples/fully-featured/configurations/Summer.host.nix deleted file mode 100644 index 8f3273eb..00000000 --- a/examples/fully-featured/configurations/Summer.host.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ lib, ... }: { - boot.loader.grub.devices = [ "nodev" ]; - fileSystems."/" = { device = "test"; fsType = "ext4"; }; - patchedModule.test = lib.patchedFunction "test"; - nixpkgs.config.packageOverrides = pkgs: { }; -} diff --git a/examples/fully-featured/flake.nix b/examples/fully-featured/flake.nix deleted file mode 100644 index 2f4f45d4..00000000 --- a/examples/fully-featured/flake.nix +++ /dev/null @@ -1,170 +0,0 @@ -{ - description = "A highly awesome system configuration."; - - inputs = { - nixpkgs.url = github:nixos/nixpkgs/release-20.09; - unstable.url = github:nixos/nixpkgs/nixos-unstable; - nur.url = github:nix-community/NUR; - utils.url = path:../../; - - home-manager = { - url = github:nix-community/home-manager/master; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - neovim = { - url = github:neovim/neovim?dir=contrib; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - }; - - - outputs = inputs@{ self, nixpkgs, unstable, nur, utils, home-manager, neovim }: - utils.lib.systemFlake { - - # `self` and `inputs` arguments are REQUIRED!!!!!!!!!!!!!! - inherit self inputs; - - # Supported systems, used for packages, apps, devShell and multiple other definitions. Defaults to `flake-utils.lib.defaultSystems` - supportedSystems = [ "x86_64-linux" ]; - - - # Default host settings. - hostDefaults = { - # Default architecture to be used for `hosts` defaults to "x86_64-linux" - system = "x86_64-linux"; - # Default channel to be used for `hosts` defaults to "nixpkgs" - channelName = "unstable"; - # Extra arguments to be passed to modules. Merged with host's extraArgs - extraArgs = { inherit utils inputs; foo = "foo"; }; - # Default modules to be passed to all hosts. - modules = [ - home-manager.nixosModules.home-manager - # Sets sane `nix.*` defaults. Please refer to implementation/readme for more details. - utils.nixosModules.saneFlakeDefaults - (import ./modules) - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - } - ]; - - }; - - # Shared overlays between channels, gets applied to all `channels..input` - sharedOverlays = [ - # Overlay imported from `./overlays`. (Defined below) - self.overlay - # Nix User Repository overlay - nur.overlay - ]; - - - - # Channel definitions. `channels..{input,overlaysBuilder,config,patches}` - channels.nixpkgs = { - # Channel input to import - input = nixpkgs; - - # Channel specific overlays - overlaysBuilder = channels: [ - (final: prev: { inherit (channels.unstable) zsh; }) - ]; - - # Channel specific configuration. Overwrites `channelsConfig` argument - config = { - allowUnfree = false; - }; - }; - - # Additional channel input - channels.unstable.input = unstable; - # Yep, you see it first folks - you can patch nixpkgs! - channels.unstable.patches = [ ./myNixpkgsPatch.patch ]; - channels.unstable.overlaysBuilder = channels: [ - (final: prev: { - neovim-nightly = neovim.defaultPackage.${prev.system}; - }) - ]; - - - # Default configuration values for `channels..config = {...}` - channelsConfig = { - allowBroken = true; - allowUnfree = true; - }; - - # Host definitions - hosts = { - # Profile name / System hostname - Morty = { - # System architecture. - system = "x86_64-linux"; - # of the channel to be used. Defaults to `nixpkgs` - channelName = "unstable"; - # Extra arguments to be passed to the modules. - extraArgs = { - abc = 123; - }; - # Host specific configuration. - modules = [ ./configurations/Morty.host.nix ]; - }; - - Rick = { - modules = [ ./configurations/Rick.host.nix ]; - output = "someConfigurations"; - }; - - Summer = { - channelName = "unstable"; - modules = [ ./configurations/Summer.host.nix ]; - }; - }; - - # Evaluates to `packages..attributeKey = "attributeValue"` - packagesBuilder = channels: { inherit (channels.unstable) coreutils; }; - - # Evaluates to `defaultPackage..attributeKey = "attributeValue"` - defaultPackageBuilder = channels: channels.nixpkgs.runCommandNoCC "package" { } "echo package > $out"; - - # Evaluates to `apps..attributeKey = "attributeValue"` - appsBuilder = channels: { package = { type = "app"; program = channels.nixpkgs.runCommandNoCC "package" { } "echo test > $out"; }; }; - - # Evaluates to `defaultApp..attributeKey = "attributeValue"` - defaultAppBuilder = channels: { type = "app"; program = channels.nixpkgs.runCommandNoCC "package" { } "echo test > $out"; }; - - # Evaluates to `devShell. = "attributeValue"` - devShellBuilder = channels: channels.nixpkgs.mkShell { name = "devShell"; }; - - # Evaluates to `checks..attributeKey = "attributeValue"` - checksBuilder = channels: - let - booleanCheck = cond: - if cond - then channels.nixpkgs.runCommandNoCC "success" { } "echo success > $out" - else channels.nixpkgs.runCommandNoCC "failure" { } "exit 1"; - in - { - check = channels.nixpkgs.runCommandNoCC "test" { } "echo test > $out"; - # Modules (and lib) from patched nixpkgs are used - summerHasCustomModuleConfigured = booleanCheck (self.nixosConfigurations.Summer.config.patchedModule.test == "test"); - # nixpkgs config from host-specific module is used - summerHasPackageOverridesConfigured = booleanCheck (self.nixosConfigurations.Summer.config.nixpkgs.pkgs.config ? packageOverrides); - # nixpkgs config from channel is also used - summerHasUnfreeConfigured = booleanCheck (self.nixosConfigurations.Summer.config.nixpkgs.pkgs.config ? allowUnfree); - }; - - # All other values gets passed down to the flake - checks.x86_64-linux.merge-with-checksBuilder-test = self.pkgs.x86_64-linux.nixpkgs.hello; - packages.x86_64-linux.patched-package = self.pkgs.x86_64-linux.unstable.flake-utils-plus-test; - overlay = import ./overlays; - abc = 132; - # etc - - }; -} - - - - diff --git a/examples/fully-featured/modules/default.nix b/examples/fully-featured/modules/default.nix deleted file mode 100644 index c915eb0a..00000000 --- a/examples/fully-featured/modules/default.nix +++ /dev/null @@ -1 +0,0 @@ -{ ... }: { } diff --git a/examples/home-manager+nur+neovim/flake.nix b/examples/home-manager+nur+neovim/flake.nix new file mode 100644 index 00000000..a8d29570 --- /dev/null +++ b/examples/home-manager+nur+neovim/flake.nix @@ -0,0 +1,55 @@ +{ + description = "A highly awesome system configuration."; + + inputs = { + nixpkgs.url = github:nixos/nixpkgs/nixos-unstable; + utils.url = path:../../; + + + nur.url = github:nix-community/NUR; + + neovim = { + url = github:neovim/neovim?dir=contrib; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + home-manager = { + url = github:nix-community/home-manager/release-20.09; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + + outputs = inputs@{ self, nixpkgs, utils, home-manager, neovim, nur }: + utils.lib.systemFlake { + inherit self inputs; + + + channels.nixpkgs.input = nixpkgs; + channelsConfig.allowUnfree = true; + + sharedOverlays = [ + nur.overlay + self.overlay + neovim.overlay + ]; + + + # Modules shared between all hosts + hostDefaults.modules = [ + utils.nixosModules.saneFlakeDefaults + home-manager.nixosModules.home-manager + ./modules/sharedConfigurationBetweenHosts.nix + ]; + + + hosts.Rick.modules = [ + ./hosts/Rick.nix + ]; + + + overlay = import ./overlays; + + }; +} + diff --git a/examples/fully-featured/configurations/Rick.host.nix b/examples/home-manager+nur+neovim/hosts/Rick.nix similarity index 51% rename from examples/fully-featured/configurations/Rick.host.nix rename to examples/home-manager+nur+neovim/hosts/Rick.nix index ab42de77..dcaa4a0a 100644 --- a/examples/fully-featured/configurations/Rick.host.nix +++ b/examples/home-manager+nur+neovim/hosts/Rick.nix @@ -1,4 +1,5 @@ -{ +{ ... }: { + # Root file system and bootloader is required for CI to build system configuration boot.loader.grub.devices = [ "nodev" ]; fileSystems."/" = { device = "test"; fsType = "ext4"; }; } diff --git a/examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix b/examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix new file mode 100644 index 00000000..7f6a0e3f --- /dev/null +++ b/examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + + environment.systemPackages = with pkgs; [ + neovim-developer + ]; + +} diff --git a/examples/fully-featured/overlays/default.nix b/examples/home-manager+nur+neovim/overlays/default.nix similarity index 100% rename from examples/fully-featured/overlays/default.nix rename to examples/home-manager+nur+neovim/overlays/default.nix diff --git a/examples/minimal-multichannel/flake.nix b/examples/minimal-multichannel/flake.nix new file mode 100644 index 00000000..0866a717 --- /dev/null +++ b/examples/minimal-multichannel/flake.nix @@ -0,0 +1,49 @@ +{ + description = "A highly awesome system configuration."; + + inputs = { + nixpkgs.url = github:nixos/nixpkgs/release-20.09; + unstable.url = github:nixos/nixpkgs/nixos-unstable; + utils.url = path:../../; + }; + + + outputs = inputs@{ self, nixpkgs, unstable, utils, home-manager }: + utils.lib.systemFlake { + inherit self inputs; + + # Channel definitions. + channels.unstable.input = unstable; + channels.nixpkgs.input = nixpkgs; + channelsConfig.allowUnfree = true; + + + # Modules shared between all hosts + hostDefaults.modules = [ + ./modules/sharedConfigurationBetweenHosts.nix + utils.nixosModules.saneFlakeDefaults + ]; + + + ############# + ### Hosts ### + ############# + + # Machine using default channel (nixpkgs) + hosts.Hostname1.modules = [ + ./hosts/Hostname1.nix + ]; + + + # Machine using `unstable` channel + hosts.Hostname2 = { + channelName = "unstable"; + + modules = [ + ./hosts/Hostname2.nix + ]; + }; + + }; +} + diff --git a/examples/minimal-multichannel/hosts/Hostname1.nix b/examples/minimal-multichannel/hosts/Hostname1.nix new file mode 100644 index 00000000..dcaa4a0a --- /dev/null +++ b/examples/minimal-multichannel/hosts/Hostname1.nix @@ -0,0 +1,5 @@ +{ ... }: { + # Root file system and bootloader is required for CI to build system configuration + boot.loader.grub.devices = [ "nodev" ]; + fileSystems."/" = { device = "test"; fsType = "ext4"; }; +} diff --git a/examples/minimal-multichannel/hosts/Hostname2.nix b/examples/minimal-multichannel/hosts/Hostname2.nix new file mode 120000 index 00000000..da680bb5 --- /dev/null +++ b/examples/minimal-multichannel/hosts/Hostname2.nix @@ -0,0 +1 @@ +Hostname1.nix \ No newline at end of file diff --git a/examples/minimal-multichannel/modules/sharedConfigurationBetweenHosts.nix b/examples/minimal-multichannel/modules/sharedConfigurationBetweenHosts.nix new file mode 100644 index 00000000..fb4b367e --- /dev/null +++ b/examples/minimal-multichannel/modules/sharedConfigurationBetweenHosts.nix @@ -0,0 +1,2 @@ +{ ... }: +{ } diff --git a/examples/somewhat-realistic/flake.nix b/examples/somewhat-realistic/flake.nix deleted file mode 100644 index 8504e144..00000000 --- a/examples/somewhat-realistic/flake.nix +++ /dev/null @@ -1,127 +0,0 @@ -{ - description = "A highly awesome system configuration."; - - inputs = { - nixpkgs.url = github:nixos/nixpkgs/release-20.09; - unstable.url = github:nixos/nixpkgs/nixos-unstable; - utils.url = path:../../; - - nix-darwin.url = github:LnL7/nix-darwin; - home-manager = { - url = github:nix-community/home-manager/release-20.09; - inputs.nixpkgs.follows = "nixpkgs"; - }; - agenix.url = github:ryantm/agenix; - }; - - - outputs = inputs@{ self, nixpkgs, unstable, utils, nix-darwin, home-manager, agenix }: - utils.lib.systemFlake { - - # `self` and `inputs` arguments are REQUIRED!!!!!!!!!!!!!! - inherit self inputs; - - - - - # Shared overlays between channels, gets applied to all `channels..input` - sharedOverlays = [ - # Overlay imported from `./overlays`. (Defined above) - self.overlay - ]; - - # Channel definitions. `channels..{input,overlaysBuilder,config,patches}` - channels.nixpkgs.input = nixpkgs; - channels.unstable.input = unstable; - - # Default configuration values for `channels..config = {...}` - channelsConfig.allowUnfree = true; - - # Channel specific overlays - channels.nixpkgs.overlaysBuilder = channels: [ - (final: prev: { - # Overwrites specified packages to be used from unstable channel. - inherit (channels.unstable) alacritty ranger; - }) - (final: prev: { - lib = prev.lib.extend (lfinal: lprev: { - utils = utils.lib; - }); - # As long as the attribute exists, overlaysFromChannelsExporter won't export it - __dontExport = true; - }) - agenix.overlay - ]; - - - - - - - # Shared modules/configurations between `hosts` - hostDefaults = { - modules = [ - # Sets sane `nix.*` defaults. Please refer to implementation/readme for more details. - utils.nixosModules.saneFlakeDefaults - (import ./modules) - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - } - ]; - }; - - - # Profiles, gets parsed into `nixosConfigurations` - hosts.Alice.modules = [ - home-manager.nixosModules.home-manager - ./hosts/Alice.nix - ]; - - - hosts.Bob = { - # This host uses `channels.unstable.{input,overlaysBuilder,config,patches}` attributes instead of `channels.nixpkgs.<...>` - channelName = "unstable"; - - # Host specific configuration. - modules = [ - home-manager.nixosModules.home-manager - ./hosts/Bob.nix - ]; - }; - - hosts."Carl" = { - # This host will be exported under the flake's `darwinConfigurations` output - output = "darwinConfigurations"; - - # Build host with darwinSystem. `removeAttrs` workaround due to https://github.com/LnL7/nix-darwin/issues/319 - builder = args: nix-darwin.lib.darwinSystem (builtins.removeAttrs args [ "system" ]); - - system = "x86_64-darwin"; - - # This host uses `channels.unstable.{input,overlaysBuilder,config,patches}` attributes instead of `channels.nixpkgs.<...>` - channelName = "unstable"; - - # Host specific configuration. - modules = [ - home-manager.darwinModules.home-manager - ./hosts/Carl.nix - ]; - }; - - - - - # export overlays automatically for all packages defined in overlaysBuilder of each channel - overlays = utils.lib.exporter.overlaysFromChannelsExporter { - inherit (self) pkgs inputs; - }; - - # construct packagesBuilder to export all packages defined in overlays - packagesBuilder = utils.lib.builder.packagesFromOverlaysBuilderConstructor self.overlays; - - overlay = import ./overlays; - - }; -} - diff --git a/examples/somewhat-realistic/hosts/Bob.nix b/examples/somewhat-realistic/hosts/Bob.nix deleted file mode 120000 index b7f0569b..00000000 --- a/examples/somewhat-realistic/hosts/Bob.nix +++ /dev/null @@ -1 +0,0 @@ -One.nix \ No newline at end of file diff --git a/examples/somewhat-realistic/hosts/Carl.nix b/examples/somewhat-realistic/hosts/Carl.nix deleted file mode 100644 index c915eb0a..00000000 --- a/examples/somewhat-realistic/hosts/Carl.nix +++ /dev/null @@ -1 +0,0 @@ -{ ... }: { } diff --git a/examples/somewhat-realistic/modules/default.nix b/examples/somewhat-realistic/modules/default.nix deleted file mode 100644 index c915eb0a..00000000 --- a/examples/somewhat-realistic/modules/default.nix +++ /dev/null @@ -1 +0,0 @@ -{ ... }: { } diff --git a/examples/somewhat-realistic/overlays/default.nix b/examples/somewhat-realistic/overlays/default.nix deleted file mode 100644 index ce168707..00000000 --- a/examples/somewhat-realistic/overlays/default.nix +++ /dev/null @@ -1 +0,0 @@ -final: prev: { } diff --git a/flake.nix b/flake.nix index faa664ff..ad3b620d 100644 --- a/flake.nix +++ b/flake.nix @@ -7,30 +7,27 @@ let inherit (builtins) isList isAttrs mapAttrs; fupArgs = { flake-utils-plus = self; }; - systemFlake = import ./systemFlake.nix fupArgs; - packagesFromOverlaysBuilderConstructor = import ./packagesFromOverlaysBuilderConstructor.nix fupArgs; - overlaysFromChannelsExporter = import ./overlaysFromChannelsExporter.nix fupArgs; - modulesFromList = import ./moduleFromListExporter.nix fupArgs; + + systemFlake = import ./src/systemFlake.nix fupArgs; + modulesFromList = import ./src/modulesFromList.nix fupArgs; + fromOverlays = import ./src/fromOverlays.nix fupArgs; + internalOverlays = import ./src/internalOverlays.nix fupArgs; in rec { - nixosModules.saneFlakeDefaults = import ./modules/saneFlakeDefaults.nix; + nixosModules.saneFlakeDefaults = import ./src/saneFlakeDefaults.nix; - devShell.x86_64-linux = import ./shell.nix { system = "x86_64-linux"; }; + devShell.x86_64-linux = import ./devShell.nix { system = "x86_64-linux"; }; lib = flake-utils.lib // { # modulesFromList is deprecated, will be removed in future releases inherit systemFlake modulesFromList; - builder = { - inherit packagesFromOverlaysBuilderConstructor; - }; - - exporter = { - inherit overlaysFromChannelsExporter modulesFromList; + exporters = { + inherit modulesFromList fromOverlays internalOverlays; }; - repl = ./repl.nix; + repl = ./src/repl.nix; # merge nested attribute sets and lists mergeAny = lhs: rhs: diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 10427a03..00000000 --- a/shell.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ system ? builtins.currentSystem }: -let - # nixpkgs / devshell is only used for development. Don't add it to the flake.lock. - nixpkgsGitRev = "5268ee2ebacbc73875be42d71e60c2b5c1b5a1c7"; - devshellGitRev = "709fe4d04a9101c9d224ad83f73416dce71baf21"; - - nixpkgsSrc = fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsGitRev}.tar.gz"; - sha256 = "080fvmg0i6z01h6adddfrjp1bbbjhhqk32ks6ch9gv689645ccfq"; - }; - - devshellSrc = fetchTarball { - url = "https://github.com/numtide/devshell/archive/${devshellGitRev}.tar.gz"; - sha256 = "1px9cqfshfqs1b7ypyxch3s3ymr4xgycy1krrcg7b97rmmszvsqr"; - }; - - pkgs = import nixpkgsSrc { inherit system; }; - devshell = import devshellSrc { inherit system pkgs; }; - -in -devshell.fromTOML ./devshell.toml diff --git a/packagesFromOverlaysBuilderConstructor.nix b/src/fromOverlays.nix similarity index 100% rename from packagesFromOverlaysBuilderConstructor.nix rename to src/fromOverlays.nix diff --git a/overlaysFromChannelsExporter.nix b/src/internalOverlays.nix similarity index 100% rename from overlaysFromChannelsExporter.nix rename to src/internalOverlays.nix diff --git a/moduleFromListExporter.nix b/src/modulesFromList.nix similarity index 100% rename from moduleFromListExporter.nix rename to src/modulesFromList.nix diff --git a/repl.nix b/src/repl.nix similarity index 100% rename from repl.nix rename to src/repl.nix diff --git a/modules/saneFlakeDefaults.nix b/src/saneFlakeDefaults.nix similarity index 100% rename from modules/saneFlakeDefaults.nix rename to src/saneFlakeDefaults.nix diff --git a/systemFlake.nix b/src/systemFlake.nix similarity index 95% rename from systemFlake.nix rename to src/systemFlake.nix index f1080915..13ff9cbf 100644 --- a/systemFlake.nix +++ b/src/systemFlake.nix @@ -103,6 +103,8 @@ let (foldl' (lhs: rhs: lhs // rhs) { } (map f (attrNames channels))) # Override `modulesPath` because otherwise imports from there will not use patched nixpkgs // { modulesPath = toString (patchedChannel + "/nixos/modules"); }; + + # The only way to find out if a host has `nixpkgs.config` set to # the non-default value is by evalling most of the config. hostConfig = (lib.evalModules { @@ -135,11 +137,12 @@ let if (hostConfig.nixpkgs.config == { }) then selectedNixpkgs else - import patchedChannel { - inherit (host) system; - overlays = selectedNixpkgs.overlays; - config = selectedNixpkgs.config // config.nixpkgs.config; - }; + import patchedChannel + { + inherit (host) system; + overlays = selectedNixpkgs.overlays ++ hostConfig.nixpkgs.overlays; + config = selectedNixpkgs.config // config.nixpkgs.config; + } // { inherit (selectedNixpkgs) name input; }; } else { _module.args.pkgs = selectedNixpkgs; }) diff --git a/tests/channel-patching/flake.nix b/tests/channel-patching/flake.nix new file mode 100644 index 00000000..4560d49c --- /dev/null +++ b/tests/channel-patching/flake.nix @@ -0,0 +1,81 @@ +{ + inputs.utils.url = path:../../; + + outputs = inputs@{ self, nixpkgs, utils }: + let + testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; + inherit (testing-utils) hasKey isEqual; + in + utils.lib.systemFlake { + inherit self inputs; + supportedSystems = [ "x86_64-linux" ]; + + + + + ################# + ### Test Data ### + ################# + + channelsConfig.allowBroken = true; + + channels.nixpkgs = { + input = nixpkgs; + patches = [ ./myNixpkgsPatch.patch ]; + config.allowUnfree = true; + }; + + hosts.PatchedHost.modules = [ + ({ lib, ... }: { + patchedModule.test = lib.patchedFunction "using patched module via patched function"; + nixpkgs.config.packageOverrides = pkgs: { }; + + # To keep Nix from complaining + boot.loader.grub.devices = [ "nodev" ]; + fileSystems."/" = { device = "test"; fsType = "ext4"; }; + }) + ]; + + # Using patched channel in builder + packagesBuilder = channels: { + inherit (channels.nixpkgs) flake-utils-plus-test; + }; + + + + + + ###################### + ### Test execution ### + ###################### + + checksBuilder = channels: + let + hostConfig = self.nixosConfigurations.PatchedHost.config; + in + { + + # Patched package gets passed to `packageBuilder` + patchedPackageGetsPassedToBuilders = isEqual self.packages.x86_64-linux.flake-utils-plus-test.pname "hello"; + + # Modules (and lib) from patched nixpkgs are used + patchedModuleAndFunctionWorks = isEqual hostConfig.patchedModule.test "using patched module via patched function"; + + # `channelsConfig.*` is used + globalChannelConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "allowBroken"; + + # `channels.nixpkgs.config.*` is also used + channelSpecificConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "allowUnfree"; + + # `options.nixpkgs.config.*` is also used + modulesNixpkgsConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "packageOverrides"; + + }; + + + }; +} + + + + diff --git a/examples/fully-featured/myNixpkgsPatch.patch b/tests/channel-patching/myNixpkgsPatch.patch similarity index 100% rename from examples/fully-featured/myNixpkgsPatch.patch rename to tests/channel-patching/myNixpkgsPatch.patch diff --git a/tests/derivation-outputs/flake.nix b/tests/derivation-outputs/flake.nix new file mode 100644 index 00000000..4e5caca0 --- /dev/null +++ b/tests/derivation-outputs/flake.nix @@ -0,0 +1,94 @@ +{ + inputs.utils.url = path:../../; + + outputs = inputs@{ self, nixpkgs, utils }: + let + mkApp = utils.lib.mkApp; + + packagePname = drvKey: self.packages.x86_64-linux.${drvKey}.pname; + + appHasSuffix = drvKey: suffix: nixpkgs.lib.hasSuffix suffix self.apps.x86_64-linux.${drvKey}.program; + + defaultAppHasSuffix = suffix: nixpkgs.lib.hasSuffix suffix self.defaultApp.x86_64-linux.program; + + pnameFromOutput = output: self.${output}.x86_64-linux.pname; + in + utils.lib.systemFlake { + inherit self inputs; + supportedSystems = [ "x86_64-linux" ]; + channels.nixpkgs.input = nixpkgs; + + + + ################# + ### Test Data ### + ################# + + defaultPackageBuilder = channels: channels.nixpkgs.coreutils; + + packagesBuilder = channels: { + inherit (channels.nixpkgs) coreutils; + }; + + # Should Get merged with `packagesBuilder` + packages.x86_64-linux.coreutils2 = self.pkgs.x86_64-linux.nixpkgs.coreutils; + + + + appsBuilder = channels: { + coreutils = mkApp { + drv = channels.nixpkgs.coreutils; + exePath = "/bin/nice"; + }; + }; + + + defaultAppBuilder = channels: mkApp { + drv = channels.nixpkgs.coreutils; + exePath = "/bin/nice"; + }; + + devShellBuilder = channels: channels.nixpkgs.mkShell { + pname = "super-shell"; + }; + + + + + ###################### + ### Test execution ### + ###################### + + checksBuilder = channels: + let + isTrue = cond: + if cond + then channels.nixpkgs.runCommandNoCC "success" { } "echo success > $out" + else channels.nixpkgs.runCommandNoCC "failure" { } "exit 1"; + in + { + + # Packages + defaultPackageValid = isTrue (pnameFromOutput "defaultPackage" == "coreutils"); + + packagesValid = isTrue (packagePname "coreutils" == "coreutils"); + + packagesMerged = isTrue (packagePname "coreutils2" == "coreutils"); + + + # Apps + appsValid = isTrue (appHasSuffix "coreutils" "nice"); + + defaultAppValid = isTrue (defaultAppHasSuffix "nice"); + + # Devshell + devshellValid = isTrue (pnameFromOutput "devShell" == "super-shell"); + + }; + + }; +} + + + + diff --git a/tests/hosts-config/flake.nix b/tests/hosts-config/flake.nix new file mode 100644 index 00000000..f985c104 --- /dev/null +++ b/tests/hosts-config/flake.nix @@ -0,0 +1,111 @@ +{ + inputs.utils.url = path:../../; + + outputs = inputs@{ self, nixpkgs, utils }: + let + testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; + inherit (testing-utils) hasKey base-nixos isEqual; + in + utils.lib.systemFlake { + inherit self inputs; + supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" ]; + + channels.nixpkgs.input = nixpkgs; + channels.unstable.input = nixpkgs; + channels.someChannel.input = nixpkgs; + + + + ################# + ### Test Data ### + ################# + + # Hosts + hostDefaults = { + output = "someConfigurations"; + system = "aarch64-linux"; + channelName = "someChannel"; + extraArgs.sharedExtraArg = "sharedExtraArg"; + specialArgs.sharedSpecialArg = "sharedSpecialArg"; + + modules = [ + base-nixos + # Assigning to lib.* so we could assert these options in checks + ({ sharedExtraArg, sharedSpecialArg, ... }: { + lib = { inherit sharedExtraArg sharedSpecialArg; }; + }) + ]; + }; + + hosts.Plain = { }; + + hosts.WithFakeBuilder = { + builder = args: { fakeBuilder = "fakeBuilder"; }; + }; + + hosts.Customized = { + output = "darwinConfigurations"; + system = "x86_64-darwin"; + channelName = "unstable"; + extraArgs.hostExtraArg = "hostExtraArg"; + specialArgs.hostSpecialArg = "hostSpecialArg"; + + # Assigning to lib.* so we could assert these options in checks + modules = [ + ({ hostExtraArg, hostSpecialArg, ... }: { + lib = { inherit hostSpecialArg hostExtraArg; }; + }) + ]; + }; + + + + ###################### + ### Test execution ### + ###################### + + checksBuilder = channels: + let + plainHost = self.someConfigurations.Plain; + plainHostPkgs = plainHost.config.nixpkgs.pkgs; + + customizedHost = self.darwinConfigurations.Customized; + customizedHostPkgs = customizedHost.config.nixpkgs.pkgs; + in + { + + # Plain system with inherited options from hostDefaults + system_valid_1 = isEqual plainHostPkgs.system "aarch64-linux"; + + channelName_valid_1 = isEqual plainHostPkgs.name "someChannel"; + + channelInput_valid_1 = hasKey plainHostPkgs "input"; + + extraArgs_valid_1 = hasKey plainHost.config.lib "sharedExtraArg"; + + specialArgs_valid_1 = hasKey plainHost.config.lib "sharedSpecialArg"; + + + # System with overwritten hostDefaults + system_valid_2 = isEqual customizedHostPkgs.system "x86_64-darwin"; + + channelName_valid_2 = isEqual customizedHostPkgs.name "unstable"; + + channelInput_valid_2 = hasKey customizedHostPkgs "input"; + + extraArgs_valid_2 = hasKey customizedHost.config.lib "hostExtraArg"; + + specialArgs_valid_2 = hasKey customizedHost.config.lib "hostSpecialArg"; + + + # Eval fakeBuilder + builder_applied = isEqual self.someConfigurations.WithFakeBuilder.fakeBuilder "fakeBuilder"; + + }; + + }; +} + + + + diff --git a/tests/overlays-flow/flake.nix b/tests/overlays-flow/flake.nix new file mode 100644 index 00000000..0c6a7388 --- /dev/null +++ b/tests/overlays-flow/flake.nix @@ -0,0 +1,96 @@ +{ + inputs.utils.url = path:../../; + + outputs = inputs@{ self, nixpkgs, utils }: + let + testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; + inherit (testing-utils) hasKey; + in + utils.lib.systemFlake { + inherit self inputs; + supportedSystems = [ "x86_64-linux" ]; + channels.nixpkgs.input = nixpkgs; + + + + ################# + ### Test Data ### + ################# + + # Applied to all Channels + sharedOverlays = [ + (final: prev: { + fromSharedOverlays = prev.hello; + }) + ]; + + # Applied only to `nixpkgs` channel + channels.nixpkgs.overlaysBuilder = channels: [ + (final: prev: { + fromChannelSpecific = prev.hello; + }) + ]; + + + # Hosts + hostDefaults.modules = [ + { + nixpkgs.overlays = [ + (final: prev: { fromHostConfig = prev.hello; }) + ]; + + # To keep Nix from complaining + boot.loader.grub.devices = [ "nodev" ]; + fileSystems."/" = { device = "test"; fsType = "ext4"; }; + } + ]; + + hosts.ExistingPkgsFlow = { }; + + hosts.ReimportFlow.modules = [ + { + # Custom configuration from modules causes reimport of nixpkgs + nixpkgs.config.allowUnfree = true; + } + ]; + + + + ###################### + ### Test execution ### + ###################### + + checksBuilder = channels: + let + existingPkgsFlow = self.nixosConfigurations.ExistingPkgsFlow.pkgs; + reimportFlow = self.nixosConfigurations.ReimportFlow.pkgs; + in + { + + # ExistingPkgsFlow + sharedOverlays_Applied_1 = hasKey existingPkgsFlow "fromSharedOverlays"; + + channelSpecific_Applied_1 = hasKey existingPkgsFlow "fromChannelSpecific"; + + hostConfig_Applied_1 = hasKey existingPkgsFlow "fromHostConfig"; + + contains_srcs_1 = hasKey existingPkgsFlow "srcs"; + + + # ReimportFlow + sharedOverlays_Applied_2 = hasKey reimportFlow "fromSharedOverlays"; + + channelSpecific_Applied_2 = hasKey reimportFlow "fromChannelSpecific"; + + hostConfig_Applied_2 = hasKey reimportFlow "fromHostConfig"; + + contains_srcs_2 = hasKey reimportFlow "srcs"; + + }; + + }; +} + + + + diff --git a/tests/testing-utils.nix b/tests/testing-utils.nix new file mode 100644 index 00000000..b99e93ac --- /dev/null +++ b/tests/testing-utils.nix @@ -0,0 +1,19 @@ +{ nixpkgs }: + +{ + # Options that keep Nix from complaining + base-nixos = { + boot.loader.grub.devices = [ "nodev" ]; + fileSystems."/" = { device = "test"; fsType = "ext4"; }; + }; + + isEqual = a: b: + if a == b + then nixpkgs.runCommandNoCC "success-${a}-IS-EQUAL-${b}" { } "echo success > $out" + else nixpkgs.runCommandNoCC "falure-${a}-IS-NOT-EQUAL-${b}" { } "exit 1"; + + hasKey = attrset: key: + if attrset ? ${key} + then nixpkgs.runCommandNoCC "success-${key}-exists-in-attrset" { } "echo success > $out" + else nixpkgs.runCommandNoCC "falure-key-${key}-does-not-exist-in-attrset" { } "exit 1"; +} From e0278428df2de106d5a773875dc52792c8f7dc5e Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 17 May 2021 11:27:39 -0700 Subject: [PATCH 19/90] fromOverlays: opt-in for exporting sub-systems sub-systems are not great for flakes ecosystems and this prevents exporting overriden sub-systems from nixpkgs --- src/fromOverlays.nix | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fromOverlays.nix b/src/fromOverlays.nix index ac78ac00..3fd85f06 100644 --- a/src/fromOverlays.nix +++ b/src/fromOverlays.nix @@ -60,7 +60,18 @@ let # create list of single-attribute sets that contain each package exportPackagesList = map (name: - { ${name} = flattenedPackages.${name}; } + let + item = flattenedPackages.${name}; + exportItem = { ${name} = item; }; + in + if item ? type && item.type == "derivation" then + # if its a package export it + exportItem + else if item ? __dontExport && !item.__dontExport then + # if its a package sub-system, __dontExport has to be set to false to export + exportItem + else + { } ) flattenedOverlaysNames; From 3c6efcb00e81e504952b143f0bd81e84c2eb411d Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Mon, 17 May 2021 23:16:47 +0300 Subject: [PATCH 20/90] Add replace xyzBuilder with unified 'outputsBuilder' --- src/systemFlake.nix | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/systemFlake.nix b/src/systemFlake.nix index 13ff9cbf..2e09af96 100644 --- a/src/systemFlake.nix +++ b/src/systemFlake.nix @@ -19,6 +19,8 @@ extraArgs = sharedExtraArgs; } +, outputsBuilder ? null + , packagesBuilder ? null , defaultPackageBuilder ? null , appsBuilder ? null @@ -69,6 +71,7 @@ let "sharedOverlays" "supportedSystems" + "outputsBuilder" "packagesBuilder" "defaultPackageBuilder" "appsBuilder" @@ -189,24 +192,37 @@ mergeAny otherArguments ( pkgs = mapAttrs importChannel channels; - mkOutput = output: builder: + + deprecatedBuilders = channels: { } + // optionalAttrs (packagesBuilder != null) { packages = packagesBuilder channels; } + // optionalAttrs (defaultPackageBuilder != null) { defaultPackage = defaultPackageBuilder channels; } + // optionalAttrs (appsBuilder != null) { apps = appsBuilder channels; } + // optionalAttrs (defaultAppBuilder != null) { defaultApp = defaultAppBuilder channels; } + // optionalAttrs (devShellBuilder != null) { devShell = devShellBuilder channels; } + // optionalAttrs (checksBuilder != null) { checks = checksBuilder channels; }; + + systemOutputs = (if outputsBuilder == null then deprecatedBuilders else outputsBuilder) pkgs; + + mkOutput = output: mergeAny # prevent override of nested outputs in otherArguments (optionalAttrs (otherArguments ? ${output}.${system}) { ${output} = otherArguments.${output}.${system}; }) - (optionalAttrs (args ? ${builder}) - { ${output} = args.${builder} pkgs; }); + (optionalAttrs (systemOutputs ? ${output}) + { ${output} = systemOutputs.${output}; }); + in { inherit pkgs; } - // mkOutput "packages" "packagesBuilder" - // mkOutput "defaultPackage" "defaultPackageBuilder" - // mkOutput "apps" "appsBuilder" - // mkOutput "defaultApp" "defaultAppBuilder" - // mkOutput "devShell" "devShellBuilder" - // mkOutput "checks" "checksBuilder" + // mkOutput "packages" + // mkOutput "defaultPackage" + // mkOutput "apps" + // mkOutput "defaultApp" + // mkOutput "devShell" + // mkOutput "checks" ) # produces attrset in the shape of # { nixosConfigurations = {}; darwinConfigurations = {}; ... } # according to profile.output or the default `nixosConfigurations` // foldHosts (attrValues (mapAttrs configurationBuilder hosts)) ) + From 6bdff319912f97397bf15162db686534fb9e94d3 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Mon, 17 May 2021 23:24:27 +0300 Subject: [PATCH 21/90] Add derivation tests --- .github/workflows/ci.yaml | 1 + devShell.nix | 1 + tests/derivation-outputs-old/flake.nix | 91 ++++++++++++++++++++++++ tests/derivation-outputs/flake.nix | 98 +++++++++++++------------- 4 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 tests/derivation-outputs-old/flake.nix diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ee13d49a..cc827414 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,6 +21,7 @@ jobs: # Execute /tests/* - run: nix develop --command check-derivation-outputs + - run: nix develop --command check-derivation-outputs-old - run: nix develop --command check-channel-patching - run: nix develop --command check-overlays-flow - run: nix develop --command check-hosts-config diff --git a/devShell.nix b/devShell.nix index 428ef72b..f9881960 100644 --- a/devShell.nix +++ b/devShell.nix @@ -72,6 +72,7 @@ devshell.mkShell { (test "channel-patching") (test "derivation-outputs") + (test "derivation-outputs-old") (test "hosts-config") (test "overlays-flow") (dry-nixos-build "minimal-multichannel" "Hostname1") diff --git a/tests/derivation-outputs-old/flake.nix b/tests/derivation-outputs-old/flake.nix new file mode 100644 index 00000000..57f16d32 --- /dev/null +++ b/tests/derivation-outputs-old/flake.nix @@ -0,0 +1,91 @@ +{ + inputs.utils.url = path:../../; + + outputs = inputs@{ self, nixpkgs, utils }: + let + mkApp = utils.lib.mkApp; + + packagePname = drvKey: self.packages.x86_64-linux.${drvKey}.pname; + + appHasSuffix = drvKey: suffix: nixpkgs.lib.hasSuffix suffix self.apps.x86_64-linux.${drvKey}.program; + + defaultAppHasSuffix = suffix: nixpkgs.lib.hasSuffix suffix self.defaultApp.x86_64-linux.program; + + pnameFromOutput = output: self.${output}.x86_64-linux.pname; + in + utils.lib.systemFlake { + inherit self inputs; + supportedSystems = [ "x86_64-linux" ]; + channels.nixpkgs.input = nixpkgs; + + + + ################# + ### Test Data ### + ################# + + defaultPackageBuilder = channels: channels.nixpkgs.coreutils; + + packagesBuilder = channels: { + inherit (channels.nixpkgs) coreutils; + }; + + # Should Get merged with `packagesBuilder` + packages.x86_64-linux.coreutils2 = self.pkgs.x86_64-linux.nixpkgs.coreutils; + + + + appsBuilder = channels: { + coreutils = mkApp { + drv = channels.nixpkgs.coreutils; + exePath = "/bin/nice"; + }; + }; + + + defaultAppBuilder = channels: mkApp { + drv = channels.nixpkgs.coreutils; + exePath = "/bin/nice"; + }; + + devShellBuilder = channels: channels.nixpkgs.mkShell { + pname = "super-shell"; + }; + + + + + ###################### + ### Test execution ### + ###################### + + checksBuilder = channels: + let + isTrue = cond: + if cond + then channels.nixpkgs.runCommandNoCC "success" { } "echo success > $out" + else channels.nixpkgs.runCommandNoCC "failure" { } "exit 1"; + in + { + + # Packages + defaultPackageValid = isTrue (pnameFromOutput "defaultPackage" == "coreutils"); + + packagesValid = isTrue (packagePname "coreutils" == "coreutils"); + + packagesMerged = isTrue (packagePname "coreutils2" == "coreutils"); + + + # Apps + appsValid = isTrue (appHasSuffix "coreutils" "nice"); + + defaultAppValid = isTrue (defaultAppHasSuffix "nice"); + + # Devshell + devshellValid = isTrue (pnameFromOutput "devShell" == "super-shell"); + + }; + + }; +} + diff --git a/tests/derivation-outputs/flake.nix b/tests/derivation-outputs/flake.nix index 4e5caca0..00cd407a 100644 --- a/tests/derivation-outputs/flake.nix +++ b/tests/derivation-outputs/flake.nix @@ -3,92 +3,90 @@ outputs = inputs@{ self, nixpkgs, utils }: let - mkApp = utils.lib.mkApp; - - packagePname = drvKey: self.packages.x86_64-linux.${drvKey}.pname; - - appHasSuffix = drvKey: suffix: nixpkgs.lib.hasSuffix suffix self.apps.x86_64-linux.${drvKey}.program; + testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; + inherit (testing-utils) hasKey isEqual; - defaultAppHasSuffix = suffix: nixpkgs.lib.hasSuffix suffix self.defaultApp.x86_64-linux.program; - - pnameFromOutput = output: self.${output}.x86_64-linux.pname; + mkApp = utils.lib.mkApp; in utils.lib.systemFlake { inherit self inputs; supportedSystems = [ "x86_64-linux" ]; channels.nixpkgs.input = nixpkgs; - - ################# ### Test Data ### ################# - defaultPackageBuilder = channels: channels.nixpkgs.coreutils; - - packagesBuilder = channels: { - inherit (channels.nixpkgs) coreutils; - }; # Should Get merged with `packagesBuilder` packages.x86_64-linux.coreutils2 = self.pkgs.x86_64-linux.nixpkgs.coreutils; + outputsBuilder = channels: { + + packages = { + inherit (channels.nixpkgs) coreutils; + }; + + defaultPackage = channels.nixpkgs.coreutils; + + apps = { + coreutils = mkApp { + drv = channels.nixpkgs.coreutils; + exePath = "/bin/nice"; + }; + }; - appsBuilder = channels: { - coreutils = mkApp { + defaultApp = mkApp { drv = channels.nixpkgs.coreutils; exePath = "/bin/nice"; }; - }; + devShell = channels.nixpkgs.mkShell { + pname = "super-shell"; + }; - defaultAppBuilder = channels: mkApp { - drv = channels.nixpkgs.coreutils; - exePath = "/bin/nice"; - }; - - devShellBuilder = channels: channels.nixpkgs.mkShell { - pname = "super-shell"; - }; + ###################### + ### Test execution ### + ###################### + checks = + let + inherit (nixpkgs.lib) hasSuffix; + getOutput = output: self.${output}.${channels.nixpkgs.system}; - ###################### - ### Test execution ### - ###################### + packages = getOutput "packages"; + defaultPackage = getOutput "defaultPackage"; + devShell = getOutput "devShell"; - checksBuilder = channels: - let - isTrue = cond: - if cond - then channels.nixpkgs.runCommandNoCC "success" { } "echo success > $out" - else channels.nixpkgs.runCommandNoCC "failure" { } "exit 1"; - in - { + isTrue = cond: + if cond + then channels.nixpkgs.runCommandNoCC "success" { } "echo success > $out" + else channels.nixpkgs.runCommandNoCC "failure" { } "exit 1"; + in + { - # Packages - defaultPackageValid = isTrue (pnameFromOutput "defaultPackage" == "coreutils"); + # Packages + defaultPackage_valid = isEqual defaultPackage.pname "coreutils"; - packagesValid = isTrue (packagePname "coreutils" == "coreutils"); + packages_valid = isEqual packages.coreutils.pname "coreutils"; + packages_merged = isEqual packages.coreutils2.pname "coreutils"; - packagesMerged = isTrue (packagePname "coreutils2" == "coreutils"); + # Apps + apps_valid = isTrue (hasSuffix "nice" (getOutput "apps").coreutils.program); - # Apps - appsValid = isTrue (appHasSuffix "coreutils" "nice"); + defaultApp_valid = isTrue (hasSuffix "nice" (getOutput "defaultApp").program); - defaultAppValid = isTrue (defaultAppHasSuffix "nice"); + # Devshell + devshell_valid = isEqual devShell.pname "super-shell"; - # Devshell - devshellValid = isTrue (pnameFromOutput "devShell" == "super-shell"); + }; - }; + }; }; } - - - From 78f7c9bb298e57b71e797dd62e9cb4f480985ba7 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Wed, 19 May 2021 12:08:44 +0300 Subject: [PATCH 22/90] Tests cleanup --- examples/exporters/flake.nix | 6 ++-- tests/channel-patching/flake.nix | 48 ++++++++++++++++-------------- tests/derivation-outputs/flake.nix | 1 + tests/hosts-config/flake.nix | 48 ++++++++++++++++-------------- tests/overlays-flow/flake.nix | 36 +++++++++++----------- 5 files changed, 74 insertions(+), 65 deletions(-) diff --git a/examples/exporters/flake.nix b/examples/exporters/flake.nix index 0699b882..6ae01c81 100644 --- a/examples/exporters/flake.nix +++ b/examples/exporters/flake.nix @@ -33,8 +33,10 @@ inherit (self) pkgs inputs; }; - # construct packagesBuilder to export all packages defined in overlays - #packagesBuilder = fromOverlays self.overlays; + outputsBuilder = channels: { + # construct packagesBuilder to export all packages defined in overlays + packages = fromOverlays self.overlays channels; + }; overlay = import ./overlays; diff --git a/tests/channel-patching/flake.nix b/tests/channel-patching/flake.nix index 4560d49c..43f53624 100644 --- a/tests/channel-patching/flake.nix +++ b/tests/channel-patching/flake.nix @@ -36,41 +36,43 @@ }) ]; - # Using patched channel in builder - packagesBuilder = channels: { - inherit (channels.nixpkgs) flake-utils-plus-test; - }; + outputsBuilder = channels: { + packages = { + # Using patched channel + inherit (channels.nixpkgs) flake-utils-plus-test; + }; - ###################### - ### Test execution ### - ###################### + ###################### + ### Test execution ### + ###################### - checksBuilder = channels: - let - hostConfig = self.nixosConfigurations.PatchedHost.config; - in - { + checks = + let + hostConfig = self.nixosConfigurations.PatchedHost.config; + in + { - # Patched package gets passed to `packageBuilder` - patchedPackageGetsPassedToBuilders = isEqual self.packages.x86_64-linux.flake-utils-plus-test.pname "hello"; + # Patched package gets passed to `packageBuilder` + patchedPackageGetsPassedToBuilders = isEqual self.packages.x86_64-linux.flake-utils-plus-test.pname "hello"; - # Modules (and lib) from patched nixpkgs are used - patchedModuleAndFunctionWorks = isEqual hostConfig.patchedModule.test "using patched module via patched function"; + # Modules (and lib) from patched nixpkgs are used + patchedModuleAndFunctionWorks = isEqual hostConfig.patchedModule.test "using patched module via patched function"; - # `channelsConfig.*` is used - globalChannelConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "allowBroken"; + # `channelsConfig.*` is used + globalChannelConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "allowBroken"; - # `channels.nixpkgs.config.*` is also used - channelSpecificConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "allowUnfree"; + # `channels.nixpkgs.config.*` is also used + channelSpecificConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "allowUnfree"; - # `options.nixpkgs.config.*` is also used - modulesNixpkgsConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "packageOverrides"; + # `options.nixpkgs.config.*` is also used + modulesNixpkgsConfigWorks = hasKey hostConfig.nixpkgs.pkgs.config "packageOverrides"; - }; + }; + }; }; diff --git a/tests/derivation-outputs/flake.nix b/tests/derivation-outputs/flake.nix index 00cd407a..00e09d0c 100644 --- a/tests/derivation-outputs/flake.nix +++ b/tests/derivation-outputs/flake.nix @@ -13,6 +13,7 @@ supportedSystems = [ "x86_64-linux" ]; channels.nixpkgs.input = nixpkgs; + ################# ### Test Data ### ################# diff --git a/tests/hosts-config/flake.nix b/tests/hosts-config/flake.nix index f985c104..bcded384 100644 --- a/tests/hosts-config/flake.nix +++ b/tests/hosts-config/flake.nix @@ -64,44 +64,46 @@ ### Test execution ### ###################### - checksBuilder = channels: - let - plainHost = self.someConfigurations.Plain; - plainHostPkgs = plainHost.config.nixpkgs.pkgs; + outputsBuilder = channels: { + checks = + let + plainHost = self.someConfigurations.Plain; + plainHostPkgs = plainHost.config.nixpkgs.pkgs; - customizedHost = self.darwinConfigurations.Customized; - customizedHostPkgs = customizedHost.config.nixpkgs.pkgs; - in - { + customizedHost = self.darwinConfigurations.Customized; + customizedHostPkgs = customizedHost.config.nixpkgs.pkgs; + in + { - # Plain system with inherited options from hostDefaults - system_valid_1 = isEqual plainHostPkgs.system "aarch64-linux"; + # Plain system with inherited options from hostDefaults + system_valid_1 = isEqual plainHostPkgs.system "aarch64-linux"; - channelName_valid_1 = isEqual plainHostPkgs.name "someChannel"; + channelName_valid_1 = isEqual plainHostPkgs.name "someChannel"; - channelInput_valid_1 = hasKey plainHostPkgs "input"; + channelInput_valid_1 = hasKey plainHostPkgs "input"; - extraArgs_valid_1 = hasKey plainHost.config.lib "sharedExtraArg"; + extraArgs_valid_1 = hasKey plainHost.config.lib "sharedExtraArg"; - specialArgs_valid_1 = hasKey plainHost.config.lib "sharedSpecialArg"; + specialArgs_valid_1 = hasKey plainHost.config.lib "sharedSpecialArg"; - # System with overwritten hostDefaults - system_valid_2 = isEqual customizedHostPkgs.system "x86_64-darwin"; + # System with overwritten hostDefaults + system_valid_2 = isEqual customizedHostPkgs.system "x86_64-darwin"; - channelName_valid_2 = isEqual customizedHostPkgs.name "unstable"; + channelName_valid_2 = isEqual customizedHostPkgs.name "unstable"; - channelInput_valid_2 = hasKey customizedHostPkgs "input"; + channelInput_valid_2 = hasKey customizedHostPkgs "input"; - extraArgs_valid_2 = hasKey customizedHost.config.lib "hostExtraArg"; + extraArgs_valid_2 = hasKey customizedHost.config.lib "hostExtraArg"; - specialArgs_valid_2 = hasKey customizedHost.config.lib "hostSpecialArg"; + specialArgs_valid_2 = hasKey customizedHost.config.lib "hostSpecialArg"; - # Eval fakeBuilder - builder_applied = isEqual self.someConfigurations.WithFakeBuilder.fakeBuilder "fakeBuilder"; + # Eval fakeBuilder + builder_applied = isEqual self.someConfigurations.WithFakeBuilder.fakeBuilder "fakeBuilder"; - }; + }; + }; }; } diff --git a/tests/overlays-flow/flake.nix b/tests/overlays-flow/flake.nix index 0c6a7388..24face65 100644 --- a/tests/overlays-flow/flake.nix +++ b/tests/overlays-flow/flake.nix @@ -60,33 +60,35 @@ ### Test execution ### ###################### - checksBuilder = channels: - let - existingPkgsFlow = self.nixosConfigurations.ExistingPkgsFlow.pkgs; - reimportFlow = self.nixosConfigurations.ReimportFlow.pkgs; - in - { + outputsBuilder = channels: { + checks = + let + existingPkgsFlow = self.nixosConfigurations.ExistingPkgsFlow.pkgs; + reimportFlow = self.nixosConfigurations.ReimportFlow.pkgs; + in + { - # ExistingPkgsFlow - sharedOverlays_Applied_1 = hasKey existingPkgsFlow "fromSharedOverlays"; + # ExistingPkgsFlow + sharedOverlays_Applied_1 = hasKey existingPkgsFlow "fromSharedOverlays"; - channelSpecific_Applied_1 = hasKey existingPkgsFlow "fromChannelSpecific"; + channelSpecific_Applied_1 = hasKey existingPkgsFlow "fromChannelSpecific"; - hostConfig_Applied_1 = hasKey existingPkgsFlow "fromHostConfig"; + hostConfig_Applied_1 = hasKey existingPkgsFlow "fromHostConfig"; - contains_srcs_1 = hasKey existingPkgsFlow "srcs"; + contains_srcs_1 = hasKey existingPkgsFlow "srcs"; - # ReimportFlow - sharedOverlays_Applied_2 = hasKey reimportFlow "fromSharedOverlays"; + # ReimportFlow + sharedOverlays_Applied_2 = hasKey reimportFlow "fromSharedOverlays"; - channelSpecific_Applied_2 = hasKey reimportFlow "fromChannelSpecific"; + channelSpecific_Applied_2 = hasKey reimportFlow "fromChannelSpecific"; - hostConfig_Applied_2 = hasKey reimportFlow "fromHostConfig"; + hostConfig_Applied_2 = hasKey reimportFlow "fromHostConfig"; - contains_srcs_2 = hasKey reimportFlow "srcs"; + contains_srcs_2 = hasKey reimportFlow "srcs"; - }; + }; + }; }; } From 1efba19f46043cd8445f8ae5c34af955db71a197 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Wed, 19 May 2021 12:15:21 +0300 Subject: [PATCH 23/90] Add build-all and check-all commands --- devShell.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/devShell.nix b/devShell.nix index f9881960..331e2569 100644 --- a/devShell.nix +++ b/devShell.nix @@ -75,10 +75,14 @@ devshell.mkShell { (test "derivation-outputs-old") (test "hosts-config") (test "overlays-flow") + (test "all" // { command = "check-channel-patching && check-derivation-outputs && check-derivation-outputs-old && check-hosts-config && check-overlays-flow"; }) + (dry-nixos-build "minimal-multichannel" "Hostname1") (dry-nixos-build "minimal-multichannel" "Hostname2") (dry-nixos-build "home-manager+nur+neovim" "Rick") (dry-nixos-build "exporters" "Morty") + (withCategory "dry-build" { name = "build-all"; command = "build-exporters-Morty && build-home-manager+nur+neovim-Rick && build-minimal-multichannel-Hostname1 && build-minimal-multichannel-Hostname2"; }) + ]; } From 8d8f9d734dfd3b62914bedc02ae6714a41d29f2d Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Thu, 20 May 2021 21:47:45 -0700 Subject: [PATCH 24/90] modulesFromList: allow for import customization and allow .toml files --- src/modulesFromList.nix | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modulesFromList.nix b/src/modulesFromList.nix index 7d91652b..77b96ded 100644 --- a/src/modulesFromList.nix +++ b/src/modulesFromList.nix @@ -1,15 +1,18 @@ { flake-utils-plus }: let - modulesFromListExporter = paths: + modulesFromListExporter = args: /** Synopsis: modulesFromListExporter _paths_ - paths: [ ] + paths: [ ] or { paths = [ ]; _import = ; } Returns an attribute set of modules from a list of paths by converting the path's basename into the attribute key. + Optionally, an attrset can be passed containing `paths` and `_import` + to control how paths get imported + Example: paths: [ ./path/to/moduleA.nix ./path/to/moduleBfolder ] @@ -23,6 +26,11 @@ let let + # To allow for the default to just pass a list + # or pass an attrset with `paths` and `_import` + paths = args.paths or args; + _import = args._import or import; + removeSuffix = suffix: str: let sufLen = builtins.stringLength suffix; @@ -39,8 +47,8 @@ let genAttrs' (path: { - name = removeSuffix ".nix" (baseNameOf path); - value = import path; + name = removeSuffix ".toml" (removeSuffix ".nix" (baseNameOf path)); + value = _import path; }) paths; From 19dc794280aca2e39bbea2663629cffcd3d9f826 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 23 May 2021 14:27:33 +0300 Subject: [PATCH 25/90] Rename lib to src --- flake.nix | 12 ++++++------ {src => lib}/fromOverlays.nix | 0 {src => lib}/internalOverlays.nix | 0 {src => lib}/modulesFromList.nix | 0 {src => lib}/repl.nix | 0 {src => lib}/saneFlakeDefaults.nix | 0 {src => lib}/systemFlake.nix | 0 7 files changed, 6 insertions(+), 6 deletions(-) rename {src => lib}/fromOverlays.nix (100%) rename {src => lib}/internalOverlays.nix (100%) rename {src => lib}/modulesFromList.nix (100%) rename {src => lib}/repl.nix (100%) rename {src => lib}/saneFlakeDefaults.nix (100%) rename {src => lib}/systemFlake.nix (100%) diff --git a/flake.nix b/flake.nix index ad3b620d..80cfe2aa 100644 --- a/flake.nix +++ b/flake.nix @@ -8,14 +8,14 @@ inherit (builtins) isList isAttrs mapAttrs; fupArgs = { flake-utils-plus = self; }; - systemFlake = import ./src/systemFlake.nix fupArgs; - modulesFromList = import ./src/modulesFromList.nix fupArgs; - fromOverlays = import ./src/fromOverlays.nix fupArgs; - internalOverlays = import ./src/internalOverlays.nix fupArgs; + systemFlake = import ./lib/systemFlake.nix fupArgs; + modulesFromList = import ./lib/modulesFromList.nix fupArgs; + fromOverlays = import ./lib/fromOverlays.nix fupArgs; + internalOverlays = import ./lib/internalOverlays.nix fupArgs; in rec { - nixosModules.saneFlakeDefaults = import ./src/saneFlakeDefaults.nix; + nixosModules.saneFlakeDefaults = import ./lib/saneFlakeDefaults.nix; devShell.x86_64-linux = import ./devShell.nix { system = "x86_64-linux"; }; @@ -27,7 +27,7 @@ inherit modulesFromList fromOverlays internalOverlays; }; - repl = ./src/repl.nix; + repl = ./lib/repl.nix; # merge nested attribute sets and lists mergeAny = lhs: rhs: diff --git a/src/fromOverlays.nix b/lib/fromOverlays.nix similarity index 100% rename from src/fromOverlays.nix rename to lib/fromOverlays.nix diff --git a/src/internalOverlays.nix b/lib/internalOverlays.nix similarity index 100% rename from src/internalOverlays.nix rename to lib/internalOverlays.nix diff --git a/src/modulesFromList.nix b/lib/modulesFromList.nix similarity index 100% rename from src/modulesFromList.nix rename to lib/modulesFromList.nix diff --git a/src/repl.nix b/lib/repl.nix similarity index 100% rename from src/repl.nix rename to lib/repl.nix diff --git a/src/saneFlakeDefaults.nix b/lib/saneFlakeDefaults.nix similarity index 100% rename from src/saneFlakeDefaults.nix rename to lib/saneFlakeDefaults.nix diff --git a/src/systemFlake.nix b/lib/systemFlake.nix similarity index 100% rename from src/systemFlake.nix rename to lib/systemFlake.nix From eb85b667f5d678f24caf8410bcb20b7438882296 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 23 May 2021 14:29:30 +0300 Subject: [PATCH 26/90] #60: nixUnstable -> nixFlakes --- lib/saneFlakeDefaults.nix | 6 +----- lib/systemFlake.nix | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/saneFlakeDefaults.nix b/lib/saneFlakeDefaults.nix index ccbe3004..23779dbe 100644 --- a/lib/saneFlakeDefaults.nix +++ b/lib/saneFlakeDefaults.nix @@ -9,10 +9,6 @@ let in { - nix = { - extraOptions = "experimental-features = nix-command ca-references flakes"; - registry = nixRegistry; - package = pkgs.nixUnstable; - }; + nix.registry = nixRegistry; } diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 2e09af96..03e2a8ac 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -154,7 +154,7 @@ let }) (optionalAttrs (options ? nix.package) { - nix.package = lib.mkDefault pkgs.nixUnstable; + nix.package = lib.mkDefault pkgs.nixFlakes; }) { From 12917cba31f29e3b3df6d9c260c2c78714a904ba Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 23 May 2021 18:25:52 +0300 Subject: [PATCH 27/90] #63: Replace saneFlakeDefaults with nix.generateRegistryFromInputs option --- flake.nix | 3 ++- lib/autoRegistry.options.nix | 18 ++++++++++++++++++ lib/saneFlakeDefaults.nix | 14 -------------- lib/systemFlake.nix | 3 ++- 4 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 lib/autoRegistry.options.nix delete mode 100644 lib/saneFlakeDefaults.nix diff --git a/flake.nix b/flake.nix index 80cfe2aa..0a4bbd54 100644 --- a/flake.nix +++ b/flake.nix @@ -15,7 +15,8 @@ in rec { - nixosModules.saneFlakeDefaults = import ./lib/saneFlakeDefaults.nix; + # Deprecated in favor of 'nix.generateRegistryFromInputs = true;' + nixosModules.saneFlakeDefaults = { nix.generateRegistryFromInputs = true; }; devShell.x86_64-linux = import ./devShell.nix { system = "x86_64-linux"; }; diff --git a/lib/autoRegistry.options.nix b/lib/autoRegistry.options.nix new file mode 100644 index 00000000..37842cfc --- /dev/null +++ b/lib/autoRegistry.options.nix @@ -0,0 +1,18 @@ +{ lib, config, inputs, ... }: + +let + flakes = lib.filterAttrs (name: value: value ? outputs) inputs; + + nixRegistry = builtins.mapAttrs + (name: v: { flake = v; }) + flakes; +in +{ + options.nix.generateRegistryFromInputs = lib.mkEnableOption "Generates Nix registry from available inputs."; + + config = lib.mkIf config.nix.generateRegistryFromInputs { + nix.registry = nixRegistry; + }; + + +} diff --git a/lib/saneFlakeDefaults.nix b/lib/saneFlakeDefaults.nix deleted file mode 100644 index 23779dbe..00000000 --- a/lib/saneFlakeDefaults.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ lib, pkgs, inputs, ... }: - -let - flakes = lib.filterAttrs (name: value: value ? outputs) inputs; - - nixRegistry = builtins.mapAttrs - (name: v: { flake = v; }) - flakes; -in -{ - - nix.registry = nixRegistry; - -} diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 03e2a8ac..f86b3005 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -50,7 +50,8 @@ let # These are not part of the module system, so they can be used in `imports` lines without infinite recursion , specialArgs ? { } }: { - inherit channelName system output builder modules extraArgs specialArgs; + inherit channelName system output builder extraArgs specialArgs; + modules = modules ++ [ ./autoRegistry.options.nix ]; }; foldHosts = foldl' mergeAny { }; From ffd0078a2e3f923c2d882c0d6d2ccd33206f7d35 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 23 May 2021 18:37:20 +0300 Subject: [PATCH 28/90] Fix few repl.nix usecases --- lib/repl.nix | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/repl.nix b/lib/repl.nix index ee4457f0..67c95461 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -1,11 +1,12 @@ let - flake = builtins.getFlake "flake:self"; - hostname = builtins.head (builtins.match "([a-zA-Z0-9]+)\n" (builtins.readFile "/etc/hostname")); - nixpkgs = flake.pkgs.${builtins.currentSystem}.nixpkgs; + inherit (builtins) getFlake head match currentSystem; + flake = getFlake "flake:self"; + hostname = head (match "([a-zA-Z0-9]+)\n" (builtins.readFile "/etc/hostname")); + nixpkgs = flake.pkgs.${currentSystem}.nixpkgs; in { inherit flake; } // flake // builtins -// flake.nixosConfigurations.${hostname} -// nixpkgs.lib - // (builtins.removeAttrs nixpkgs [ "config" ]) +// flake.nixosConfigurations.${hostname} or {} +// (removeAttrs nixpkgs.lib [ "options" ]) + // (removeAttrs nixpkgs [ "config" ]) From 9cda3591119d3ef7e03ff68496b3582202c7f3a8 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 23 May 2021 19:07:00 +0300 Subject: [PATCH 29/90] #61: Implement 'channels..input' autogen if not defined --- lib/repl.nix | 2 +- lib/systemFlake.nix | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/repl.nix b/lib/repl.nix index 67c95461..0d345cde 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -7,6 +7,6 @@ in { inherit flake; } // flake // builtins -// flake.nixosConfigurations.${hostname} or {} +// flake.nixosConfigurations.${hostname} or { } // (removeAttrs nixpkgs.lib [ "options" ]) // (removeAttrs nixpkgs [ "config" ]) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index f86b3005..407d4a0c 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -180,6 +180,12 @@ mergeAny otherArguments ( eachSystem supportedSystems (system: let + filterAttrs = pred: set: + listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); + + channelFlakes = filterAttrs (_: value: value ? legacyPackages) inputs; + channelsFromFlakes = mapAttrs (name: input: { inherit input; }) channelFlakes; + importChannel = name: value: (import (patchChannel system value.input (value.patches or [ ])) { inherit system; overlays = [ @@ -191,7 +197,7 @@ mergeAny otherArguments ( config = channelsConfig // (value.config or { }); }) // { inherit name; inherit (value) input; }; - pkgs = mapAttrs importChannel channels; + pkgs = mapAttrs importChannel (mergeAny channelsFromFlakes channels); deprecatedBuilders = channels: { } From a7986457452b5a27f78e74dc805be7f5ac1f3232 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 24 May 2021 14:14:01 +0300 Subject: [PATCH 30/90] Revert "#60: nixUnstable -> nixFlakes" This reverts commit eb85b667f5d678f24caf8410bcb20b7438882296. Also moves nix.extraOptions to lib/systemFlake.nix --- lib/systemFlake.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 03e2a8ac..824374b2 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -154,7 +154,11 @@ let }) (optionalAttrs (options ? nix.package) { - nix.package = lib.mkDefault pkgs.nixFlakes; + nix.package = lib.mkDefault pkgs.nixUnstable; + }) + + (optionalAttrs (options ? nix.extraOptions) { + nix.extraOptions = lib.mkDefault "experimental-features = nix-command ca-references flakes"; }) { From 74e38e66673f0228b37af91a1702529c547ddf18 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Thu, 27 May 2021 11:12:37 +0300 Subject: [PATCH 31/90] Fix nix.extraOptions --- lib/systemFlake.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 0343b23f..356d1818 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -157,9 +157,9 @@ let (optionalAttrs (options ? nix.package) { nix.package = lib.mkDefault pkgs.nixUnstable; }) - + (optionalAttrs (options ? nix.extraOptions) { - nix.extraOptions = lib.mkDefault "experimental-features = nix-command ca-references flakes"; + nix.extraOptions = "experimental-features = nix-command ca-references flakes"; }) { From 5d36f03c3697d07a0c43adeace8b79474473c498 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 23 May 2021 20:06:05 +0300 Subject: [PATCH 32/90] Work on repl.nix --- lib/repl.nix | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/repl.nix b/lib/repl.nix index 0d345cde..8917ef15 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -1,12 +1,18 @@ +{ flakePath ? "flake:self", hostnamePath ? "/etc/hostname" }: + let - inherit (builtins) getFlake head match currentSystem; - flake = getFlake "flake:self"; - hostname = head (match "([a-zA-Z0-9]+)\n" (builtins.readFile "/etc/hostname")); - nixpkgs = flake.pkgs.${currentSystem}.nixpkgs; + inherit (builtins) getFlake head match currentSystem readFile pathExists; + flake = getFlake (toString flakePath); + hostname = if pathExists hostnamePath then head (match "([a-zA-Z0-9]+)\n" (readFile hostnamePath)) else ""; + + nixpkgsFromInputsPath = flake.inputs.nixpkgs.outPath or ""; + nixpkgs = flake.pkgs.${currentSystem}.nixpkgs or (if nixpkgsFromInputsPath != "" then import nixpkgsFromInputsPath { } else { }); + + nixpkgsOutput = (removeAttrs (nixpkgs // nixpkgs.lib or { }) [ "options" "config" ]); in { inherit flake; } // flake // builtins -// flake.nixosConfigurations.${hostname} or { } -// (removeAttrs nixpkgs.lib [ "options" ]) - // (removeAttrs nixpkgs [ "config" ]) +// (flake.nixosConfigurations or { }) +// flake.nixosConfigurations.${builtins.trace hostname hostname} or { } + // nixpkgsOutput From 872d8c3bcceb88462b624fad12b592fcb0411444 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 23 May 2021 20:30:08 +0300 Subject: [PATCH 33/90] Add fup-repl --- lib/systemFlake.nix | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 356d1818..4f5ad682 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -34,6 +34,16 @@ let inherit (flake-utils-plus.lib) eachSystem patchChannel mergeAny; inherit (builtins) foldl' mapAttrs removeAttrs attrValues attrNames listToAttrs concatMap; + fupOverlay = final: prev: { + fup-repl = final.writeShellScriptBin "repl" '' + if [ -z "$1" ]; then + nix repl ${./repl.nix} + else + nix repl --arg flakePath $(readlink -f $1 | sed 's|/flake.nix||') ${./repl.nix} + fi + ''; + }; + filterAttrs = pred: set: listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); @@ -197,7 +207,7 @@ mergeAny otherArguments ( __dontExport = true; # in case user uses overlaysFromChannelsExporter, doesn't hurt for others inherit srcs; }) - ] ++ sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]); + ] ++ sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]) ++ [ fupOverlay ]; config = channelsConfig // (value.config or { }); }) // { inherit name; inherit (value) input; }; From d526007591e455c2f7ecc338e1c0f288be6ffad5 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Thu, 27 May 2021 18:41:32 -0500 Subject: [PATCH 34/90] Add support for reverse DNS hostname declarations --- lib/systemFlake.nix | 23 +++++++++++++++++++++-- tests/hosts-config/flake.nix | 18 ++++++++++++++++++ tests/testing-utils.nix | 11 +++++++---- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 4f5ad682..b287558c 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -47,6 +47,13 @@ let filterAttrs = pred: set: listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); + reverseList = xs: + let l = builtins.length xs; in builtins.genList (n: builtins.elemAt xs (l - n - 1)) l; + + partitionString = sep: s: + builtins.filter (v: builtins.isString v) (builtins.split "${sep}" s); + + srcs = filterAttrs (_: value: !value ? outputs) inputs; # set defaults and validate host arguments @@ -94,8 +101,16 @@ let getChannels = system: self.pkgs.${system}; getNixpkgs = host: (getChannels host.system).${host.channelName}; - configurationBuilder = hostname: host': ( + configurationBuilder = reverseDnsFqdn: host': ( let + dnsLabels = reverseList (partitionString "\\." reverseDnsFqdn); + hostname = builtins.head dnsLabels; + domain = let + domainLabels = builtins.tail dnsLabels; + in + if domainLabels == [] then null # null is the networking.domain option's default + else builtins.concatStringsSep "." domainLabels; + selectedNixpkgs = getNixpkgs host; host = evalHostArgs (mergeAny hostDefaults host'); patchedChannel = selectedNixpkgs.path; @@ -130,7 +145,7 @@ let }).config; in { - ${host.output}.${hostname} = host.builder ({ + ${host.output}.${reverseDnsFqdn} = host.builder ({ inherit (host) system; modules = [ ({ pkgs, lib, options, config, ... }: { @@ -141,6 +156,10 @@ let networking.hostName = hostname; }) + (optionalAttrs (options ? networking.domain) { + networking.domain = domain; + }) + (if options ? nixpkgs.pkgs then { nixpkgs.config = selectedNixpkgs.config; diff --git a/tests/hosts-config/flake.nix b/tests/hosts-config/flake.nix index bcded384..fffc1a47 100644 --- a/tests/hosts-config/flake.nix +++ b/tests/hosts-config/flake.nix @@ -39,6 +39,8 @@ hosts.Plain = { }; + hosts."com.example.myhost" = { }; + hosts.WithFakeBuilder = { builder = args: { fakeBuilder = "fakeBuilder"; }; }; @@ -69,6 +71,12 @@ let plainHost = self.someConfigurations.Plain; plainHostPkgs = plainHost.config.nixpkgs.pkgs; + plainHostName = plainHost.config.networking.hostName; + plainHostDomain = plainHost.config.networking.domain; + + reverseDnsHost = self.someConfigurations."com.example.myhost"; + reverseDnsHostName = reverseDnsHost.config.networking.hostName; + reverseDnsHostDomain = reverseDnsHost.config.networking.domain; customizedHost = self.darwinConfigurations.Customized; customizedHostPkgs = customizedHost.config.nixpkgs.pkgs; @@ -86,6 +94,10 @@ specialArgs_valid_1 = hasKey plainHost.config.lib "sharedSpecialArg"; + hostName_valid_1 = isEqual plainHostName "Plain"; + + domain_valid_1 = isEqual plainHostDomain null; + # System with overwritten hostDefaults system_valid_2 = isEqual customizedHostPkgs.system "x86_64-darwin"; @@ -99,6 +111,12 @@ specialArgs_valid_2 = hasKey customizedHost.config.lib "hostSpecialArg"; + # Hostname and Domain set from reverse DNS name + hostName_valid_3 = isEqual reverseDnsHostName "myhost"; + + domain_valid_3 = isEqual reverseDnsHostDomain "example.com"; + + # Eval fakeBuilder builder_applied = isEqual self.someConfigurations.WithFakeBuilder.fakeBuilder "fakeBuilder"; diff --git a/tests/testing-utils.nix b/tests/testing-utils.nix index b99e93ac..3d52ecb5 100644 --- a/tests/testing-utils.nix +++ b/tests/testing-utils.nix @@ -7,13 +7,16 @@ fileSystems."/" = { device = "test"; fsType = "ext4"; }; }; - isEqual = a: b: + isEqual = a: b: let + stringifyNull = s: + if s == null then "-null-" else s; + in if a == b - then nixpkgs.runCommandNoCC "success-${a}-IS-EQUAL-${b}" { } "echo success > $out" - else nixpkgs.runCommandNoCC "falure-${a}-IS-NOT-EQUAL-${b}" { } "exit 1"; + then nixpkgs.runCommandNoCC "success-${stringifyNull a}-IS-EQUAL-${stringifyNull b}" { } "echo success > $out" + else nixpkgs.runCommandNoCC "faliure-${stringifyNull a}-IS-NOT-EQUAL-${stringifyNull b}" { } "exit 1"; hasKey = attrset: key: if attrset ? ${key} then nixpkgs.runCommandNoCC "success-${key}-exists-in-attrset" { } "echo success > $out" - else nixpkgs.runCommandNoCC "falure-key-${key}-does-not-exist-in-attrset" { } "exit 1"; + else nixpkgs.runCommandNoCC "faliure-key-${key}-does-not-exist-in-attrset" { } "exit 1"; } From ae2bb108a67e7b0ea2b6a2eac494056ca6bdc167 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Fri, 28 May 2021 16:07:38 -0500 Subject: [PATCH 35/90] fix: if domain is not set, pass a default only to remain overridable. --- lib/systemFlake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index b287558c..33efa959 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -108,7 +108,7 @@ let domain = let domainLabels = builtins.tail dnsLabels; in - if domainLabels == [] then null # null is the networking.domain option's default + if domainLabels == [] then (lib.mkDefault null) # null is the networking.domain option's default else builtins.concatStringsSep "." domainLabels; selectedNixpkgs = getNixpkgs host; From 4ee864527357aafc8d431f048fa3683f2ff4ba19 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 31 May 2021 12:04:24 -0500 Subject: [PATCH 36/90] fix/style: pull used builtins in scope That's how we do it. --- lib/systemFlake.nix | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 33efa959..55dceead 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -32,7 +32,24 @@ let inherit (flake-utils-plus.lib) eachSystem patchChannel mergeAny; - inherit (builtins) foldl' mapAttrs removeAttrs attrValues attrNames listToAttrs concatMap; + inherit (builtins) + attrNames + attrValues + concatMap + concatStringsSep + elemAt + filter + foldl' + genList + head + isString + length + listToAttrs + mapAttrs + removeAttrs + split + tail + ; fupOverlay = final: prev: { fup-repl = final.writeShellScriptBin "repl" '' @@ -48,10 +65,10 @@ let listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); reverseList = xs: - let l = builtins.length xs; in builtins.genList (n: builtins.elemAt xs (l - n - 1)) l; + let l = length xs; in genList (n: elemAt xs (l - n - 1)) l; partitionString = sep: s: - builtins.filter (v: builtins.isString v) (builtins.split "${sep}" s); + filter (v: isString v) (split "${sep}" s); srcs = filterAttrs (_: value: !value ? outputs) inputs; @@ -104,12 +121,12 @@ let configurationBuilder = reverseDnsFqdn: host': ( let dnsLabels = reverseList (partitionString "\\." reverseDnsFqdn); - hostname = builtins.head dnsLabels; + hostname = head dnsLabels; domain = let - domainLabels = builtins.tail dnsLabels; + domainLabels = tail dnsLabels; in if domainLabels == [] then (lib.mkDefault null) # null is the networking.domain option's default - else builtins.concatStringsSep "." domainLabels; + else concatStringsSep "." domainLabels; selectedNixpkgs = getNixpkgs host; host = evalHostArgs (mergeAny hostDefaults host'); From 9e93efb4c75ab36290834282e6023b8a29e92ee4 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 31 May 2021 12:20:13 -0500 Subject: [PATCH 37/90] fix: naming --- lib/systemFlake.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 55dceead..b85eab6d 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -118,9 +118,9 @@ let getChannels = system: self.pkgs.${system}; getNixpkgs = host: (getChannels host.system).${host.channelName}; - configurationBuilder = reverseDnsFqdn: host': ( + configurationBuilder = reverseDomainName': ( let - dnsLabels = reverseList (partitionString "\\." reverseDnsFqdn); + dnsLabels = reverseList (partitionString "\\." reverseDomainName); hostname = head dnsLabels; domain = let domainLabels = tail dnsLabels; @@ -162,7 +162,7 @@ let }).config; in { - ${host.output}.${reverseDnsFqdn} = host.builder ({ + ${host.output}.${reverseDomainName} = host.builder ({ inherit (host) system; modules = [ ({ pkgs, lib, options, config, ... }: { From 7f2371107b82c7c08558f59e0d25b65000f64a99 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 31 May 2021 12:44:53 -0500 Subject: [PATCH 38/90] fixup --- lib/systemFlake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index b85eab6d..50bb79f0 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -118,7 +118,7 @@ let getChannels = system: self.pkgs.${system}; getNixpkgs = host: (getChannels host.system).${host.channelName}; - configurationBuilder = reverseDomainName': ( + configurationBuilder = reverseDomainName: host': ( let dnsLabels = reverseList (partitionString "\\." reverseDomainName); hostname = head dnsLabels; From 10096872a0691c3a213073aa8bfe739d37d84a49 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 31 May 2021 17:16:02 -0700 Subject: [PATCH 39/90] don't append overlays manually when passing pkgs overlays get appended by nixpkgs module --- lib/systemFlake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 50bb79f0..717724be 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -190,7 +190,7 @@ let import patchedChannel { inherit (host) system; - overlays = selectedNixpkgs.overlays ++ hostConfig.nixpkgs.overlays; + overlays = selectedNixpkgs.overlays; config = selectedNixpkgs.config // config.nixpkgs.config; } // { inherit (selectedNixpkgs) name input; }; } From 247c99f20e8186d501dc57b24a0bdaaacda6b3c9 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 1 Jun 2021 12:51:10 -0700 Subject: [PATCH 40/90] systemFlake: set __dontExport for fupOverlay --- lib/systemFlake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 717724be..c3ff6dba 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -52,6 +52,7 @@ let ; fupOverlay = final: prev: { + __dontExport = true; fup-repl = final.writeShellScriptBin "repl" '' if [ -z "$1" ]; then nix repl ${./repl.nix} From 6b2ea4b02cad77fac581c6a9ec4f822ba87dce5c Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Wed, 2 Jun 2021 00:36:23 +0300 Subject: [PATCH 41/90] Update testing-utils.nix derivation names --- tests/testing-utils.nix | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/testing-utils.nix b/tests/testing-utils.nix index 3d52ecb5..2acec322 100644 --- a/tests/testing-utils.nix +++ b/tests/testing-utils.nix @@ -1,5 +1,8 @@ { nixpkgs }: +let + str = it: if it == null then "null" else (toString it); +in { # Options that keep Nix from complaining base-nixos = { @@ -7,16 +10,13 @@ fileSystems."/" = { device = "test"; fsType = "ext4"; }; }; - isEqual = a: b: let - stringifyNull = s: - if s == null then "-null-" else s; - in + isEqual = a: b: if a == b - then nixpkgs.runCommandNoCC "success-${stringifyNull a}-IS-EQUAL-${stringifyNull b}" { } "echo success > $out" - else nixpkgs.runCommandNoCC "faliure-${stringifyNull a}-IS-NOT-EQUAL-${stringifyNull b}" { } "exit 1"; + then nixpkgs.runCommandNoCC "SUCCESS__${str a}__IS_EQUAL__${str b}" { } "echo success > $out" + else nixpkgs.runCommandNoCC "FAILURE__${str a}__NOT_EQUAL__${str b}" { } "exit 0"; hasKey = attrset: key: if attrset ? ${key} - then nixpkgs.runCommandNoCC "success-${key}-exists-in-attrset" { } "echo success > $out" - else nixpkgs.runCommandNoCC "faliure-key-${key}-does-not-exist-in-attrset" { } "exit 1"; + then nixpkgs.runCommandNoCC "SUCCESS__${str key}__EXISTS_IN_ATTRSET" { } "echo success > $out" + else nixpkgs.runCommandNoCC "FAILURE__${str key}__DOES_NOT_EXISTS_IN_ATTRSET_SIZE_${str(nixpkgs.lib.length (builtins.attrNames attrset))}" { } "exit 0"; } From 38f0103feadf93f949ca72579607a37601e34178 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 14 Jun 2021 12:22:55 -0500 Subject: [PATCH 42/90] bump flake-utils: incorporate new shiny check-utils --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 2387309c..a1365f7b 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-utils": { "locked": { - "lastModified": 1620759905, - "narHash": "sha256-WiyWawrgmyN0EdmiHyG2V+fqReiVi8bM9cRdMaKQOFg=", + "lastModified": 1623660459, + "narHash": "sha256-OTmOsh43po7r5F9s9H6lVCBQ2b0FikWbmiwLbMAGRdw=", "owner": "numtide", "repo": "flake-utils", - "rev": "b543720b25df6ffdfcf9227afafc5b8c1fabfae8", + "rev": "98c8d36b1828009b20f12544214683c7489935a1", "type": "github" }, "original": { From cfe0181cbbfe2cb50175743dde6f30e6e2522c0e Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 14 Jun 2021 20:58:13 -0500 Subject: [PATCH 43/90] Revert "modulesFromList: allow for import customization" This reverts commit 8d8f9d734dfd3b62914bedc02ae6714a41d29f2d. We need an alternative implementation that uses already imported module's metadata to infer the name. --- lib/modulesFromList.nix | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/modulesFromList.nix b/lib/modulesFromList.nix index 77b96ded..7d91652b 100644 --- a/lib/modulesFromList.nix +++ b/lib/modulesFromList.nix @@ -1,18 +1,15 @@ { flake-utils-plus }: let - modulesFromListExporter = args: + modulesFromListExporter = paths: /** Synopsis: modulesFromListExporter _paths_ - paths: [ ] or { paths = [ ]; _import = ; } + paths: [ ] Returns an attribute set of modules from a list of paths by converting the path's basename into the attribute key. - Optionally, an attrset can be passed containing `paths` and `_import` - to control how paths get imported - Example: paths: [ ./path/to/moduleA.nix ./path/to/moduleBfolder ] @@ -26,11 +23,6 @@ let let - # To allow for the default to just pass a list - # or pass an attrset with `paths` and `_import` - paths = args.paths or args; - _import = args._import or import; - removeSuffix = suffix: str: let sufLen = builtins.stringLength suffix; @@ -47,8 +39,8 @@ let genAttrs' (path: { - name = removeSuffix ".toml" (removeSuffix ".nix" (baseNameOf path)); - value = _import path; + name = removeSuffix ".nix" (baseNameOf path); + value = import path; }) paths; From e9cfad74a79430bfdd391a6073cc581c1b1504c8 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 14 Jun 2021 21:21:18 -0500 Subject: [PATCH 44/90] modulesFromList: infer names from paths or modules's _file attr --- lib/modulesFromList.nix | 50 +++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/modulesFromList.nix b/lib/modulesFromList.nix index 7d91652b..0737c2a3 100644 --- a/lib/modulesFromList.nix +++ b/lib/modulesFromList.nix @@ -1,22 +1,22 @@ { flake-utils-plus }: let - modulesFromListExporter = paths: + modulesFromListExporter = args: /** - Synopsis: modulesFromListExporter _paths_ + Synopsis: modulesFromListExporter _paths or modules_ - paths: [ ] + paths: [ ] - Returns an attribute set of modules from a list of paths by converting - the path's basename into the attribute key. + Returns an attribute set of modules from a list of paths or modules by converting + the path's basename / the module's _file attribute's basename into the attribute key. Example: - paths: [ ./path/to/moduleA.nix ./path/to/moduleBfolder ] + paths: [ ./path/to/moduleA.nix { _file = ./path/to/moduleBfolder; ... } ] { moduleA = import ./path/to/moduleA.nix; - moduleBfolder = import ./path/to/moduleBfolder; + moduleBfolder = { _file = ./path/to/moduleBfolder; ... } } **/ @@ -35,14 +35,40 @@ let genAttrs' = func: values: builtins.listToAttrs (map func values); + hasFileAttr = o: builtins.hasAttr "_file" o; + peek = f: f (builtins.functionArgs f); + in genAttrs' - (path: { - name = removeSuffix ".nix" (baseNameOf path); - value = import path; - }) - paths; + (arg: + + # a regular path to be imported + if builtins.isPath arg then + { + name = removeSuffix ".nix" (baseNameOf arg); + value = import arg; + } + + # a module function with a _file attr + else if ((builtins.isFunction arg) && (hasFileAttr (peek args))) then + { + name = removeSuffix ".toml" (removeSuffix ".nix" (baseNameOf (peek arg)._file)); + value = arg; + } + + # a module with a _file attr + else if (hasFileAttr arg) then + { + name = removeSuffix ".toml" (removeSuffix ".nix" (baseNameOf arg._file)); + value = arg; + } + + # panic: something else + else + builtins.throw "either pass a path or a module with _file key to modulesFromListExporter" + ) + args; in modulesFromListExporter From 785e6f13b8c6131d1eee625a713e8475b2b0512b Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sat, 19 Jun 2021 13:09:42 -0500 Subject: [PATCH 45/90] fixup! modulesFromList: infer names from paths or modules's _file attr --- lib/modulesFromList.nix | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/modulesFromList.nix b/lib/modulesFromList.nix index 0737c2a3..07d467bd 100644 --- a/lib/modulesFromList.nix +++ b/lib/modulesFromList.nix @@ -51,22 +51,36 @@ let } # a module function with a _file attr - else if ((builtins.isFunction arg) && (hasFileAttr (peek args))) then + else if ((builtins.isFunction arg) && (hasFileAttr (peek arg))) then { name = removeSuffix ".toml" (removeSuffix ".nix" (baseNameOf (peek arg)._file)); value = arg; } - # a module with a _file attr - else if (hasFileAttr arg) then + # panic: a module function without a _file attr + else if ((builtins.isFunction arg) && (!(hasFileAttr (peek arg)))) then + builtins.throw '' + module function has no (required) _file argument key: ${builtins.trace (peek arg) "."} + '' + + # a simple module with a _file attr + else if (builtins.isAttrs arg) && (hasFileAttr arg) then { name = removeSuffix ".toml" (removeSuffix ".nix" (baseNameOf arg._file)); value = arg; } + # panic: a simple module with a _file attr + else if (builtins.isAttrs arg) && (hasFileAttr arg) then + builtins.throw '' + simple module has no (required) _file argument key: ${builtins.trace arg "."} + '' + # panic: something else else - builtins.throw "either pass a path or a module with _file key to modulesFromListExporter" + builtins.throw '' + either pass a path or a module with _file key to modulesFromListExporter: ${builtins.trace arg "."} + '' ) args; From 36d9cd23223a2782ed36630d2efcedfb93ea9734 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 20 Jun 2021 14:16:07 +0300 Subject: [PATCH 46/90] Update dependencies + implement check-utils --- devShell.nix | 8 ++++---- examples/exporters/flake.nix | 2 +- examples/home-manager+nur+neovim/flake.nix | 4 ++-- examples/minimal-multichannel/flake.nix | 2 +- flake.lock | 6 +++--- tests/channel-patching/flake.nix | 5 +---- tests/derivation-outputs/flake.nix | 4 +--- tests/hosts-config/flake.nix | 8 ++++++-- tests/overlays-flow/flake.nix | 5 +---- tests/testing-utils.nix | 22 ---------------------- 10 files changed, 20 insertions(+), 46 deletions(-) delete mode 100644 tests/testing-utils.nix diff --git a/devShell.nix b/devShell.nix index 331e2569..ca44a562 100644 --- a/devShell.nix +++ b/devShell.nix @@ -1,17 +1,17 @@ { system ? builtins.currentSystem }: let # nixpkgs / devshell is only used for development. Don't add it to the flake.lock. - nixpkgsGitRev = "5268ee2ebacbc73875be42d71e60c2b5c1b5a1c7"; - devshellGitRev = "709fe4d04a9101c9d224ad83f73416dce71baf21"; + nixpkgsGitRev = "246502ae2d5ca9def252abe0ce6363a0f08382a7"; + devshellGitRev = "1f4fb67b662b65fa7cfe696fc003fcc1e8f7cc36"; nixpkgsSrc = fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsGitRev}.tar.gz"; - sha256 = "080fvmg0i6z01h6adddfrjp1bbbjhhqk32ks6ch9gv689645ccfq"; + sha256 = "sha256-cuCj8CfBrVlEYQM2jfD3psh2jV/sR5HACYkC74WR9KE="; }; devshellSrc = fetchTarball { url = "https://github.com/numtide/devshell/archive/${devshellGitRev}.tar.gz"; - sha256 = "1px9cqfshfqs1b7ypyxch3s3ymr4xgycy1krrcg7b97rmmszvsqr"; + sha256 = "03258pq60nppq39571bjxqn75h3rn25bdlrx04k75v20n77xfs5c"; }; pkgs = import nixpkgsSrc { inherit system; }; diff --git a/examples/exporters/flake.nix b/examples/exporters/flake.nix index 6ae01c81..11fc405b 100644 --- a/examples/exporters/flake.nix +++ b/examples/exporters/flake.nix @@ -2,7 +2,7 @@ description = "A highly awesome system configuration."; inputs = { - nixpkgs.url = github:nixos/nixpkgs/release-20.09; + nixpkgs.url = github:nixos/nixpkgs/nixos-unstable-small; utils.url = path:../../; }; diff --git a/examples/home-manager+nur+neovim/flake.nix b/examples/home-manager+nur+neovim/flake.nix index a8d29570..6738ab0f 100644 --- a/examples/home-manager+nur+neovim/flake.nix +++ b/examples/home-manager+nur+neovim/flake.nix @@ -2,7 +2,7 @@ description = "A highly awesome system configuration."; inputs = { - nixpkgs.url = github:nixos/nixpkgs/nixos-unstable; + nixpkgs.url = github:nixos/nixpkgs/nixos-unstable-small; utils.url = path:../../; @@ -14,7 +14,7 @@ }; home-manager = { - url = github:nix-community/home-manager/release-20.09; + url = github:nix-community/home-manager/release-21.05; inputs.nixpkgs.follows = "nixpkgs"; }; }; diff --git a/examples/minimal-multichannel/flake.nix b/examples/minimal-multichannel/flake.nix index 0866a717..770c4a44 100644 --- a/examples/minimal-multichannel/flake.nix +++ b/examples/minimal-multichannel/flake.nix @@ -2,7 +2,7 @@ description = "A highly awesome system configuration."; inputs = { - nixpkgs.url = github:nixos/nixpkgs/release-20.09; + nixpkgs.url = github:nixos/nixpkgs/release-21.05; unstable.url = github:nixos/nixpkgs/nixos-unstable; utils.url = path:../../; }; diff --git a/flake.lock b/flake.lock index a1365f7b..54993f88 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-utils": { "locked": { - "lastModified": 1623660459, - "narHash": "sha256-OTmOsh43po7r5F9s9H6lVCBQ2b0FikWbmiwLbMAGRdw=", + "lastModified": 1623875721, + "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", "owner": "numtide", "repo": "flake-utils", - "rev": "98c8d36b1828009b20f12544214683c7489935a1", + "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772", "type": "github" }, "original": { diff --git a/tests/channel-patching/flake.nix b/tests/channel-patching/flake.nix index 43f53624..3de608fc 100644 --- a/tests/channel-patching/flake.nix +++ b/tests/channel-patching/flake.nix @@ -2,10 +2,6 @@ inputs.utils.url = path:../../; outputs = inputs@{ self, nixpkgs, utils }: - let - testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; - inherit (testing-utils) hasKey isEqual; - in utils.lib.systemFlake { inherit self inputs; supportedSystems = [ "x86_64-linux" ]; @@ -52,6 +48,7 @@ checks = let + inherit (utils.lib.check-utils channels.nixpkgs) hasKey isEqual; hostConfig = self.nixosConfigurations.PatchedHost.config; in { diff --git a/tests/derivation-outputs/flake.nix b/tests/derivation-outputs/flake.nix index 00e09d0c..26cf8cd6 100644 --- a/tests/derivation-outputs/flake.nix +++ b/tests/derivation-outputs/flake.nix @@ -3,9 +3,6 @@ outputs = inputs@{ self, nixpkgs, utils }: let - testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; - inherit (testing-utils) hasKey isEqual; - mkApp = utils.lib.mkApp; in utils.lib.systemFlake { @@ -55,6 +52,7 @@ checks = let + inherit (utils.lib.check-utils channels.nixpkgs) hasKey isEqual; inherit (nixpkgs.lib) hasSuffix; getOutput = output: self.${output}.${channels.nixpkgs.system}; diff --git a/tests/hosts-config/flake.nix b/tests/hosts-config/flake.nix index fffc1a47..044c427f 100644 --- a/tests/hosts-config/flake.nix +++ b/tests/hosts-config/flake.nix @@ -3,8 +3,10 @@ outputs = inputs@{ self, nixpkgs, utils }: let - testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; - inherit (testing-utils) hasKey base-nixos isEqual; + base-nixos = { + boot.loader.grub.devices = [ "nodev" ]; + fileSystems."/" = { device = "test"; fsType = "ext4"; }; + }; in utils.lib.systemFlake { inherit self inputs; @@ -69,6 +71,8 @@ outputsBuilder = channels: { checks = let + inherit (utils.lib.check-utils channels.nixpkgs) hasKey isEqual; + plainHost = self.someConfigurations.Plain; plainHostPkgs = plainHost.config.nixpkgs.pkgs; plainHostName = plainHost.config.networking.hostName; diff --git a/tests/overlays-flow/flake.nix b/tests/overlays-flow/flake.nix index 24face65..b765e0e9 100644 --- a/tests/overlays-flow/flake.nix +++ b/tests/overlays-flow/flake.nix @@ -2,10 +2,6 @@ inputs.utils.url = path:../../; outputs = inputs@{ self, nixpkgs, utils }: - let - testing-utils = import ../testing-utils.nix { inherit (self.pkgs.x86_64-linux) nixpkgs; }; - inherit (testing-utils) hasKey; - in utils.lib.systemFlake { inherit self inputs; supportedSystems = [ "x86_64-linux" ]; @@ -63,6 +59,7 @@ outputsBuilder = channels: { checks = let + inherit (utils.lib.check-utils channels.nixpkgs) hasKey; existingPkgsFlow = self.nixosConfigurations.ExistingPkgsFlow.pkgs; reimportFlow = self.nixosConfigurations.ReimportFlow.pkgs; in diff --git a/tests/testing-utils.nix b/tests/testing-utils.nix deleted file mode 100644 index 2acec322..00000000 --- a/tests/testing-utils.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ nixpkgs }: - -let - str = it: if it == null then "null" else (toString it); -in -{ - # Options that keep Nix from complaining - base-nixos = { - boot.loader.grub.devices = [ "nodev" ]; - fileSystems."/" = { device = "test"; fsType = "ext4"; }; - }; - - isEqual = a: b: - if a == b - then nixpkgs.runCommandNoCC "SUCCESS__${str a}__IS_EQUAL__${str b}" { } "echo success > $out" - else nixpkgs.runCommandNoCC "FAILURE__${str a}__NOT_EQUAL__${str b}" { } "exit 0"; - - hasKey = attrset: key: - if attrset ? ${key} - then nixpkgs.runCommandNoCC "SUCCESS__${str key}__EXISTS_IN_ATTRSET" { } "echo success > $out" - else nixpkgs.runCommandNoCC "FAILURE__${str key}__DOES_NOT_EXISTS_IN_ATTRSET_SIZE_${str(nixpkgs.lib.length (builtins.attrNames attrset))}" { } "exit 0"; -} From f60eb469be1a759bce1ee2a6c820efdfb224658c Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 20 Jun 2021 15:17:25 +0300 Subject: [PATCH 47/90] Seperate repl overlay and implement help menu --- flake.nix | 2 ++ lib/overlay.nix | 25 +++++++++++++++++++++++++ lib/systemFlake.nix | 22 ++++++---------------- 3 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 lib/overlay.nix diff --git a/flake.nix b/flake.nix index 0a4bbd54..c7509666 100644 --- a/flake.nix +++ b/flake.nix @@ -12,8 +12,10 @@ modulesFromList = import ./lib/modulesFromList.nix fupArgs; fromOverlays = import ./lib/fromOverlays.nix fupArgs; internalOverlays = import ./lib/internalOverlays.nix fupArgs; + overlay = import ./lib/overlay.nix; in rec { + inherit overlay; # Deprecated in favor of 'nix.generateRegistryFromInputs = true;' nixosModules.saneFlakeDefaults = { nix.generateRegistryFromInputs = true; }; diff --git a/lib/overlay.nix b/lib/overlay.nix new file mode 100644 index 00000000..fbdc07ca --- /dev/null +++ b/lib/overlay.nix @@ -0,0 +1,25 @@ +final: prev: +let + example = command: desc: ''\n\u001b[33m ${command}\u001b[0m - ${desc}''; +in +{ + __dontExport = true; + + fup-repl = final.writeShellScriptBin "repl" '' + case "$1" in + "-h"|"--help"|"help") + printf "%b\n\e[4mUsage\e[0m: \ + ${example "repl" "Loads system flake if available."} \ + ${example "repl /path/to/flake.nix" "Loads specified flake."}\n" + ;; + *) + if [ -z "$1" ]; then + nix repl ${./repl.nix} + else + nix repl --arg flakePath $(readlink -f $1 | sed 's|/flake.nix||') ${./repl.nix} + fi + ;; + esac + ''; +} + diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index c3ff6dba..1c13293e 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -51,17 +51,6 @@ let tail ; - fupOverlay = final: prev: { - __dontExport = true; - fup-repl = final.writeShellScriptBin "repl" '' - if [ -z "$1" ]; then - nix repl ${./repl.nix} - else - nix repl --arg flakePath $(readlink -f $1 | sed 's|/flake.nix||') ${./repl.nix} - fi - ''; - }; - filterAttrs = pred: set: listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); @@ -123,10 +112,11 @@ let let dnsLabels = reverseList (partitionString "\\." reverseDomainName); hostname = head dnsLabels; - domain = let - domainLabels = tail dnsLabels; - in - if domainLabels == [] then (lib.mkDefault null) # null is the networking.domain option's default + domain = + let + domainLabels = tail dnsLabels; + in + if domainLabels == [ ] then (lib.mkDefault null) # null is the networking.domain option's default else concatStringsSep "." domainLabels; selectedNixpkgs = getNixpkgs host; @@ -244,7 +234,7 @@ mergeAny otherArguments ( __dontExport = true; # in case user uses overlaysFromChannelsExporter, doesn't hurt for others inherit srcs; }) - ] ++ sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]) ++ [ fupOverlay ]; + ] ++ sharedOverlays ++ (if (value ? overlaysBuilder) then (value.overlaysBuilder pkgs) else [ ]) ++ [ flake-utils-plus.overlay ]; config = channelsConfig // (value.config or { }); }) // { inherit name; inherit (value) input; }; From b87458d530a453e3eef98dce8585354c454d1c74 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 20 Jun 2021 15:33:24 +0300 Subject: [PATCH 48/90] Make repl find system flake path more dynamically --- lib/repl.nix | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/repl.nix b/lib/repl.nix index 8917ef15..d9dfc72e 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -1,8 +1,12 @@ -{ flakePath ? "flake:self", hostnamePath ? "/etc/hostname" }: +{ flakePath ? null, hostnamePath ? "/etc/hostname" }: let - inherit (builtins) getFlake head match currentSystem readFile pathExists; - flake = getFlake (toString flakePath); + inherit (builtins) getFlake head match currentSystem readFile pathExists filter fromJSON; + flakePath' = + if flakePath != null + then flakePath + else (head (filter (it: it.from.id == "self") (fromJSON (readFile /etc/nix/registry.json)).flakes)).to.path; + flake = getFlake (toString flakePath'); hostname = if pathExists hostnamePath then head (match "([a-zA-Z0-9]+)\n" (readFile hostnamePath)) else ""; nixpkgsFromInputsPath = flake.inputs.nixpkgs.outPath or ""; @@ -14,5 +18,5 @@ in // flake // builtins // (flake.nixosConfigurations or { }) -// flake.nixosConfigurations.${builtins.trace hostname hostname} or { } +// flake.nixosConfigurations.${hostname} or { } // nixpkgsOutput From 68983c1db835516e69f31d7f5f6aabc2bc3f841a Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 20 Jun 2021 15:46:39 +0300 Subject: [PATCH 49/90] Make 'self' flake to always exist as part of the registry --- lib/autoRegistry.options.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/autoRegistry.options.nix b/lib/autoRegistry.options.nix index 37842cfc..8be4d6d0 100644 --- a/lib/autoRegistry.options.nix +++ b/lib/autoRegistry.options.nix @@ -10,9 +10,11 @@ in { options.nix.generateRegistryFromInputs = lib.mkEnableOption "Generates Nix registry from available inputs."; - config = lib.mkIf config.nix.generateRegistryFromInputs { - nix.registry = nixRegistry; + config = { + nix.registry = + if config.nix.generateRegistryFromInputs + then nixRegistry + else { self.flake = flakes.self; }; }; - } From 91cad97a01a76c4cc3c218a4ce1fa6408ec11616 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 20 Jun 2021 15:47:05 +0300 Subject: [PATCH 50/90] Fix repl paths checking --- lib/repl.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/repl.nix b/lib/repl.nix index d9dfc72e..d3ebf82b 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -2,10 +2,14 @@ let inherit (builtins) getFlake head match currentSystem readFile pathExists filter fromJSON; + selfFlake = filter (it: it.from.id == "self") (fromJSON (readFile /etc/nix/registry.json)).flakes; flakePath' = if flakePath != null then flakePath - else (head (filter (it: it.from.id == "self") (fromJSON (readFile /etc/nix/registry.json)).flakes)).to.path; + else if selfFlake != [] + then (head selfFlake).to.path + else "/etc/nixos"; + flake = getFlake (toString flakePath'); hostname = if pathExists hostnamePath then head (match "([a-zA-Z0-9]+)\n" (readFile hostnamePath)) else ""; From 490c38a486dad12b9ecbe749f03d3bcb2db8bbc1 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Fri, 25 Jun 2021 08:15:33 +0300 Subject: [PATCH 51/90] Allow repl open even if flake was not found --- lib/repl.nix | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/repl.nix b/lib/repl.nix index d3ebf82b..0b674216 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -2,15 +2,20 @@ let inherit (builtins) getFlake head match currentSystem readFile pathExists filter fromJSON; - selfFlake = filter (it: it.from.id == "self") (fromJSON (readFile /etc/nix/registry.json)).flakes; - flakePath' = - if flakePath != null + registryPath = /etc/nix/registry.json; + selfFlake = + if pathExists registryPath + then filter (it: it.from.id == "self") (fromJSON (readFile registryPath)).flakes + else [ ]; + + flakePath' = toString + (if flakePath != null then flakePath - else if selfFlake != [] + else if selfFlake != [ ] then (head selfFlake).to.path - else "/etc/nixos"; + else "/etc/nixos"); - flake = getFlake (toString flakePath'); + flake = if pathExists flakePath' then getFlake flakePath' else { }; hostname = if pathExists hostnamePath then head (match "([a-zA-Z0-9]+)\n" (readFile hostnamePath)) else ""; nixpkgsFromInputsPath = flake.inputs.nixpkgs.outPath or ""; From 5cf2e3efb1aab9476bcabe1c3e78a34ca80b3a19 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Fri, 25 Jun 2021 08:19:04 +0300 Subject: [PATCH 52/90] 71: Fix repl reproducability --- lib/overlay.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/overlay.nix b/lib/overlay.nix index fbdc07ca..fedbfd77 100644 --- a/lib/overlay.nix +++ b/lib/overlay.nix @@ -16,7 +16,7 @@ in if [ -z "$1" ]; then nix repl ${./repl.nix} else - nix repl --arg flakePath $(readlink -f $1 | sed 's|/flake.nix||') ${./repl.nix} + nix repl --arg flakePath $(${final.coreutils}/bin/readlink -f $1 | ${final.gnused}/bin/sed 's|/flake.nix||') ${./repl.nix} fi ;; esac From 438316a7b7d798bff326c97da8e2b15a56c7657e Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Fri, 25 Jun 2021 08:39:15 +0300 Subject: [PATCH 53/90] Add loadFlake function --- lib/repl.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/repl.nix b/lib/repl.nix index 0b674216..f0bbfeb4 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -28,4 +28,5 @@ in // builtins // (flake.nixosConfigurations or { }) // flake.nixosConfigurations.${hostname} or { } - // nixpkgsOutput +// nixpkgsOutput + // { loadFlake = path: getFlake (toString path);} From 0a8e4005a3abc840eded875b302a605a4d422298 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sat, 3 Jul 2021 17:59:47 +0300 Subject: [PATCH 54/90] Add mkDefault to extra-options --- lib/systemFlake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 1c13293e..64c77ba4 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -196,7 +196,7 @@ let }) (optionalAttrs (options ? nix.extraOptions) { - nix.extraOptions = "experimental-features = nix-command ca-references flakes"; + nix.extraOptions = lib.mkDefault "experimental-features = nix-command ca-references flakes"; }) { From f0cbd4d78203e03f16273ac0a9be9ee0ca9cd545 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Fri, 9 Jul 2021 17:44:49 +0300 Subject: [PATCH 55/90] Use extra-experimental-features instead of experimental-features --- lib/systemFlake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 64c77ba4..7aebcb80 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -196,7 +196,7 @@ let }) (optionalAttrs (options ? nix.extraOptions) { - nix.extraOptions = lib.mkDefault "experimental-features = nix-command ca-references flakes"; + nix.extraOptions = "extra-experimental-features = nix-command ca-references flakes"; }) { From c94a68e3cb49ccc2d65dd77eb33286ffdf8a7696 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Fri, 9 Jul 2021 17:47:54 +0300 Subject: [PATCH 56/90] Fix formatting --- lib/repl.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/repl.nix b/lib/repl.nix index f0bbfeb4..404eb708 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -29,4 +29,4 @@ in // (flake.nixosConfigurations or { }) // flake.nixosConfigurations.${hostname} or { } // nixpkgsOutput - // { loadFlake = path: getFlake (toString path);} + // { loadFlake = path: getFlake (toString path); } From d490fe933fcf0996d6cfef0508a0e9091bb65b70 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sun, 11 Jul 2021 22:42:33 +0300 Subject: [PATCH 57/90] examples: add comments --- examples/exporters/flake.nix | 14 +++++++++----- examples/home-manager+nur+neovim/flake.nix | 3 +-- examples/minimal-multichannel/flake.nix | 6 ++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/exporters/flake.nix b/examples/exporters/flake.nix index 11fc405b..3c382c5c 100644 --- a/examples/exporters/flake.nix +++ b/examples/exporters/flake.nix @@ -1,5 +1,5 @@ { - description = "A highly awesome system configuration."; + description = "FUP exporters demo"; inputs = { nixpkgs.url = github:nixos/nixpkgs/nixos-unstable-small; @@ -14,16 +14,20 @@ utils.lib.systemFlake { inherit self inputs; - channels.nixpkgs.input = nixpkgs; - - hosts.Morty.modules = with self.nixosModules; [ - Morty + # explicitly add overlaysBuilder + channels.nixpkgs.overlaysBuilder = arg: [ + (final: prev: { inherit coreutils; }) ]; + # propagates to channels.nixpkgs.overlaysBuilder sharedOverlays = [ self.overlay ]; + hosts.Morty.modules = with self.nixosModules; [ + Morty + ]; + nixosModules = modulesFromList [ ./hosts/Morty.nix ]; diff --git a/examples/home-manager+nur+neovim/flake.nix b/examples/home-manager+nur+neovim/flake.nix index 6738ab0f..42496af5 100644 --- a/examples/home-manager+nur+neovim/flake.nix +++ b/examples/home-manager+nur+neovim/flake.nix @@ -1,5 +1,5 @@ { - description = "A highly awesome system configuration."; + description = "Home Manager + NUR + Neovim config"; inputs = { nixpkgs.url = github:nixos/nixpkgs/nixos-unstable-small; @@ -25,7 +25,6 @@ inherit self inputs; - channels.nixpkgs.input = nixpkgs; channelsConfig.allowUnfree = true; sharedOverlays = [ diff --git a/examples/minimal-multichannel/flake.nix b/examples/minimal-multichannel/flake.nix index 770c4a44..a459c32a 100644 --- a/examples/minimal-multichannel/flake.nix +++ b/examples/minimal-multichannel/flake.nix @@ -13,8 +13,8 @@ inherit self inputs; # Channel definitions. - channels.unstable.input = unstable; - channels.nixpkgs.input = nixpkgs; + # Channels are automatically generated from nixpkgs inputs + # e.g the inputs which contain `legacyPackages` channelsConfig.allowUnfree = true; @@ -25,9 +25,7 @@ ]; - ############# ### Hosts ### - ############# # Machine using default channel (nixpkgs) hosts.Hostname1.modules = [ From 96d816c298a32062307e290f1e4263fbb91dae45 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Wed, 14 Jul 2021 13:29:35 -0500 Subject: [PATCH 58/90] imp: allow arguments for devshell checks This allows to pass --show-trace to the checks --- devShell.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/devShell.nix b/devShell.nix index ca44a562..f58a2259 100644 --- a/devShell.nix +++ b/devShell.nix @@ -27,8 +27,8 @@ let set -e cd $DEVSHELL_ROOT/tests/${name} nix flake lock --update-input utils - nix flake show - nix flake check + nix flake show "$@" + nix flake check "$@" git rm -f flake.lock ''; }; @@ -39,8 +39,8 @@ let set -e cd $DEVSHELL_ROOT/examples/${example} nix flake lock --update-input utils - nix flake show - nix build .#nixosConfigurations.${host}.config.system.build.toplevel --dry-run + nix flake show "$@" + nix build .#nixosConfigurations.${host}.config.system.build.toplevel --dry-run "$@" git rm -f flake.lock ''; }; From 5c6ee69f6957afc2fe22c094717d6d78516418b5 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 12 Jul 2021 18:50:53 -0500 Subject: [PATCH 59/90] imp: make output dynamic according to outputsBuilder towards #79 --- lib/systemFlake.nix | 14 ++++---------- tests/derivation-outputs/flake.nix | 10 +++++++++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/systemFlake.nix b/lib/systemFlake.nix index 7aebcb80..a4fca03e 100644 --- a/lib/systemFlake.nix +++ b/lib/systemFlake.nix @@ -78,8 +78,6 @@ let modules = modules ++ [ ./autoRegistry.options.nix ]; }; - foldHosts = foldl' mergeAny { }; - optionalAttrs = check: value: if check then value else { }; otherArguments = removeAttrs args [ @@ -251,7 +249,8 @@ mergeAny otherArguments ( systemOutputs = (if outputsBuilder == null then deprecatedBuilders else outputsBuilder) pkgs; - mkOutput = output: + mkOutputs = attrs: output: + attrs // mergeAny # prevent override of nested outputs in otherArguments (optionalAttrs (otherArguments ? ${output}.${system}) @@ -261,16 +260,11 @@ mergeAny otherArguments ( in { inherit pkgs; } - // mkOutput "packages" - // mkOutput "defaultPackage" - // mkOutput "apps" - // mkOutput "defaultApp" - // mkOutput "devShell" - // mkOutput "checks" + // (foldl' mkOutputs { } (attrNames systemOutputs)) ) # produces attrset in the shape of # { nixosConfigurations = {}; darwinConfigurations = {}; ... } # according to profile.output or the default `nixosConfigurations` - // foldHosts (attrValues (mapAttrs configurationBuilder hosts)) + // foldl' mergeAny { } (attrValues (mapAttrs configurationBuilder hosts)) ) diff --git a/tests/derivation-outputs/flake.nix b/tests/derivation-outputs/flake.nix index 26cf8cd6..d098df8e 100644 --- a/tests/derivation-outputs/flake.nix +++ b/tests/derivation-outputs/flake.nix @@ -16,11 +16,14 @@ ################# - # Should Get merged with `packagesBuilder` + # Should Get merged with corresponding outputsBuilder ouput packages.x86_64-linux.coreutils2 = self.pkgs.x86_64-linux.nixpkgs.coreutils; + customSystemOutput.x86_64-linux.bar = "bar-string"; outputsBuilder = channels: { + customSystemOutput = { foo = "foo-string"; }; + packages = { inherit (channels.nixpkgs) coreutils; }; @@ -59,6 +62,7 @@ packages = getOutput "packages"; defaultPackage = getOutput "defaultPackage"; devShell = getOutput "devShell"; + customSystemOutput = getOutput "customSystemOutput"; isTrue = cond: if cond @@ -67,6 +71,10 @@ in { + # Custom System Ouput + customSystemOutput_valid = isEqual customSystemOutput.foo "foo-string"; + customSystemOutput_merged = isEqual customSystemOutput.bar "bar-string"; + # Packages defaultPackage_valid = isEqual defaultPackage.pname "coreutils"; From 2e5c29dc05cdc7cda6ed4a48f3192ef423b1d486 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sun, 11 Jul 2021 22:43:26 +0300 Subject: [PATCH 60/90] README: update documentation to future lib Update examples/minimal-multichannel/flake.nix Co-authored-by: Pacman99 Co-authored-by: Gytis Ivaskevicius --- README.md | 90 +++++++++++++------------ examples/exporters/flake.nix | 9 ++- examples/minimal-multichannel/flake.nix | 3 +- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 4f365149..ff5dd1bc 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,40 @@ [![Discord](https://img.shields.io/discord/591914197219016707.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.com/invite/RbvHtGa) -Need help? Createn an issue or ping @Gytis#0001 in discord server above. +Need help? Create an issue or ping @Gytis#0001 in the above Discord Server. -# What is this flake # +# What is this flake? # -This flake exposes a library abstraction to *painlessly* generate nixos flake configurations. +Flake-utils-plus exposes a library abstraction to *painlessly* generate NixOS flake configurations. -The biggest design goal is to keep down the fluff. The library is meant to be easy to understand and use. It aims to be far simpler than frameworks such as devos (previously called nixflk). +The biggest design goal is to keep down the fluff. The library is meant to be easy to understand and use. It aims to be far simpler than frameworks such as DevOS (previously called nixflk). -# Features of flake # +# Features of the flake # -This flake provides two main features (visible from `flake.nix`): +FUP provides a few main features (visible from `flake.nix`): -- `nixosModules.saneFlakeDefaults` - Configures `nix.*` attributes. Generates `nix.nixPath`/`nix.registry` from flake `inputs`, sets `pkgs.nixUnstable` as the default also enables `ca-references` and `flakes`. -- `lib.systemFlake { ... }` - Generates a system flake that may then be built. -- `lib.exporter.modulesFromListExporter [ ./a.nix ./b.nix ]` - Generates modules attributes which looks like this `{ a = import ./a.nix; b = import ./b.nix; }`. -- `lib.exporter.overlaysFromChannelsExporter channels` - Collects all overlays from channels and exports them as an appropriately namespaced attribute set. Users can instantiate with their nixpkgs version. -- `lib.builder.packagesFromOverlayBuilderConstructor channels pkgs` - Similar to the overlay generator, but outputs them as packages, instead. Users can use your cache. +- `nix.generateRegistryFromInputs` - Generates `nix.registry` from flake `inputs`. +- `lib.mkFlake { ... }` - Generates a flake using FUP magic. +- `lib.exportModules [ ./a.nix ./b.nix ]` - Generates module attribute which look like this `{ a = import ./a.nix; b = import ./b.nix; }`. +- `lib.exportOverlays channels` - Exports all overlays from channels as an appropriately namespaced attribute set. Users can instantiate with their nixpkgs version. +- `lib.outputsBuilder.packages channels pkgs` - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. +# How to use # -# Examples # +* [Using FUP to configure hosts with Home Manager, NUR and neovim](https://github.com/gytis-ivaskevicius/flake-utils-plus/blob/master/examples/home-manager+nur+neovim) + +* [Example of using multiple channels](https://github.com/gytis-ivaskevicius/flake-utils-plus/blob/master/examples/minimal-multichannel) + +## Examples + +We recommend referring to people's examples below when setting up your system. - [Gytis Dotfiles (Author of this project)](https://github.com/gytis-ivaskevicius/nixfiles/blob/master/flake.nix) - [Fufexan Dotfiles](https://github.com/fufexan/dotfiles/blob/main/flake.nix) - [Bobbbay Dotfiles](https://github.com/Bobbbay/dotfiles/blob/master/flake.nix) - [Charlotte Dotfiles](https://github.com/chvp/nixos-config/blob/master/flake.nix) -# How to use this flake # - -Example flake with all available attributes can be found [Here](https://github.com/gytis-ivaskevicius/flake-utils-plus/blob/master/examples/fully-featured/flake.nix). (WARNING: Quite overwhelming) - -And more realistic flake example can be found [Here](https://github.com/gytis-ivaskevicius/flake-utils-plus/blob/master/examples/somewhat-realistic/flake.nix). - -I strongly recommend referring to actual people examples above when setting up your system. - -Looking to add a kick-ass repl to your config? Create and import something along the lines of this: +Looking to add a kick-ass repl to your config? Create and import something along these lines: ```nix { inputs, ... }: @@ -47,7 +46,9 @@ Looking to add a kick-ass repl to your config? Create and import something along ``` -## Documentation as code. Options with their example usage and description. +# Documentation + +Options with their example usage and description. ```nix let @@ -55,10 +56,10 @@ let mkApp = utils.lib.mkApp; # If there is a need to get direct reference to nixpkgs - do this: pkgs = self.pkgs.x86_64-linux.nixpkgs; -in flake-utils-plus.lib.systemFlake { +in flake-utils-plus.lib.mkFlake { - # `self` and `inputs` arguments are REQUIRED!!!!!!!!!!!!!! + # `self` and `inputs` arguments are REQUIRED! inherit self inputs; # Supported systems, used for packages, apps, devShell and multiple other definitions. Defaults to `flake-utils.lib.defaultSystems`. @@ -76,6 +77,7 @@ in flake-utils-plus.lib.systemFlake { sharedOverlays = [ nur.overlay ]; # Nixpkgs flake reference to be used in the configuration. + # Autogenerated from `inputs` by default. channels..input = nixpkgs; # Channel specific config options. @@ -98,7 +100,7 @@ in flake-utils-plus.lib.systemFlake { hostDefaults.system = "x86_64-linux"; # Default modules to be passed to all hosts. - hostDefaults.modules = [ utils.nixosModules.saneFlakeDefaults ]; + hostDefaults.modules = [ ./module.nix ./module2 ]; # Reference to `channels..*`, defines default channel to be used by hosts. Defaults to "nixpkgs". hostDefaults.channelName = "unstable"; @@ -135,29 +137,32 @@ in flake-utils-plus.lib.systemFlake { ############################# - ### flake output builders ### + ### flake outputs builder ### ############################# - # Evaluates to `packages..coreutils = .coreutils`. - packagesBuilder = channels: { inherit (channels.unstable) coreutils; }; - - # Evaluates to `defaultPackage..neovim = .neovim`. - defaultPackageBuilder = channels: channels.nixpkgs.neovim; - # Evaluates to `apps..custom-neovim = utils.lib.mkApp { drv = ...; exePath = ...; };`. - appsBuilder = channels: with channels.nixpkgs; { - custom-neovim = mkApp { - drv = fancy-neovim; - exePath = "/bin/nvim"; + outputsBuilder = channels: { + # Evaluates to `apps..custom-neovim = utils.lib.mkApp { drv = ...; exePath = ...; };`. + apps = { + custom-neovim = mkApp { + drv = fancy-neovim; + exePath = "/bin/nvim"; + }; }; + + # Evaluates to `packages..coreutils = .package-from-overlays`. + packages = { inherit (channels.unstable) package-from-overlays; }; + + # Evaluates to `apps..firefox = utils.lib.mkApp { drv = ...; };`. + defaultApp = mkApp { drv = channels.nixpkgs.firefox }; + + # Evaluates to `defaultPackage..neovim = .neovim`. + defaultPackage = channels.nixpkgs.neovim; + + # Evaluates to `devShell. = .mkShell { name = "devShell"; };`. + devShell = channels.nixpkgs.mkShell { name = "devShell"; }; }; - # Evaluates to `apps..firefox = utils.lib.mkApp { drv = ...; };`. - defaultAppBuilder = channels: mkApp { drv = channels.nixpkgs.firefox; }; - - # Evaluates to `devShell. = .mkShell { name = "devShell"; };`. - devShellBuilder = channels: channels.nixpkgs.mkShell { name = "devShell"; }; - ######################################################### ### All other properties are passed down to the flake ### @@ -170,4 +175,3 @@ in flake-utils-plus.lib.systemFlake { } ``` - diff --git a/examples/exporters/flake.nix b/examples/exporters/flake.nix index 3c382c5c..5168505b 100644 --- a/examples/exporters/flake.nix +++ b/examples/exporters/flake.nix @@ -14,12 +14,12 @@ utils.lib.systemFlake { inherit self inputs; - # explicitly add overlaysBuilder - channels.nixpkgs.overlaysBuilder = arg: [ - (final: prev: { inherit coreutils; }) + # Channel specific overlays. Overlays `coreutils` from `unstable` channel. + channels.nixpkgs.overlaysBuilder = channels: [ + (final: prev: { inherit (channels.unstable) coreutils; }) ]; - # propagates to channels.nixpkgs.overlaysBuilder + # Propagates to channels..overlaysBuilder sharedOverlays = [ self.overlay ]; @@ -46,4 +46,3 @@ }; } - diff --git a/examples/minimal-multichannel/flake.nix b/examples/minimal-multichannel/flake.nix index a459c32a..554694ae 100644 --- a/examples/minimal-multichannel/flake.nix +++ b/examples/minimal-multichannel/flake.nix @@ -14,7 +14,7 @@ # Channel definitions. # Channels are automatically generated from nixpkgs inputs - # e.g the inputs which contain `legacyPackages` + # e.g the inputs which contain `legacyPackages` attribute are used. channelsConfig.allowUnfree = true; @@ -44,4 +44,3 @@ }; } - From 55d74737b3a87332972dc147ca6d464cf4852c7b Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Fri, 16 Jul 2021 18:13:55 +0300 Subject: [PATCH 61/90] Update README.md Co-authored-by: Mihai Fufezan <36706276+fufexan@users.noreply.github.com> --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ff5dd1bc..8e6a5d48 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ FUP provides a few main features (visible from `flake.nix`): - `nix.generateRegistryFromInputs` - Generates `nix.registry` from flake `inputs`. - `lib.mkFlake { ... }` - Generates a flake using FUP magic. -- `lib.exportModules [ ./a.nix ./b.nix ]` - Generates module attribute which look like this `{ a = import ./a.nix; b = import ./b.nix; }`. -- `lib.exportOverlays channels` - Exports all overlays from channels as an appropriately namespaced attribute set. Users can instantiate with their nixpkgs version. -- `lib.outputsBuilder.packages channels pkgs` - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. +- [`lib.exportModules [ ./a.nix ./b.nix ]`](./lib/exportModules.nix) - Generates module attribute which look like this `{ a = import ./a.nix; b = import ./b.nix; }`. +- [`lib.exportOverlays channels`](./lib/exportOverlays.nix) - Exports all overlays from channels as an appropriately namespaced attribute set. Users can instantiate with their nixpkgs version. +- [`lib.outputsBuilder.packages channels pkgs`](./lib/outputsBuilder.nix) - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. # How to use # From 0bd24483cc84ff2c1bce6c714de2b819eab1a845 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Thu, 15 Jul 2021 00:00:56 +0300 Subject: [PATCH 62/90] Fix Github Actions --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cc827414..790f8277 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,7 +13,7 @@ jobs: - uses: cachix/install-nix-action@v13 with: nix_path: nixpkgs=channel:nixos-unstable - install_url: https://github.com/numtide/nix-flakes-installer/releases/download/nix-3.0pre20201007_5257a25/install + install_url: https://github.com/numtide/nix-unstable-installer/releases/download/nix-2.4pre20210604_8e6ee1b/install extra_nix_config: experimental-features = nix-command flakes # Quick eval From 90c45a9cbf455e6192db3cb34814465f813cbef6 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 18 Jul 2021 22:29:14 +0300 Subject: [PATCH 63/90] Fix build scripts --- devShell.nix | 14 ++++++-------- .../modules/sharedConfigurationBetweenHosts.nix | 4 ---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/devShell.nix b/devShell.nix index f58a2259..0c4eb8f4 100644 --- a/devShell.nix +++ b/devShell.nix @@ -25,11 +25,10 @@ let help = "Checks ${name} testcases"; command = '' set -e + echo -e "\n\n##### Building ${name}\n" cd $DEVSHELL_ROOT/tests/${name} - nix flake lock --update-input utils - nix flake show "$@" - nix flake check "$@" - git rm -f flake.lock + nix flake show --no-write-lock-file "$@" + nix flake check --no-write-lock-file "$@" ''; }; @@ -37,11 +36,10 @@ let name = "build-${example}-${host}"; command = '' set -e + echo -e "\n\n##### Building ${example}-${host}\n" cd $DEVSHELL_ROOT/examples/${example} - nix flake lock --update-input utils - nix flake show "$@" - nix build .#nixosConfigurations.${host}.config.system.build.toplevel --dry-run "$@" - git rm -f flake.lock + nix flake show --no-write-lock-file "$@" + nix build .#nixosConfigurations.${host}.config.system.build.toplevel --no-write-lock-file "$@" ''; }; diff --git a/examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix b/examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix index 7f6a0e3f..55dcb964 100644 --- a/examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix +++ b/examples/home-manager+nur+neovim/modules/sharedConfigurationBetweenHosts.nix @@ -4,8 +4,4 @@ home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; - environment.systemPackages = with pkgs; [ - neovim-developer - ]; - } From 05478f0b72c6b00f5498eb1db0f4fad87dbe04a8 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 18 Jul 2021 22:33:25 +0300 Subject: [PATCH 64/90] Post rebase fixes --- devShell.nix | 2 +- examples/exporters/flake.nix | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/devShell.nix b/devShell.nix index 0c4eb8f4..0a4076ff 100644 --- a/devShell.nix +++ b/devShell.nix @@ -39,7 +39,7 @@ let echo -e "\n\n##### Building ${example}-${host}\n" cd $DEVSHELL_ROOT/examples/${example} nix flake show --no-write-lock-file "$@" - nix build .#nixosConfigurations.${host}.config.system.build.toplevel --no-write-lock-file "$@" + nix build .#nixosConfigurations.${host}.config.system.build.toplevel --no-write-lock-file --no-link "$@" ''; }; diff --git a/examples/exporters/flake.nix b/examples/exporters/flake.nix index 5168505b..6c8b480f 100644 --- a/examples/exporters/flake.nix +++ b/examples/exporters/flake.nix @@ -2,12 +2,13 @@ description = "FUP exporters demo"; inputs = { - nixpkgs.url = github:nixos/nixpkgs/nixos-unstable-small; + nixpkgs.url = github:nixos/nixpkgs/release-21.05; + unstable.url = github:nixos/nixpkgs/nixos-unstable-small; utils.url = path:../../; }; - outputs = inputs@{ self, nixpkgs, utils }: + outputs = inputs@{ self, nixpkgs, utils, ... }: let inherit (utils.lib.exporters) internalOverlays fromOverlays modulesFromList; in @@ -16,7 +17,7 @@ # Channel specific overlays. Overlays `coreutils` from `unstable` channel. channels.nixpkgs.overlaysBuilder = channels: [ - (final: prev: { inherit (channels.unstable) coreutils; }) + (final: prev: { inherit (channels.unstable) ranger; }) ]; # Propagates to channels..overlaysBuilder From be7b62899de17b3ced98e8e758a7b7cba151fcd5 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 18 Jul 2021 22:37:02 +0300 Subject: [PATCH 65/90] Post rebase fixes --- examples/minimal-multichannel/flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/minimal-multichannel/flake.nix b/examples/minimal-multichannel/flake.nix index 554694ae..ac58a02d 100644 --- a/examples/minimal-multichannel/flake.nix +++ b/examples/minimal-multichannel/flake.nix @@ -8,7 +8,7 @@ }; - outputs = inputs@{ self, nixpkgs, unstable, utils, home-manager }: + outputs = inputs@{ self, nixpkgs, unstable, utils }: utils.lib.systemFlake { inherit self inputs; From 1675f4605fbfd2813926cd2f0552644d9218e753 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Thu, 15 Jul 2021 00:36:59 +0300 Subject: [PATCH 66/90] move functions to lib/internal-functions.nix --- ...nternalOverlays.nix => exportChannels.nix} | 0 ...{modulesFromList.nix => exportModules.nix} | 40 +++------ lib/{fromOverlays.nix => exportOverlays.nix} | 8 +- lib/internal-functions.nix | 90 +++++++++++++++++++ 4 files changed, 107 insertions(+), 31 deletions(-) rename lib/{internalOverlays.nix => exportChannels.nix} (100%) rename lib/{modulesFromList.nix => exportModules.nix} (67%) rename lib/{fromOverlays.nix => exportOverlays.nix} (94%) create mode 100644 lib/internal-functions.nix diff --git a/lib/internalOverlays.nix b/lib/exportChannels.nix similarity index 100% rename from lib/internalOverlays.nix rename to lib/exportChannels.nix diff --git a/lib/modulesFromList.nix b/lib/exportModules.nix similarity index 67% rename from lib/modulesFromList.nix rename to lib/exportModules.nix index 07d467bd..0bc5a949 100644 --- a/lib/modulesFromList.nix +++ b/lib/exportModules.nix @@ -1,9 +1,10 @@ -{ flake-utils-plus }: -let +{ fup }: - modulesFromListExporter = args: +with fup; +let + exportModules = args: /** - Synopsis: modulesFromListExporter _paths or modules_ + Synopsis: exportModules _paths or modules_ paths: [ ] @@ -21,35 +22,20 @@ let **/ - let - - removeSuffix = suffix: str: - let - sufLen = builtins.stringLength suffix; - sLen = builtins.stringLength str; - in - if sufLen <= sLen && suffix == builtins.substring (sLen - sufLen) sufLen str then - builtins.substring 0 (sLen - sufLen) str - else - str; - - genAttrs' = func: values: builtins.listToAttrs (map func values); - - hasFileAttr = o: builtins.hasAttr "_file" o; - peek = f: f (builtins.functionArgs f); - - in - genAttrs' (arg: - # a regular path to be imported - if builtins.isPath arg then + # a regular file to be imported + if pathIsRegularFile arg then { name = removeSuffix ".nix" (baseNameOf arg); value = import arg; } + # a directory to be recursively imported + else if pathIsDirectory arg then + rakeLeaves arg + # a module function with a _file attr else if ((builtins.isFunction arg) && (hasFileAttr (peek arg))) then { @@ -79,10 +65,10 @@ let # panic: something else else builtins.throw '' - either pass a path or a module with _file key to modulesFromListExporter: ${builtins.trace arg "."} + either pass a path or a module with _file key to exportModules: ${builtins.trace arg "."} '' ) args; in -modulesFromListExporter +exportModules diff --git a/lib/fromOverlays.nix b/lib/exportOverlays.nix similarity index 94% rename from lib/fromOverlays.nix rename to lib/exportOverlays.nix index 3fd85f06..f0c705f4 100644 --- a/lib/fromOverlays.nix +++ b/lib/exportOverlays.nix @@ -1,11 +1,11 @@ { flake-utils-plus }: let - packagesFromOverlaysBuilderConstructor = overlays: + packagesFromOverlaysBuilder = overlays: let # overlays: self.overlays - packagesFromOverlaysBuilder = channels: + packagesFromOverlays = channels: /** Synopsis: packagesFromOverlaysBuilder _channels_ @@ -85,7 +85,7 @@ let filterPackages system (flattenTree exportPackages); in - packagesFromOverlaysBuilder; + packagesFromOverlays; in -packagesFromOverlaysBuilderConstructor +packagesFromOverlaysBuilder diff --git a/lib/internal-functions.nix b/lib/internal-functions.nix new file mode 100644 index 00000000..5b6c6296 --- /dev/null +++ b/lib/internal-functions.nix @@ -0,0 +1,90 @@ +{ + filterAttrs = pred: set: + listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); + + /* Generate an attribute set by mapping a function over a list of + attribute names. + + Example: + genAttrs [ "foo" "bar" ] (name: "x_" + name) + => { foo = "x_foo"; bar = "x_bar"; } + */ + genAttrs' = func: values: builtins.listToAttrs (map func values); + + hasFileAttr = o: builtins.hasAttr "_file" o; + + # Definition in nixpkgs + hasSuffix = + # Suffix to check for + suffix: + # Input string + content: + let + lenContent = stringLength content; + lenSuffix = stringLength suffix; + in lenContent >= lenSuffix && + substring (lenContent - lenSuffix) lenContent content == suffix; + + # Definition in nixpkgs + mapAttrs' = f: set: + listToAttrs (map (attr: f attr set.${attr}) (attrNames set)); + + /* Partition string s based on sep + + Example: + partitionString "," "nix,json,yaml" + => [ "nix" "json" "yaml" ] + */ + partitionString = sep: s: + filter (v: isString v) (split "${sep}" s); + + # Returns true if the path exists and is a directory, false otherwise + pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false; + + # Returns true if the path exists and is a regular file, false otherwise + pathIsRegularFile = p: if builtins.pathExists p then (pathType p) == "regular" else false; + + # Returns the type of a path: regular (for file), symlink, or directory + pathType = p: getAttr (baseNameOf p) (readDir (dirOf p)); + + peek = f: f (builtins.functionArgs f); + + removeSuffix = suffix: str: + let + sufLen = builtins.stringLength suffix; + sLen = builtins.stringLength str; + in + if sufLen <= sLen && suffix == builtins.substring (sLen - sufLen) sufLen str then + builtins.substring 0 (sLen - sufLen) str + else + str; + + rakeLeaves = + dirPath: + let + seive = file: type: + # Only rake `.nix` files or directories + (type == "regular" && hasSuffix ".nix" file) || (type == "directory") + ; + + collect = file: type: { + name = removeSuffix ".nix" file; + value = + let + path = dirPath + "/${file}"; + in + if (type == "regular") + || (type == "directory" && builtins.pathExists (path + "/default.nix")) + then path + # recurse on directories that don't contain a `default.nix` + else rakeLeaves path; + }; + + files = filterAttrs seive (builtins.readDir dirPath); + in + filterAttrs (n: v: v != { }) (mapAttrs' collect files); + + reverseList = xs: + let l = length xs; in genList (n: elemAt xs (l - n - 1)) l; + +} From f53affea95cf224c78d6191e3e09ea6955a44426 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 17 Jul 2021 15:09:49 +0300 Subject: [PATCH 67/90] flake.nix: change functions to new names --- flake.nix | 21 ++++++++++++------- lib/exportModules.nix | 12 +++++++++-- ...{exportChannels.nix => exportPackages.nix} | 0 lib/internal-functions.nix | 3 ++- lib/{systemFlake.nix => mkFlake.nix} | 18 +++++++--------- 5 files changed, 34 insertions(+), 20 deletions(-) rename lib/{exportChannels.nix => exportPackages.nix} (100%) rename lib/{systemFlake.nix => mkFlake.nix} (95%) diff --git a/flake.nix b/flake.nix index c7509666..ed347451 100644 --- a/flake.nix +++ b/flake.nix @@ -8,11 +8,18 @@ inherit (builtins) isList isAttrs mapAttrs; fupArgs = { flake-utils-plus = self; }; - systemFlake = import ./lib/systemFlake.nix fupArgs; - modulesFromList = import ./lib/modulesFromList.nix fupArgs; - fromOverlays = import ./lib/fromOverlays.nix fupArgs; - internalOverlays = import ./lib/internalOverlays.nix fupArgs; + mkFlake = import ./lib/mkFlake.nix fupArgs; + exportModules = import ./lib/exportModules.nix fupArgs; + exportOverlays = import ./lib/exportOverlays.nix fupArgs; + exportPackages = import ./lib/exportPackages.nix fupArgs; + internal-functions = import ./lib/internal-functions.nix; overlay = import ./lib/overlay.nix; + + # Deprecated names of the above + systemFlake = mkFlake; + modulesFromList = exportModules; + fromOverlays = exportOverlays; + internalOverlays = exportPackages; in rec { inherit overlay; @@ -22,10 +29,10 @@ devShell.x86_64-linux = import ./devShell.nix { system = "x86_64-linux"; }; - lib = flake-utils.lib // { - # modulesFromList is deprecated, will be removed in future releases - inherit systemFlake modulesFromList; + lib = flake-utils.lib // internal-functions // { + inherit mkFlake exportModules exportOverlays exportPackages; + # Deprecated - should use top-level functions instead exporters = { inherit modulesFromList fromOverlays internalOverlays; }; diff --git a/lib/exportModules.nix b/lib/exportModules.nix index 0bc5a949..7a4043d4 100644 --- a/lib/exportModules.nix +++ b/lib/exportModules.nix @@ -1,7 +1,15 @@ -{ fup }: +{ flake-utils-plus }: -with fup; let + inherit (flake-utils-plus.lib) + genAttrs' + hasFileAttr + pathIsDirectory + pathIsRegularFile + peek + rakeLeaves + removeSuffix + ; exportModules = args: /** Synopsis: exportModules _paths or modules_ diff --git a/lib/exportChannels.nix b/lib/exportPackages.nix similarity index 100% rename from lib/exportChannels.nix rename to lib/exportPackages.nix diff --git a/lib/internal-functions.nix b/lib/internal-functions.nix index 5b6c6296..a6a76f45 100644 --- a/lib/internal-functions.nix +++ b/lib/internal-functions.nix @@ -1,4 +1,5 @@ -{ +with builtins; +rec { filterAttrs = pred: set: listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); diff --git a/lib/systemFlake.nix b/lib/mkFlake.nix similarity index 95% rename from lib/systemFlake.nix rename to lib/mkFlake.nix index a4fca03e..d4c6c65b 100644 --- a/lib/systemFlake.nix +++ b/lib/mkFlake.nix @@ -31,7 +31,14 @@ }@args: let - inherit (flake-utils-plus.lib) eachSystem patchChannel mergeAny; + inherit (flake-utils-plus.lib) + eachSystem + filterAttrs + mergeAny + partitionString + patchChannel + reverseList + ; inherit (builtins) attrNames attrValues @@ -51,15 +58,6 @@ let tail ; - filterAttrs = pred: set: - listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); - - reverseList = xs: - let l = length xs; in genList (n: elemAt xs (l - n - 1)) l; - - partitionString = sep: s: - filter (v: isString v) (split "${sep}" s); - srcs = filterAttrs (_: value: !value ? outputs) inputs; From a9c80ba18a54301d2c89309fcf429eadbbaa869f Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 19 Jul 2021 15:09:49 +0300 Subject: [PATCH 68/90] flake.nix: move internal-functions to own attrset --- flake.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index ed347451..fbe1e78a 100644 --- a/flake.nix +++ b/flake.nix @@ -29,7 +29,8 @@ devShell.x86_64-linux = import ./devShell.nix { system = "x86_64-linux"; }; - lib = flake-utils.lib // internal-functions // { + lib = flake-utils.lib // { + inherit (internal-functions) rakeLeaves; inherit mkFlake exportModules exportOverlays exportPackages; # Deprecated - should use top-level functions instead @@ -37,6 +38,9 @@ inherit modulesFromList fromOverlays internalOverlays; }; + # DO NOT USE - subject to change without notice + internal = internal-functions; + repl = ./lib/repl.nix; # merge nested attribute sets and lists From d5cd10dfb28f1a142e8c7f4cd2245e9c9527edc6 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 19 Jul 2021 16:17:09 +0300 Subject: [PATCH 69/90] properly call internal lib --- flake.nix | 2 +- lib/exportModules.nix | 2 +- lib/mkFlake.nix | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index fbe1e78a..7248d5ba 100644 --- a/flake.nix +++ b/flake.nix @@ -30,13 +30,13 @@ devShell.x86_64-linux = import ./devShell.nix { system = "x86_64-linux"; }; lib = flake-utils.lib // { - inherit (internal-functions) rakeLeaves; inherit mkFlake exportModules exportOverlays exportPackages; # Deprecated - should use top-level functions instead exporters = { inherit modulesFromList fromOverlays internalOverlays; }; + inherit systemFlake; # DO NOT USE - subject to change without notice internal = internal-functions; diff --git a/lib/exportModules.nix b/lib/exportModules.nix index 7a4043d4..cc6ecb12 100644 --- a/lib/exportModules.nix +++ b/lib/exportModules.nix @@ -1,7 +1,7 @@ { flake-utils-plus }: let - inherit (flake-utils-plus.lib) + inherit (flake-utils-plus.lib.internal) genAttrs' hasFileAttr pathIsDirectory diff --git a/lib/mkFlake.nix b/lib/mkFlake.nix index d4c6c65b..faaac437 100644 --- a/lib/mkFlake.nix +++ b/lib/mkFlake.nix @@ -33,10 +33,12 @@ let inherit (flake-utils-plus.lib) eachSystem - filterAttrs mergeAny - partitionString patchChannel + ; + inherit (flake-utils-plus.lib.internal) + filterAttrs + partitionString reverseList ; inherit (builtins) From 22256e8560655673d36f97fcbbda55d21edcf20a Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 19 Jul 2021 16:17:21 +0300 Subject: [PATCH 70/90] fix formatting --- lib/internal-functions.nix | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/internal-functions.nix b/lib/internal-functions.nix index a6a76f45..e4901302 100644 --- a/lib/internal-functions.nix +++ b/lib/internal-functions.nix @@ -4,11 +4,11 @@ rec { listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); /* Generate an attribute set by mapping a function over a list of - attribute names. + attribute names. - Example: - genAttrs [ "foo" "bar" ] (name: "x_" + name) - => { foo = "x_foo"; bar = "x_bar"; } + Example: + genAttrs [ "foo" "bar" ] (name: "x_" + name) + => { foo = "x_foo"; bar = "x_bar"; } */ genAttrs' = func: values: builtins.listToAttrs (map func values); @@ -23,8 +23,9 @@ rec { let lenContent = stringLength content; lenSuffix = stringLength suffix; - in lenContent >= lenSuffix && - substring (lenContent - lenSuffix) lenContent content == suffix; + in + lenContent >= lenSuffix && + substring (lenContent - lenSuffix) lenContent content == suffix; # Definition in nixpkgs mapAttrs' = f: set: @@ -32,9 +33,9 @@ rec { /* Partition string s based on sep - Example: - partitionString "," "nix,json,yaml" - => [ "nix" "json" "yaml" ] + Example: + partitionString "," "nix,json,yaml" + => [ "nix" "json" "yaml" ] */ partitionString = sep: s: filter (v: isString v) (split "${sep}" s); From 0f7b21670bac7ad08fa1306cd3cf9709f3de021a Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Tue, 20 Jul 2021 20:46:38 +0300 Subject: [PATCH 71/90] rename export{Overlays,Packages} --- flake.nix | 4 +- lib/exportOverlays.nix | 174 ++++++++++++++++++++++------------------- lib/exportPackages.nix | 164 +++++++++++++++++++------------------- 3 files changed, 176 insertions(+), 166 deletions(-) diff --git a/flake.nix b/flake.nix index 7248d5ba..e7fc762b 100644 --- a/flake.nix +++ b/flake.nix @@ -18,8 +18,8 @@ # Deprecated names of the above systemFlake = mkFlake; modulesFromList = exportModules; - fromOverlays = exportOverlays; - internalOverlays = exportPackages; + fromOverlays = exportPackages; + internalOverlays = exportOverlays; in rec { inherit overlay; diff --git a/lib/exportOverlays.nix b/lib/exportOverlays.nix index f0c705f4..9d4637c2 100644 --- a/lib/exportOverlays.nix +++ b/lib/exportOverlays.nix @@ -1,91 +1,103 @@ { flake-utils-plus }: let - packagesFromOverlaysBuilder = overlays: - let - # overlays: self.overlays - - packagesFromOverlays = channels: - /** - Synopsis: packagesFromOverlaysBuilder _channels_ - - channels: builder `channels` argument - - Returns valid packges that have been defined within an overlay so they - can be shared via _self.packages_ with the world. This is especially useful - over sharing one's art via _self.overlays_ in case you have a binary cache - running from which third parties could benefit. - - Steps: - 1. merge all channels into one nixpkgs attribute set - 2. collect all overlays' packages' keys into one flat list - 3. pick out each package from the nixpkgs set into one packages set - $. flatten package set and filter out disallowed packages - by flake check requirements - - example input and output: - ``` - overlays = { - "unstable/firefox" = prev: final: { - firefox = prev.override { privacySupport = true; }; - }; - } - - self.packages = { - firefox = *firefox derivation with privacySupport*; - } - ``` - - **/ - let - - inherit (flake-utils-plus.lib) flattenTree filterPackages; - inherit (builtins) foldl' attrNames mapAttrs listToAttrs - attrValues concatStringSep concatMap any head; - nameValuePair = name: value: { inherit name value; }; - - flattenedPackages = - # merge all channels into one package set - foldl' (a: b: a // b) { } (attrValues channels); - - # flatten all overlays' packages' keys into a single list - flattenedOverlaysNames = - let - allOverlays = attrValues overlays; - - overlayNamesList = overlay: - attrNames (overlay null null); - in - concatMap overlayNamesList allOverlays; - - # create list of single-attribute sets that contain each package - exportPackagesList = map - (name: - let - item = flattenedPackages.${name}; - exportItem = { ${name} = item; }; - in - if item ? type && item.type == "derivation" then - # if its a package export it - exportItem - else if item ? __dontExport && !item.__dontExport then - # if its a package sub-system, __dontExport has to be set to false to export - exportItem - else - { } - ) - flattenedOverlaysNames; + exportOverlays = { pkgs, inputs ? { } }: + /** + Synopsis: exportOverlays _{ pkgs, inputs }_ + + pkgs: self.pkgs + + inputs: flake inputs to sort out external overlays + + Overlays with an attribute named "__dontExport" will be filtered out. - # fold list into one attribute set - exportPackages = foldl' (lhs: rhs: lhs // rhs) { } exportPackagesList; + Returns an attribute set of all packages defined in an overlay by any channel + intended to be passed to be exported via _self.overlays_. This method of + sharing has the advantage over _self.packages_, that the user will instantiate + overlays with his proper nixpkgs version, and thereby significantly reduce their system's + closure as they avoid depending on entirely different nixpkgs versions dependency + trees. On the flip side, any caching that is set up for one's packages will essentially + be useless to users. - system = (head (attrValues channels)).system; + It can happen that an overlay is not compatible with the version of nixpkgs a user tries + to instantiate it. In order to provide users with a visual clue for which nixpkgs version + an overlay was originally created, we prefix the channle name: "/". + In the case of the unstable channel, this information is still of varying usefulness, + as effective cut dates can vary heavily between repositories. - in - # flatten nested sets with "/" delimiter then drop disallowed packages - filterPackages system (flattenTree exportPackages); + To ensure only overlays that originate from the flake are exported you can optionally pass + a set of flake inputs and any overlay which is taken from an input will be filtered out. + Optimally this would be done by detecting flake ownership of each overlay, but that is not + possible yet, so this is the next best workaround. + + Example: + + overlays = [ + "unstable/development" = final: prev: { }; + "nixos2009/chromium" = final: prev: { }; + "nixos2009/pythonPackages" = final: prev: { }; + ]; + + **/ + let + inherit (builtins) + attrNames + attrValues + concatMap + elem + filter + foldl' + head + listToAttrs + mapAttrs + ; + nameValuePair = name: value: { inherit name value; }; + + # just pull out one arch from the system-spaced pkgs to get access to channels + # overlays can be safely evaluated on any arch + channels = head (attrValues pkgs); + + pathStr = path: builtins.concatStringsSep "/" path; + + channelNames = attrNames channels; + overlayNames = overlay: attrNames (overlay null null); + + # get all overlays from inputs + inputOverlays = mapAttrs + (_: v: [ v.overlay or (_: _: { }) ] ++ attrValues v.overlays or { }) + (removeAttrs inputs [ "self" ]); + # use overlayNames as a way to identify overlays + flattenedInputOverlays = map overlayNames (foldl' (a: b: a ++ b) [ ] (attrValues inputOverlays)); + + extractAndNamespaceEachOverlay = channelName: overlay: + map + (overlayName: + nameValuePair + (pathStr [ channelName overlayName ]) + (final: prev: { + ${overlayName} = (overlay final prev).${overlayName}; + }) + ) + (overlayNames overlay); + + checkOverlay = overlay: + (!elem (overlayNames overlay) flattenedInputOverlays) + && (!elem "__dontExport" (overlayNames overlay)); + + filterOverlays = channel: filter checkOverlay channel.overlays; in - packagesFromOverlays; + listToAttrs ( + concatMap + (channelName: + concatMap + (overlay: + extractAndNamespaceEachOverlay channelName overlay + ) + (filterOverlays channels.${channelName}) + ) + channelNames + ); in -packagesFromOverlaysBuilder +exportOverlays diff --git a/lib/exportPackages.nix b/lib/exportPackages.nix index 3c2e9480..99785625 100644 --- a/lib/exportPackages.nix +++ b/lib/exportPackages.nix @@ -1,93 +1,91 @@ { flake-utils-plus }: let - overlaysFromChannelsExporter = { pkgs, inputs ? { } }: - /** - Synopsis: overlaysFromChannelsExporter _{ pkgs, inputs }_ - - pkgs: self.pkgs - - inputs: flake inputs to sort out external overlays - - Overlays with an attribute named "__dontExport" will be filtered out. - - Returns an attribute set of all packages defined in an overlay by any channel - intended to be passed to be exported via _self.overlays_. This method of - sharing has the advantage over _self.packages_, that the user will instantiate - overlays with his proper nixpkgs version, and thereby significantly reduce their system's - closure as they avoid depending on entirely different nixpkgs versions dependency - trees. On the flip side, any caching that is set up for one's packages will essentially - be useless to users. - - It can happen that an overlay is not compatible with the version of nixpkgs a user tries - to instantiate it. In order to provide users with a visual clue for which nixpkgs version - an overlay was originally created, we prefix the channle name: "/". - In the case of the unstable channel, this information is still of varying usefulness, - as effective cut dates can vary heavily between repositories. + exportPackagesBuilder = overlays: + let + # overlays: self.overlays + + exportPackages = channels: + /** + Synopsis: exportPackagesBuilder _channels_ + + channels: builder `channels` argument + + Returns valid packges that have been defined within an overlay so they + can be shared via _self.packages_ with the world. This is especially useful + over sharing one's art via _self.overlays_ in case you have a binary cache + running from which third parties could benefit. + + Steps: + 1. merge all channels into one nixpkgs attribute set + 2. collect all overlays' packages' keys into one flat list + 3. pick out each package from the nixpkgs set into one packages set + $. flatten package set and filter out disallowed packages - by flake check requirements + + example input and output: + ``` + overlays = { + "unstable/firefox" = prev: final: { + firefox = prev.override { privacySupport = true; }; + }; + } + + self.packages = { + firefox = *firefox derivation with privacySupport*; + } + ``` + + **/ + let + + inherit (flake-utils-plus.lib) flattenTree filterPackages; + inherit (builtins) foldl' attrNames mapAttrs listToAttrs + attrValues concatStringSep concatMap any head; + nameValuePair = name: value: { inherit name value; }; + + flattenedPackages = + # merge all channels into one package set + foldl' (a: b: a // b) { } (attrValues channels); + + # flatten all overlays' packages' keys into a single list + flattenedOverlaysNames = + let + allOverlays = attrValues overlays; + + overlayNamesList = overlay: + attrNames (overlay null null); + in + concatMap overlayNamesList allOverlays; + + # create list of single-attribute sets that contain each package + exportPackagesList = map + (name: + let + item = flattenedPackages.${name}; + exportItem = { ${name} = item; }; + in + if item ? type && item.type == "derivation" then + # if its a package export it + exportItem + else if item ? __dontExport && !item.__dontExport then + # if its a package sub-system, __dontExport has to be set to false to export + exportItem + else + { } + ) + flattenedOverlaysNames; - To ensure only overlays that originate from the flake are exported you can optionally pass - a set of flake inputs and any overlay which is taken from an input will be filtered out. - Optimally this would be done by detecting flake ownership of each overlay, but that is not - possible yet, so this is the next best workaround. + # fold list into one attribute set + exportPackages = foldl' (lhs: rhs: lhs // rhs) { } exportPackagesList; - Example: + system = (head (attrValues channels)).system; - overlays = [ - "unstable/development" = final: prev: { }; - "nixos2009/chromium" = final: prev: { }; - "nixos2009/pythonPackages" = final: prev: { }; - ]; - - **/ - let - inherit (builtins) mapAttrs foldl' filter head attrNames attrValues concatMap listToAttrs elem; - nameValuePair = name: value: { inherit name value; }; - - # just pull out one arch from the system-spaced pkgs to get access to channels - # overlays can be safely evaluated on any arch - channels = head (attrValues pkgs); - - pathStr = path: builtins.concatStringsSep "/" path; - - channelNames = attrNames channels; - overlayNames = overlay: attrNames (overlay null null); - - # get all overlays from inputs - inputOverlays = mapAttrs - (_: v: [ v.overlay or (_: _: { }) ] ++ attrValues v.overlays or { }) - (removeAttrs inputs [ "self" ]); - # use overlayNames as a way to identify overlays - flattenedInputOverlays = map overlayNames (foldl' (a: b: a ++ b) [ ] (attrValues inputOverlays)); - - extractAndNamespaceEachOverlay = channelName: overlay: - map - (overlayName: - nameValuePair - (pathStr [ channelName overlayName ]) - (final: prev: { - ${overlayName} = (overlay final prev).${overlayName}; - }) - ) - (overlayNames overlay); - - checkOverlay = overlay: - (!elem (overlayNames overlay) flattenedInputOverlays) - && (!elem "__dontExport" (overlayNames overlay)); - - filterOverlays = channel: filter checkOverlay channel.overlays; + in + # flatten nested sets with "/" delimiter then drop disallowed packages + filterPackages system (flattenTree exportPackages); in - listToAttrs ( - concatMap - (channelName: - concatMap - (overlay: - extractAndNamespaceEachOverlay channelName overlay - ) - (filterOverlays channels.${channelName}) - ) - channelNames - ); + exportPackages; in -overlaysFromChannelsExporter +exportPackagesBuilder From ea46e02fb86785d3c883d658b194d69799386673 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Tue, 20 Jul 2021 18:50:46 -0500 Subject: [PATCH 72/90] fix: exportModules can be a function or attrs check first, since the path check implementation (builtins.pathExists) expects a string coercible (function is not!) fixes: #85 --- lib/exportModules.nix | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/exportModules.nix b/lib/exportModules.nix index cc6ecb12..d6f09e30 100644 --- a/lib/exportModules.nix +++ b/lib/exportModules.nix @@ -33,19 +33,8 @@ let genAttrs' (arg: - # a regular file to be imported - if pathIsRegularFile arg then - { - name = removeSuffix ".nix" (baseNameOf arg); - value = import arg; - } - - # a directory to be recursively imported - else if pathIsDirectory arg then - rakeLeaves arg - # a module function with a _file attr - else if ((builtins.isFunction arg) && (hasFileAttr (peek arg))) then + if ((builtins.isFunction arg) && (hasFileAttr (peek arg))) then { name = removeSuffix ".toml" (removeSuffix ".nix" (baseNameOf (peek arg)._file)); value = arg; @@ -69,6 +58,16 @@ let builtins.throw '' simple module has no (required) _file argument key: ${builtins.trace arg "."} '' + # a regular file to be imported + else if pathIsRegularFile arg then + { + name = removeSuffix ".nix" (baseNameOf arg); + value = import arg; + } + + # a directory to be recursively imported + else if pathIsDirectory arg then + rakeLeaves arg # panic: something else else From 51a82925db31073bc4822c9b538a0a3ebf1134b2 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Fri, 23 Jul 2021 15:25:52 -0500 Subject: [PATCH 73/90] fix: reverse rakeLeaves implementation for exportModules exportModules was intended to receive a list of paths-to-modules or modules as arguments. `rakeLeaves` is usually called before passing the resulting modules to this function, flattened (digga's `flattenTree`) and stripped of their name (`builtins.attrValues`) given by `rakeLeaves`. `rakeLeaves` holds path types for its leaves. --- lib/exportModules.nix | 11 ++--------- lib/internal-functions.nix | 31 ------------------------------- 2 files changed, 2 insertions(+), 40 deletions(-) diff --git a/lib/exportModules.nix b/lib/exportModules.nix index d6f09e30..72021303 100644 --- a/lib/exportModules.nix +++ b/lib/exportModules.nix @@ -4,10 +4,7 @@ let inherit (flake-utils-plus.lib.internal) genAttrs' hasFileAttr - pathIsDirectory - pathIsRegularFile peek - rakeLeaves removeSuffix ; exportModules = args: @@ -58,17 +55,13 @@ let builtins.throw '' simple module has no (required) _file argument key: ${builtins.trace arg "."} '' - # a regular file to be imported - else if pathIsRegularFile arg then + # a regular path to be imported + else if builtins.isPath arg then { name = removeSuffix ".nix" (baseNameOf arg); value = import arg; } - # a directory to be recursively imported - else if pathIsDirectory arg then - rakeLeaves arg - # panic: something else else builtins.throw '' diff --git a/lib/internal-functions.nix b/lib/internal-functions.nix index e4901302..d4175417 100644 --- a/lib/internal-functions.nix +++ b/lib/internal-functions.nix @@ -40,12 +40,6 @@ rec { partitionString = sep: s: filter (v: isString v) (split "${sep}" s); - # Returns true if the path exists and is a directory, false otherwise - pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false; - - # Returns true if the path exists and is a regular file, false otherwise - pathIsRegularFile = p: if builtins.pathExists p then (pathType p) == "regular" else false; - # Returns the type of a path: regular (for file), symlink, or directory pathType = p: getAttr (baseNameOf p) (readDir (dirOf p)); @@ -61,31 +55,6 @@ rec { else str; - rakeLeaves = - dirPath: - let - seive = file: type: - # Only rake `.nix` files or directories - (type == "regular" && hasSuffix ".nix" file) || (type == "directory") - ; - - collect = file: type: { - name = removeSuffix ".nix" file; - value = - let - path = dirPath + "/${file}"; - in - if (type == "regular") - || (type == "directory" && builtins.pathExists (path + "/default.nix")) - then path - # recurse on directories that don't contain a `default.nix` - else rakeLeaves path; - }; - - files = filterAttrs seive (builtins.readDir dirPath); - in - filterAttrs (n: v: v != { }) (mapAttrs' collect files); - reverseList = xs: let l = length xs; in genList (n: elemAt xs (l - n - 1)) l; From a79a0b86e59dc087df6704f9b13b1ed951ef5c5f Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Fri, 13 Aug 2021 14:59:45 +0300 Subject: [PATCH 74/90] Fix modulesFromList deprecation --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index e7fc762b..a4b3ba78 100644 --- a/flake.nix +++ b/flake.nix @@ -36,7 +36,7 @@ exporters = { inherit modulesFromList fromOverlays internalOverlays; }; - inherit systemFlake; + inherit systemFlake modulesFromList; # DO NOT USE - subject to change without notice internal = internal-functions; From 3d108c952906bd4e0c5327f5e71613f3c0abdb0c Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Mon, 23 Aug 2021 02:13:57 +0300 Subject: [PATCH 75/90] Update devshell --- devShell.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/devShell.nix b/devShell.nix index 0a4076ff..3b0b9909 100644 --- a/devShell.nix +++ b/devShell.nix @@ -1,17 +1,17 @@ { system ? builtins.currentSystem }: let # nixpkgs / devshell is only used for development. Don't add it to the flake.lock. - nixpkgsGitRev = "246502ae2d5ca9def252abe0ce6363a0f08382a7"; - devshellGitRev = "1f4fb67b662b65fa7cfe696fc003fcc1e8f7cc36"; + nixpkgsGitRev = "82d05e980543e1703cbfd3b5ccd1fdcd4b0f1f00"; + devshellGitRev = "26f25a12265f030917358a9632cd600b51af1d97"; nixpkgsSrc = fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsGitRev}.tar.gz"; - sha256 = "sha256-cuCj8CfBrVlEYQM2jfD3psh2jV/sR5HACYkC74WR9KE="; + sha256 = "02yqgivv8kxksv7n6vmh22qxprlfjh4rfkgf98w46nssq5ahdb1q"; }; devshellSrc = fetchTarball { url = "https://github.com/numtide/devshell/archive/${devshellGitRev}.tar.gz"; - sha256 = "03258pq60nppq39571bjxqn75h3rn25bdlrx04k75v20n77xfs5c"; + sha256 = "sha256:0f6fph5gahm2bmzd399mba6b0h6wp6i1v3gryfmgwp0as7mwqpj7"; }; pkgs = import nixpkgsSrc { inherit system; }; From 6a7b7ffcbd1b7729a3e2720b33875e85355ad915 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Mon, 23 Aug 2021 02:23:42 +0300 Subject: [PATCH 76/90] Update flake-utils --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 54993f88..30331e89 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-utils": { "locked": { - "lastModified": 1623875721, - "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", + "lastModified": 1629481132, + "narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=", "owner": "numtide", "repo": "flake-utils", - "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772", + "rev": "997f7efcb746a9c140ce1f13c72263189225f482", "type": "github" }, "original": { From ebb41749abbcb0be3d5aafb812c0ccf9329ec0cf Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Mon, 23 Aug 2021 21:42:02 +0300 Subject: [PATCH 77/90] Update README.md --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 8e6a5d48..cfc6fdf6 100644 --- a/README.md +++ b/README.md @@ -11,19 +11,30 @@ The biggest design goal is to keep down the fluff. The library is meant to be ea # Features of the flake # -FUP provides a few main features (visible from `flake.nix`): - -- `nix.generateRegistryFromInputs` - Generates `nix.registry` from flake `inputs`. -- `lib.mkFlake { ... }` - Generates a flake using FUP magic. +Main flake-utils-plus features (Attributes visible from `flake.nix`): +- Extends [flake-utils](https://github.com/numtide/flake-utils). Everything exported by fu can be used from this flake. +- `lib.mkFlake { ... }` - Clean and pleasent to use flakes abstraction. + - Option `nix.generateRegistryFromInputs` - Generates `nix.registry` from flake `inputs`. + - Simple and clean support for multiple `nixpkgs` references. + - `nixpkgs` references patching. + - `channelsConfig` - Config applied to all `nixpkgs` references. + - `hostDefaults` - Default configuration shared between host definitions. + - `outputsBuilder` - Clean way to export packages/apps/etc. + - `sharedOverlays` - Overlays applied on all imported channels. - [`lib.exportModules [ ./a.nix ./b.nix ]`](./lib/exportModules.nix) - Generates module attribute which look like this `{ a = import ./a.nix; b = import ./b.nix; }`. - [`lib.exportOverlays channels`](./lib/exportOverlays.nix) - Exports all overlays from channels as an appropriately namespaced attribute set. Users can instantiate with their nixpkgs version. -- [`lib.outputsBuilder.packages channels pkgs`](./lib/outputsBuilder.nix) - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. +- [`lib.exportPackages self.overlays channels`](./lib/exportPackages.nix) - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. +- `pkgs.fup-repl` - Adds a kick-ass repl. Usage: + - `$ repl` - Loads your system repl into scope as well as `pkgs` and `lib` from `nixpkgs` input. + - `$ repl /path/to/flake.nix` - Same as above only that it loads specified flake. # How to use # -* [Using FUP to configure hosts with Home Manager, NUR and neovim](https://github.com/gytis-ivaskevicius/flake-utils-plus/blob/master/examples/home-manager+nur+neovim) +* [Example of using multiple channels](./examples/minimal-multichannel) + +* [Exporters usage example](./examples/exporters) -* [Example of using multiple channels](https://github.com/gytis-ivaskevicius/flake-utils-plus/blob/master/examples/minimal-multichannel) +* [Using FUP to configure hosts with Home Manager, NUR and neovim](./examples/home-manager+nur+neovim) ## Examples @@ -34,17 +45,6 @@ We recommend referring to people's examples below when setting up your system. - [Bobbbay Dotfiles](https://github.com/Bobbbay/dotfiles/blob/master/flake.nix) - [Charlotte Dotfiles](https://github.com/chvp/nixos-config/blob/master/flake.nix) -Looking to add a kick-ass repl to your config? Create and import something along these lines: -```nix -{ inputs, ... }: - -{ - environment.shellAliases = { - very-cool-nix-repl = "nix repl ${inputs.utils.lib.repl}"; - }; -} - -``` # Documentation @@ -149,16 +149,16 @@ in flake-utils-plus.lib.mkFlake { exePath = "/bin/nvim"; }; }; - + # Evaluates to `packages..coreutils = .package-from-overlays`. packages = { inherit (channels.unstable) package-from-overlays; }; - + # Evaluates to `apps..firefox = utils.lib.mkApp { drv = ...; };`. defaultApp = mkApp { drv = channels.nixpkgs.firefox }; - + # Evaluates to `defaultPackage..neovim = .neovim`. defaultPackage = channels.nixpkgs.neovim; - + # Evaluates to `devShell. = .mkShell { name = "devShell"; };`. devShell = channels.nixpkgs.mkShell { name = "devShell"; }; }; From ecfd19c7b9afef7f681bdd2663f107622a64e3e0 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Mon, 23 Aug 2021 21:58:05 +0300 Subject: [PATCH 78/90] Tweak repl implementation --- README.md | 2 +- lib/repl.nix | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cfc6fdf6..542a03c1 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Main flake-utils-plus features (Attributes visible from `flake.nix`): - [`lib.exportModules [ ./a.nix ./b.nix ]`](./lib/exportModules.nix) - Generates module attribute which look like this `{ a = import ./a.nix; b = import ./b.nix; }`. - [`lib.exportOverlays channels`](./lib/exportOverlays.nix) - Exports all overlays from channels as an appropriately namespaced attribute set. Users can instantiate with their nixpkgs version. - [`lib.exportPackages self.overlays channels`](./lib/exportPackages.nix) - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. -- `pkgs.fup-repl` - Adds a kick-ass repl. Usage: +- `pkgs.fup-repl` - A package that adds a kick-ass repl. Usage: - `$ repl` - Loads your system repl into scope as well as `pkgs` and `lib` from `nixpkgs` input. - `$ repl /path/to/flake.nix` - Same as above only that it loads specified flake. diff --git a/lib/repl.nix b/lib/repl.nix index 404eb708..a46347a4 100644 --- a/lib/repl.nix +++ b/lib/repl.nix @@ -1,8 +1,8 @@ -{ flakePath ? null, hostnamePath ? "/etc/hostname" }: +{ flakePath ? null, hostnamePath ? "/etc/hostname", registryPath ? /etc/nix/registry.json }: let inherit (builtins) getFlake head match currentSystem readFile pathExists filter fromJSON; - registryPath = /etc/nix/registry.json; + selfFlake = if pathExists registryPath then filter (it: it.from.id == "self") (fromJSON (readFile registryPath)).flakes @@ -16,7 +16,7 @@ let else "/etc/nixos"); flake = if pathExists flakePath' then getFlake flakePath' else { }; - hostname = if pathExists hostnamePath then head (match "([a-zA-Z0-9]+)\n" (readFile hostnamePath)) else ""; + hostname = if pathExists hostnamePath then head (match "([a-zA-Z0-9\\-]+)\n" (readFile hostnamePath)) else ""; nixpkgsFromInputsPath = flake.inputs.nixpkgs.outPath or ""; nixpkgs = flake.pkgs.${currentSystem}.nixpkgs or (if nixpkgsFromInputsPath != "" then import nixpkgsFromInputsPath { } else { }); @@ -29,4 +29,4 @@ in // (flake.nixosConfigurations or { }) // flake.nixosConfigurations.${hostname} or { } // nixpkgsOutput - // { loadFlake = path: getFlake (toString path); } + // { getFlake = path: getFlake (toString path); } From 8a855587f0f435e3e812061f5b97e74bdd9d419e Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Tue, 24 Aug 2021 12:06:44 +0300 Subject: [PATCH 79/90] Update README.md Co-authored-by: Mihai Fufezan <36706276+fufexan@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 542a03c1..53283489 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The biggest design goal is to keep down the fluff. The library is meant to be ea Main flake-utils-plus features (Attributes visible from `flake.nix`): - Extends [flake-utils](https://github.com/numtide/flake-utils). Everything exported by fu can be used from this flake. -- `lib.mkFlake { ... }` - Clean and pleasent to use flakes abstraction. +- `lib.mkFlake { ... }` - Clean and pleasant to use flakes abstraction. - Option `nix.generateRegistryFromInputs` - Generates `nix.registry` from flake `inputs`. - Simple and clean support for multiple `nixpkgs` references. - `nixpkgs` references patching. From 28ad5a2877f670b6b799c31a8974eed404df37ad Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Tue, 24 Aug 2021 12:06:57 +0300 Subject: [PATCH 80/90] Update README.md Co-authored-by: Mihai Fufezan <36706276+fufexan@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53283489..e3ff5404 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Main flake-utils-plus features (Attributes visible from `flake.nix`): - [`lib.exportPackages self.overlays channels`](./lib/exportPackages.nix) - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. - `pkgs.fup-repl` - A package that adds a kick-ass repl. Usage: - `$ repl` - Loads your system repl into scope as well as `pkgs` and `lib` from `nixpkgs` input. - - `$ repl /path/to/flake.nix` - Same as above only that it loads specified flake. + - `$ repl /path/to/flake.nix` - Same as above but loads the specified flake. # How to use # From e1eddbd4b1b5e053f29ff7a86f445b0899fba892 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Tue, 24 Aug 2021 12:36:39 +0300 Subject: [PATCH 81/90] Update channels selection filter logic --- lib/mkFlake.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/mkFlake.nix b/lib/mkFlake.nix index faaac437..bce71276 100644 --- a/lib/mkFlake.nix +++ b/lib/mkFlake.nix @@ -42,6 +42,7 @@ let reverseList ; inherit (builtins) + pathExists attrNames attrValues concatMap @@ -222,7 +223,9 @@ mergeAny otherArguments ( filterAttrs = pred: set: listToAttrs (concatMap (name: let value = set.${name}; in if pred name value then [ ({ inherit name value; }) ] else [ ]) (attrNames set)); - channelFlakes = filterAttrs (_: value: value ? legacyPackages) inputs; + # Little hack, we make sure that `legacyPackages` contains `nix` to make sure that we are dealing with nixpkgs. + # For some odd reason `devshell` contains `legacyPackages` out put as well + channelFlakes = filterAttrs (_: value: value.legacyPackages.x86_64-linux ? nix) inputs; channelsFromFlakes = mapAttrs (name: input: { inherit input; }) channelFlakes; importChannel = name: value: (import (patchChannel system value.input (value.patches or [ ])) { From cb44a3f0e88655b4976a033c5b561b5bd268fed1 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Tue, 24 Aug 2021 12:48:26 +0300 Subject: [PATCH 82/90] Update channels selection filter logic --- lib/mkFlake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mkFlake.nix b/lib/mkFlake.nix index bce71276..885cd1c5 100644 --- a/lib/mkFlake.nix +++ b/lib/mkFlake.nix @@ -225,7 +225,7 @@ mergeAny otherArguments ( # Little hack, we make sure that `legacyPackages` contains `nix` to make sure that we are dealing with nixpkgs. # For some odd reason `devshell` contains `legacyPackages` out put as well - channelFlakes = filterAttrs (_: value: value.legacyPackages.x86_64-linux ? nix) inputs; + channelFlakes = filterAttrs (_: value: value ? legacyPackages && value.legacyPackages.x86_64-linux ? nix) inputs; channelsFromFlakes = mapAttrs (name: input: { inherit input; }) channelFlakes; importChannel = name: value: (import (patchChannel system value.input (value.patches or [ ])) { From daab9cb03ad2343a8f3b4dbd75eddf9f78f80716 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Tue, 24 Aug 2021 21:24:00 +0300 Subject: [PATCH 83/90] Remove nix_path option from workflow file --- .github/workflows/ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 790f8277..abaeba06 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,7 +12,6 @@ jobs: - uses: actions/checkout@v2.3.4 - uses: cachix/install-nix-action@v13 with: - nix_path: nixpkgs=channel:nixos-unstable install_url: https://github.com/numtide/nix-unstable-installer/releases/download/nix-2.4pre20210604_8e6ee1b/install extra_nix_config: experimental-features = nix-command flakes From 8a307b869cbe1d5c97ee3b41a63627c2776087ed Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 5 Sep 2021 17:40:36 +0300 Subject: [PATCH 84/90] Add NIX_PATH and linkInputs option --- README.md | 6 ++++-- flake.nix | 1 + lib/autoRegistry.options.nix | 20 ------------------ lib/mkFlake.nix | 2 +- lib/options.nix | 41 ++++++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 23 deletions(-) delete mode 100644 lib/autoRegistry.options.nix create mode 100644 lib/options.nix diff --git a/README.md b/README.md index e3ff5404..b1dad24f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,9 @@ The biggest design goal is to keep down the fluff. The library is meant to be ea Main flake-utils-plus features (Attributes visible from `flake.nix`): - Extends [flake-utils](https://github.com/numtide/flake-utils). Everything exported by fu can be used from this flake. - `lib.mkFlake { ... }` - Clean and pleasant to use flakes abstraction. - - Option `nix.generateRegistryFromInputs` - Generates `nix.registry` from flake `inputs`. + - Option [`nix.generateRegistryFromInputs`](./lib/options.nix) - Generates `nix.registry` from flake inputs. + - Option [`nix.generateNixPathFromInputs`](./lib/options.nix) - Generate `nix.nixPath` from available inputs. + - Option [`nix.linkInputs`](./lib/options.nix) - Symlink inputs to /etc/nix/inputs. - Simple and clean support for multiple `nixpkgs` references. - `nixpkgs` references patching. - `channelsConfig` - Config applied to all `nixpkgs` references. @@ -24,7 +26,7 @@ Main flake-utils-plus features (Attributes visible from `flake.nix`): - [`lib.exportModules [ ./a.nix ./b.nix ]`](./lib/exportModules.nix) - Generates module attribute which look like this `{ a = import ./a.nix; b = import ./b.nix; }`. - [`lib.exportOverlays channels`](./lib/exportOverlays.nix) - Exports all overlays from channels as an appropriately namespaced attribute set. Users can instantiate with their nixpkgs version. - [`lib.exportPackages self.overlays channels`](./lib/exportPackages.nix) - Similar to the overlay generator, but outputs them as packages for the platforms defined in `meta.platforms`. Unlike overlays, these packages are consistent across flakes allowing them to be cached. -- `pkgs.fup-repl` - A package that adds a kick-ass repl. Usage: +- [`pkgs.fup-repl`](./lib/overlay.nix) - A package that adds a kick-ass repl. Usage: - `$ repl` - Loads your system repl into scope as well as `pkgs` and `lib` from `nixpkgs` input. - `$ repl /path/to/flake.nix` - Same as above but loads the specified flake. diff --git a/flake.nix b/flake.nix index a4b3ba78..18818330 100644 --- a/flake.nix +++ b/flake.nix @@ -26,6 +26,7 @@ # Deprecated in favor of 'nix.generateRegistryFromInputs = true;' nixosModules.saneFlakeDefaults = { nix.generateRegistryFromInputs = true; }; + nixosModules.autoGenFromInputs = import ./lib/options.nix; devShell.x86_64-linux = import ./devShell.nix { system = "x86_64-linux"; }; diff --git a/lib/autoRegistry.options.nix b/lib/autoRegistry.options.nix deleted file mode 100644 index 8be4d6d0..00000000 --- a/lib/autoRegistry.options.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ lib, config, inputs, ... }: - -let - flakes = lib.filterAttrs (name: value: value ? outputs) inputs; - - nixRegistry = builtins.mapAttrs - (name: v: { flake = v; }) - flakes; -in -{ - options.nix.generateRegistryFromInputs = lib.mkEnableOption "Generates Nix registry from available inputs."; - - config = { - nix.registry = - if config.nix.generateRegistryFromInputs - then nixRegistry - else { self.flake = flakes.self; }; - }; - -} diff --git a/lib/mkFlake.nix b/lib/mkFlake.nix index 885cd1c5..d2745341 100644 --- a/lib/mkFlake.nix +++ b/lib/mkFlake.nix @@ -76,7 +76,7 @@ let , specialArgs ? { } }: { inherit channelName system output builder extraArgs specialArgs; - modules = modules ++ [ ./autoRegistry.options.nix ]; + modules = modules ++ [ ./options.nix ]; }; optionalAttrs = check: value: if check then value else { }; diff --git a/lib/options.nix b/lib/options.nix new file mode 100644 index 00000000..eb3523b8 --- /dev/null +++ b/lib/options.nix @@ -0,0 +1,41 @@ +{ lib, config, inputs, ... }: + +let + inherit (lib) mkIf filterAttrs mapAttrsToList mapAttrs' mkOption types; + mkFalseOption = description: mkOption { + inherit description; + default = false; + example = true; + type = types.bool; + }; + + flakes = filterAttrs (name: value: value ? outputs) inputs; + flakesWithPkgs = filterAttrs (name: value: value.outputs ? legacyPackages || value.outputs ? packages) flakes; + + nixRegistry = builtins.mapAttrs + (name: v: { flake = v; }) + flakes; +in +{ + options = { + nix.generateNixPathFromInputs = mkFalseOption "Generate NIX_PATH available inputs."; + nix.generateRegistryFromInputs = mkFalseOption "Generate Nix registry from available inputs."; + nix.linkInputs = mkFalseOption "Symlink inputs to /etc/nix/inputs."; + }; + + config = { + nix.registry = + if config.nix.generateRegistryFromInputs + then nixRegistry + else { self.flake = flakes.self; }; + + environment.etc = mkIf (config.nix.linkInputs || config.nix.generateNixPathFromInputs) (mapAttrs' + (name: value: { name = "nix/inputs/${name}"; value = { source = value.outPath; }; }) + inputs); + + nix.nixPath = mkIf config.nix.generateNixPathFromInputs (mapAttrsToList + (name: _: "${name}=/etc/nix/inputs/${name}") + flakesWithPkgs); + }; +} + From fb18a434e9dc19fb504ba59664c1d9e106991bfc Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 5 Sep 2021 17:55:15 +0300 Subject: [PATCH 85/90] Update README with branching policy --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index b1dad24f..310b6794 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ Need help? Create an issue or ping @Gytis#0001 in the above Discord Server. +# Changing branching policy # +From now on `master` serves as a development branch (previously `staging` was used for such purposes). Please use tags for stable releases of flake-utils-plus. + # What is this flake? # Flake-utils-plus exposes a library abstraction to *painlessly* generate NixOS flake configurations. From d095b5d963f8f4a8b2751b1aa4d1b6a48833bbcd Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 5 Sep 2021 18:26:53 +0300 Subject: [PATCH 86/90] Fix missing channel.shortRev when executing tests locally --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 18818330..f4c5a515 100644 --- a/flake.nix +++ b/flake.nix @@ -57,7 +57,7 @@ patchChannel = system: channel: patches: if patches == [ ] then channel else (import channel { inherit system; }).pkgs.applyPatches { - name = "nixpkgs-patched-${channel.shortRev}"; + name = if channel ? shortRev then "nixpkgs-patched-${channel.shortRev}" else "nixpkgs-patched"; src = channel; patches = patches; }; From b4848f55c7017dadc2ff4f82296a3ca0b533e1fa Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 5 Sep 2021 18:31:47 +0300 Subject: [PATCH 87/90] Fix typo --- lib/options.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/options.nix b/lib/options.nix index eb3523b8..3a873e06 100644 --- a/lib/options.nix +++ b/lib/options.nix @@ -18,7 +18,7 @@ let in { options = { - nix.generateNixPathFromInputs = mkFalseOption "Generate NIX_PATH available inputs."; + nix.generateNixPathFromInputs = mkFalseOption "Generate NIX_PATH from available inputs."; nix.generateRegistryFromInputs = mkFalseOption "Generate Nix registry from available inputs."; nix.linkInputs = mkFalseOption "Symlink inputs to /etc/nix/inputs."; }; From 82ca1c5ffefa603e218649ac5cac7e86efa0d55c Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Sun, 5 Sep 2021 18:46:39 +0300 Subject: [PATCH 88/90] Remove deprecated code from examples --- README.md | 2 ++ examples/exporters/flake.nix | 8 ++++---- examples/home-manager+nur+neovim/flake.nix | 1 - examples/minimal-multichannel/flake.nix | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 310b6794..957a359e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Need help? Create an issue or ping @Gytis#0001 in the above Discord Server. # Changing branching policy # From now on `master` serves as a development branch (previously `staging` was used for such purposes). Please use tags for stable releases of flake-utils-plus. +Also, branch [release-1.2.0-without-deprecated-code](https://github.com/gytis-ivaskevicius/flake-utils-plus/tree/release-1.2.0-without-deprecated-code) has been created. It contains a non-backward compatible version of flake-utils-plus. Consider using this branch instead of the latest release. + # What is this flake? # diff --git a/examples/exporters/flake.nix b/examples/exporters/flake.nix index 6c8b480f..09a25cbb 100644 --- a/examples/exporters/flake.nix +++ b/examples/exporters/flake.nix @@ -10,7 +10,7 @@ outputs = inputs@{ self, nixpkgs, utils, ... }: let - inherit (utils.lib.exporters) internalOverlays fromOverlays modulesFromList; + inherit (utils.lib) exportOverlays exportPackages exportModules; in utils.lib.systemFlake { inherit self inputs; @@ -29,18 +29,18 @@ Morty ]; - nixosModules = modulesFromList [ + nixosModules = exportModules [ ./hosts/Morty.nix ]; # export overlays automatically for all packages defined in overlaysBuilder of each channel - overlays = internalOverlays { + overlays = exportOverlays { inherit (self) pkgs inputs; }; outputsBuilder = channels: { # construct packagesBuilder to export all packages defined in overlays - packages = fromOverlays self.overlays channels; + packages = exportPackages self.overlays channels; }; overlay = import ./overlays; diff --git a/examples/home-manager+nur+neovim/flake.nix b/examples/home-manager+nur+neovim/flake.nix index 42496af5..e4cf40d9 100644 --- a/examples/home-manager+nur+neovim/flake.nix +++ b/examples/home-manager+nur+neovim/flake.nix @@ -36,7 +36,6 @@ # Modules shared between all hosts hostDefaults.modules = [ - utils.nixosModules.saneFlakeDefaults home-manager.nixosModules.home-manager ./modules/sharedConfigurationBetweenHosts.nix ]; diff --git a/examples/minimal-multichannel/flake.nix b/examples/minimal-multichannel/flake.nix index ac58a02d..56e5109d 100644 --- a/examples/minimal-multichannel/flake.nix +++ b/examples/minimal-multichannel/flake.nix @@ -21,7 +21,6 @@ # Modules shared between all hosts hostDefaults.modules = [ ./modules/sharedConfigurationBetweenHosts.nix - utils.nixosModules.saneFlakeDefaults ]; From a5c54d9dcecaa6fb14a53d14cd99f13aff4fc646 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sun, 5 Sep 2021 11:10:39 -0500 Subject: [PATCH 89/90] Hint on using tagged releases and explain 1.2.0 vs 1.2.1 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 957a359e..7ddd2277 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,9 @@ Need help? Create an issue or ping @Gytis#0001 in the above Discord Server. # Changing branching policy # From now on `master` serves as a development branch (previously `staging` was used for such purposes). Please use tags for stable releases of flake-utils-plus. -Also, branch [release-1.2.0-without-deprecated-code](https://github.com/gytis-ivaskevicius/flake-utils-plus/tree/release-1.2.0-without-deprecated-code) has been created. It contains a non-backward compatible version of flake-utils-plus. Consider using this branch instead of the latest release. +In general, with the imporvements in test harness, releases might happen more frequently. Sticking with a tagged release might offer better trade-offs going forward. + +Please note, while 1.2.0 retains backwards compatibility, 1.2.1 is the same version with all backwards compatibility removed. # What is this flake? # From ccc11372515451e62656aa38fc4987d7bb4ebd3f Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sun, 5 Sep 2021 11:11:59 -0500 Subject: [PATCH 90/90] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ddd2277..47d7d793 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Need help? Create an issue or ping @Gytis#0001 in the above Discord Server. # Changing branching policy # From now on `master` serves as a development branch (previously `staging` was used for such purposes). Please use tags for stable releases of flake-utils-plus. -In general, with the imporvements in test harness, releases might happen more frequently. Sticking with a tagged release might offer better trade-offs going forward. +In general, with the improvements in test harness, releases might happen more frequently. Sticking with a tagged release might offer better trade-offs going forward. Please note, while 1.2.0 retains backwards compatibility, 1.2.1 is the same version with all backwards compatibility removed.