From 039f73f134546e59ec6f1b56b4aff5b81d889f64 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 6 Sep 2023 15:08:46 +0200 Subject: [PATCH 1/6] flake: fix `lib.trivial.version` when used from a flake A lot of fetchers from Nix's own `libfetchers` also provide the information that `lib.trivial` aims to expose with `version`/`versionSuffix`/`revision`. In fact you don't even need a `nixpkgs` channel to get a proper version suffix because of that! Unfortunately this isn't used currently. When using the nixpkgs flake, but not `nixpkgs.lib.nixosSystem` to build a NixOS configuration, the version will always be `YY.MMpre-git`. One example is e.g. `colmena` which evaluates configurations via `import (npkgs.path + "/nixos/lib/eval-config.nix")`. This patch ensures that the version suffix (i.e. the normalized last modified date + git revision) is correctly exposed in `lib.trivial`. Additionally, the change is injected into the following locations: * `lib`: with that, something like $ nix eval nixpkgs#lib.trivial.version 23.05.20230921.cf8bf79 is working fine (i.e. rather than `23.05pre-git`). * `legacyPackages` to make sure that e.g. `legacyPackages..nixos` has correct version info. This also applies to everything else using `pkgs.lib.trivial` for that purpose. * `overlays.default` which can be applied to a `nixpkgs` and changes the previous `pkgs.lib` from said `nixpkgs` to also contain the correct `version`/`revision`/etc.. This is useful for people using `nixpkgs` as flake input, but importing it manually with import inputs.nixpkgs { } Co-authored-by: Linus Heckemann --- flake.nix | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/flake.nix b/flake.nix index fa00bffcdf92..bf7480a6db2d 100644 --- a/flake.nix +++ b/flake.nix @@ -9,24 +9,31 @@ nixpkgs = self; }; - lib = import ./lib; + lib = (import ./lib).extend libVersionInfoOverlay; + + libVersionInfoOverlay = finalLib: prevLib: { + trivial = prevLib.trivial // { + versionSuffix = + ".${finalLib.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}"; + version = finalLib.trivial.release + finalLib.trivial.versionSuffix; + revisionWithDefault = default: self.rev or default; + }; + }; forAllSystems = lib.genAttrs lib.systems.flakeExposed; in { + overlays.setLibVersionInfo = final: prev: { + lib = prev.lib.extend libVersionInfoOverlay; + }; + lib = lib.extend (final: prev: { nixos = import ./nixos/lib { lib = final; }; nixosSystem = args: import ./nixos/lib/eval-config.nix ( - args // { - modules = args.modules ++ [{ - system.nixos.versionSuffix = - ".${final.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}"; - system.nixos.revision = final.mkIf (self ? rev) self.rev; - }]; - } // lib.optionalAttrs (! args?system) { + args // { inherit (self) lib; } // lib.optionalAttrs (! args?system) { # Allow system to be set modularly in nixpkgs.system. # We set it to null, to remove the "legacy" entrypoint's # non-hermetic default. @@ -53,7 +60,10 @@ # attribute it displays `omitted` instead of evaluating all packages, # which keeps `nix flake show` on Nixpkgs reasonably fast, though less # information rich. - legacyPackages = forAllSystems (system: import ./. { inherit system; }); + legacyPackages = forAllSystems (system: import ./. { + inherit system; + overlays = [ self.overlays.setLibVersionInfo ]; + }); nixosModules = { notDetected = ./nixos/modules/installer/scan/not-detected.nix; From bb7921d1d6a0df8ebdc36b8ee745fe704b93b846 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Fri, 20 Oct 2023 12:12:48 +0200 Subject: [PATCH 2/6] flake: also provide proper version info for lib's flake This effectively means that nixpkgs$ nix eval ./lib#lib.trivial.version "23.11.20231020.ee0d6b5" now gives meaningful results as well. See https://github.com/NixOS/nixpkgs/pull/257100#discussion_r1352075369 for the discussion around this. --- flake.nix | 10 +--------- lib/__flake-version-info.nix | 17 +++++++++++++++++ lib/flake.nix | 7 ++++++- 3 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 lib/__flake-version-info.nix diff --git a/flake.nix b/flake.nix index bf7480a6db2d..23c9f09a174b 100644 --- a/flake.nix +++ b/flake.nix @@ -9,17 +9,9 @@ nixpkgs = self; }; + libVersionInfoOverlay = import ./lib/__flake-version-info.nix self; lib = (import ./lib).extend libVersionInfoOverlay; - libVersionInfoOverlay = finalLib: prevLib: { - trivial = prevLib.trivial // { - versionSuffix = - ".${finalLib.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}"; - version = finalLib.trivial.release + finalLib.trivial.versionSuffix; - revisionWithDefault = default: self.rev or default; - }; - }; - forAllSystems = lib.genAttrs lib.systems.flakeExposed; in { diff --git a/lib/__flake-version-info.nix b/lib/__flake-version-info.nix new file mode 100644 index 000000000000..19ce4c351cf1 --- /dev/null +++ b/lib/__flake-version-info.nix @@ -0,0 +1,17 @@ +# lib overlay to be used by the nixpkgs & nixpkgs/lib flakes +# to provide meaningful values for `lib.trivial.version` et al.. +# +# Internal and subject to change, don't use this anywhere else! + +self: # from the flake + +finalLib: prevLib: # lib overlay + +{ + trivial = prevLib.trivial // { + versionSuffix = + ".${finalLib.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}"; + version = finalLib.trivial.release + finalLib.trivial.versionSuffix; + revisionWithDefault = default: self.rev or default; + }; +} diff --git a/lib/flake.nix b/lib/flake.nix index 0b5e54d547c5..475aa13edafb 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -1,5 +1,10 @@ { description = "Library of low-level helper functions for nix expressions."; - outputs = { self }: { lib = import ./.; }; + outputs = { self }: + let + lib' = import ./.; + in { + lib = lib'.extend (import ./__flake-version-info.nix self); + }; } From 78f5ed053aba713ea2fc1226ec8193d298c221fc Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 31 Oct 2023 13:35:51 +0100 Subject: [PATCH 3/6] lib/trivial: drop `rec` in favor of `lib` fixpoint That way each expression uses the final version of other lib.trivial declarations. For instance, when replacing `versionSuffix` with the string `"fnord"` in a lib overlay, `trivial.version` uses `"fnord"` as suffix now rather than `pre-git`. --- lib/trivial.nix | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/trivial.nix b/lib/trivial.nix index caff77190fde..b3fb54a7add4 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -1,6 +1,18 @@ { lib }: -rec { +let + inherit (lib.trivial) + isFunction + isInt + functionArgs + pathExists + release + setFunctionArgs + toBaseDigits + version + versionSuffix + warn; +in { ## Simple (higher order) functions @@ -439,7 +451,7 @@ rec { */ functionArgs = f: if f ? __functor - then f.__functionArgs or (lib.functionArgs (f.__functor f)) + then f.__functionArgs or (functionArgs (f.__functor f)) else builtins.functionArgs f; /* Check whether something is a function or something From ede5720a0dde969cf83dd7cbbe54ad8c5ff7a97b Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 31 Oct 2023 13:38:29 +0100 Subject: [PATCH 4/6] flake/version overlay: review fixes * Improves the comments of `lib/flake-version-info.nix` and drops the `__`-prefix from the filename. * `lib'` -> `lib0` in `nixpkgs/lib`. * Drop the declaration of `trivial.version` in the overlay because this declaration already uses the final expressions of `versionSuffix` and `release` now. * No need to fall back to `self.lastModified` anymore, this was a workaround for pre2.4 Nix. Co-authored-by: Robert Hensing Co-authored-by: Silvan Mosberger --- flake.nix | 2 +- lib/__flake-version-info.nix | 17 ----------------- lib/flake-version-info.nix | 20 ++++++++++++++++++++ lib/flake.nix | 4 ++-- 4 files changed, 23 insertions(+), 20 deletions(-) delete mode 100644 lib/__flake-version-info.nix create mode 100644 lib/flake-version-info.nix diff --git a/flake.nix b/flake.nix index 23c9f09a174b..307eea0cd040 100644 --- a/flake.nix +++ b/flake.nix @@ -9,7 +9,7 @@ nixpkgs = self; }; - libVersionInfoOverlay = import ./lib/__flake-version-info.nix self; + libVersionInfoOverlay = import ./lib/flake-version-info.nix self; lib = (import ./lib).extend libVersionInfoOverlay; forAllSystems = lib.genAttrs lib.systems.flakeExposed; diff --git a/lib/__flake-version-info.nix b/lib/__flake-version-info.nix deleted file mode 100644 index 19ce4c351cf1..000000000000 --- a/lib/__flake-version-info.nix +++ /dev/null @@ -1,17 +0,0 @@ -# lib overlay to be used by the nixpkgs & nixpkgs/lib flakes -# to provide meaningful values for `lib.trivial.version` et al.. -# -# Internal and subject to change, don't use this anywhere else! - -self: # from the flake - -finalLib: prevLib: # lib overlay - -{ - trivial = prevLib.trivial // { - versionSuffix = - ".${finalLib.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}"; - version = finalLib.trivial.release + finalLib.trivial.versionSuffix; - revisionWithDefault = default: self.rev or default; - }; -} diff --git a/lib/flake-version-info.nix b/lib/flake-version-info.nix new file mode 100644 index 000000000000..de15be94bee8 --- /dev/null +++ b/lib/flake-version-info.nix @@ -0,0 +1,20 @@ +# This function produces a lib overlay to be used by the nixpkgs +# & nixpkgs/lib flakes to provide meaningful values for +# `lib.trivial.version` et al.. +# +# Internal and subject to change, don't use this anywhere else! +# Instead, consider using a public interface, such as this flake here +# in this directory, `lib/`, or use the nixpkgs flake, which applies +# this logic for you in its `lib` output attribute. + +self: # from the flake + +finalLib: prevLib: # lib overlay + +{ + trivial = prevLib.trivial // { + versionSuffix = + ".${finalLib.substring 0 8 (self.lastModifiedDate or "19700101")}.${self.shortRev or "dirty"}"; + revisionWithDefault = default: self.rev or default; + }; +} diff --git a/lib/flake.nix b/lib/flake.nix index 475aa13edafb..ca09ed5f4a42 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -3,8 +3,8 @@ outputs = { self }: let - lib' = import ./.; + lib0 = import ./.; in { - lib = lib'.extend (import ./__flake-version-info.nix self); + lib = lib0.extend (import ./flake-version-info.nix self); }; } From cb289a9256254d00e147521388093468eaf202cb Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sat, 9 Dec 2023 11:57:56 +0100 Subject: [PATCH 5/6] flake: be backwards-compatible for `--impure` We cannot pass `overlays = ...` to `nixpkgs` directly because by default overlays from `~/.config/nixpkgs` are loaded in there. This doesn't happen by default, but when using `--impure`. Explicitly specifying that ignores these overlays. By using `pkgs.extend` the old behavior can be kept and the new overlay can be applied. Co-authored-by: Silvan Mosberger --- flake.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index 307eea0cd040..9b437c169a4f 100644 --- a/flake.nix +++ b/flake.nix @@ -52,10 +52,9 @@ # attribute it displays `omitted` instead of evaluating all packages, # which keeps `nix flake show` on Nixpkgs reasonably fast, though less # information rich. - legacyPackages = forAllSystems (system: import ./. { - inherit system; - overlays = [ self.overlays.setLibVersionInfo ]; - }); + legacyPackages = forAllSystems (system: + (import ./. { inherit system; }).extend self.overlays.setLibVersionInfo + ); nixosModules = { notDetected = ./nixos/modules/installer/scan/not-detected.nix; From b96ba988d670ddb0e26ede4e3482624f4158a649 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 10 Dec 2023 13:25:14 +0100 Subject: [PATCH 6/6] flake: drop libVersionInfoOverlay It's not really a pkgs overlay, but a lib overlay. --- flake.nix | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index 9b437c169a4f..f16bc7d05fce 100644 --- a/flake.nix +++ b/flake.nix @@ -15,10 +15,6 @@ forAllSystems = lib.genAttrs lib.systems.flakeExposed; in { - overlays.setLibVersionInfo = final: prev: { - lib = prev.lib.extend libVersionInfoOverlay; - }; - lib = lib.extend (final: prev: { nixos = import ./nixos/lib { lib = final; }; @@ -53,7 +49,9 @@ # which keeps `nix flake show` on Nixpkgs reasonably fast, though less # information rich. legacyPackages = forAllSystems (system: - (import ./. { inherit system; }).extend self.overlays.setLibVersionInfo + (import ./. { inherit system; }).extend (final: prev: { + lib = prev.lib.extend libVersionInfoOverlay; + }) ); nixosModules = {