From ce6c733190d09fb67ea0e2ddbfa22e5fa4882965 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Tue, 20 May 2025 22:26:54 +0100 Subject: [PATCH 1/4] lib/version: init --- lib/default.nix | 1 + lib/version.nix | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 lib/version.nix diff --git a/lib/default.nix b/lib/default.nix index 2b86d67a..02f3f1b8 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -25,6 +25,7 @@ lib.makeExtensible ( options = call ./options.nix { }; plugins = call ./plugins { }; utils = call ./utils.nix { inherit _nixvimTests; } // call ./utils.internal.nix { }; + version = call ./version.nix { inherit flake; }; # Top-level helper aliases: # TODO: deprecate some aliases diff --git a/lib/version.nix b/lib/version.nix new file mode 100644 index 00000000..545295de --- /dev/null +++ b/lib/version.nix @@ -0,0 +1,6 @@ +{ + lib, + flake, +}: +{ +} From 211f532644c01e9652811bcc2f1a5a3fa9492e29 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Tue, 20 May 2025 22:27:19 +0100 Subject: [PATCH 2/4] lib/version: add `isInputModified` --- lib/version.nix | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/lib/version.nix b/lib/version.nix index 545295de..f357afdb 100644 --- a/lib/version.nix +++ b/lib/version.nix @@ -2,5 +2,92 @@ lib, flake, }: +let + inherit (builtins) + isList + mapAttrs + head + tail + ; + + lockFile = lib.importJSON ../flake.lock; + + /** + Resolve an input spec into a node name. + + # Inputs + + `inputSpec` ([String] | String) + : Either a node name, or a "follows" path relative to the root node. + + # Output + + The node name. + + # Upstream + + This is based on `resolveInput` in nix's [call-flake.nix] + + [call-flake.nix]: https://github.com/NixOS/nix/blob/46beb9af/src/libflake/call-flake.nix#L21-L25 + */ + resolveInput = + inputSpec: if isList inputSpec then getInputByPath lockFile.root inputSpec else inputSpec; + + /** + Follow an input attrpath from the root node, stepping through each node along the path. + + # Inputs + + `nodeName` + : The name of the _current_ node. + + `path` + : The input attrpath to follow. + E.g. `["dwarffs" "nixpkgs"]` + + # Outputs + + The final node name. + + # Upstream + + This is based on `getInputByPath` in nix's [call-flake.nix] + + [call-flake.nix]: https://github.com/NixOS/nix/blob/46beb9af/src/libflake/call-flake.nix#L27-L37 + */ + getInputByPath = + nodeName: path: + if path == [ ] then + nodeName + else + getInputByPath (resolveInput lockFile.nodes.${nodeName}.inputs.${head path}) (tail path); + + # Inputs specified in our flake.lock + lockedInputs = lib.pipe lockFile.nodes.${lockFile.root}.inputs [ + (mapAttrs (inputName: inputSpec: lockFile.nodes.${resolveInput inputSpec})) + ]; + + # Our actual inputs, potentially modified by end-user's "follows" + realInputs = flake.inputs; +in { + /** + Check whether a specific input is modified when compared to our `flake.lock` file. + + This can happen when a user specifies one of our inputs "follows" one of theirs. + */ + isInputModified = + name: + assert lib.assertMsg ( + realInputs ? ${name} + ) "isInputModified: `${lib.strings.escapeNixIdentifier name}` is not in `inputs`."; + assert lib.assertMsg ( + lockedInputs ? ${name} + ) "isInputModified: `${lib.strings.escapeNixIdentifier name}` is not in `flake.lock`."; + let + # If a non-flake input is used, `sourceInfo` will be missing + real = realInputs.${name}.sourceInfo.narHash or null; + locked = lockedInputs.${name}.locked.narHash; + in + real != locked; } From 8f782c7af9ecc380cff475061fe921ef04e6ec3d Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Tue, 20 May 2025 23:29:12 +0100 Subject: [PATCH 3/4] lib.version: add release info --- lib/version.nix | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/lib/version.nix b/lib/version.nix index f357afdb..993e6959 100644 --- a/lib/version.nix +++ b/lib/version.nix @@ -90,4 +90,35 @@ in locked = lockedInputs.${name}.locked.narHash; in real != locked; + + /** + Nixvim's current commit, or the specified default when nixvim's repo is dirty. + */ + revisionWithDefault = default: flake.sourceInfo.rev or default; + + /** + Nixvim's current commit, defaulting to the canonical branch name for this release. + */ + revision = with lib.nixvim.version; revisionWithDefault releaseBranch; + + /** + Nixvim's release. + + Derived from the nixpkgs branch targeted in `flake.lock`. + */ + release = + let + inherit (lockedInputs.nixpkgs.original) ref; + parts = lib.splitString "-" ref; + in + lib.last parts; + + /** + The canonical branch name associated with this release of nixvim. + */ + releaseBranch = + let + inherit (lib.nixvim.version) release; + in + if release == "unstable" then "main" else "nixos-" + release; } From ebd4ba4f792526c45bc5de1754cd763da941408f Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Tue, 20 May 2025 23:30:22 +0100 Subject: [PATCH 4/4] lib.version: add `correctNixpkgsChannel` --- lib/version.nix | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/version.nix b/lib/version.nix index 993e6959..120ca3f5 100644 --- a/lib/version.nix +++ b/lib/version.nix @@ -121,4 +121,20 @@ in inherit (lib.nixvim.version) release; in if release == "unstable" then "main" else "nixos-" + release; + + /** + Whether the nixpkgs input is correct for this release of nixvim. + + Can be used to identify mismatched nixpkgs inputs, usually caused our input + following a user's input from another channel + */ + correctNixpkgsChannel = + let + nixvimRelease = lib.nixvim.version.release; + nixpkgsRelease = lib.trivial.release; + in + if nixvimRelease == "unstable" then + true # TODO: how do we know what channel a nixpkgs instance is on? + else + nixvimRelease == nixpkgsRelease; }