diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4a847d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/result diff --git a/README.md b/README.md new file mode 100644 index 0000000..88d2f5f --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# Diamond dependencies with the nixpkgs module system + +This flake declares 2 `nixosConfigurations`: + +- `.#nixosConfigurations.use-module-binding` +- `.#nixosConfigurations.use-module-filepath` + +They both include the `./vim-option.nix` module twice (simulating a "diamond +dependency"), but in different ways: + +`use-module-filepath.nix`: +```nix +{ + imports = [ + ./vim-option.nix + ./vim-option.nix + ]; + + ... +} +``` + +`use-module-binding.nix`: +```nix +let vim-option = import ./vim-option.nix; +in +{ + imports = [ + vim-option + vim-option + ]; + + ... +} +``` + +This "double import via a binding" feels like something that's more likely to +happen as the nix flake ecosystem evolves: someday you're going to end up using +module A and module B where module B itself uses module A. + +Note that `.#nixosConfigurations.use-module-filepath` evaluates fine: + +```shell +$ nix eval .#nixosConfigurations.use-module-filepath.config.system.build.toplevel +trace: declaring _includeVim +«derivation /nix/store/dmmxnrhn6c6yibzlcdlwjb1i5akdcjsi-nixos-system-nixos-24.11.20240923.30439d9.drv» +``` + +However, `.#nixosConfigurations.use-module-binding` fails to evaluate: + +```shell +$ nix eval .#nixosConfigurations.use-module-binding.config.system.build.toplevel +trace: declaring _includeVim +trace: declaring _includeVim +error: + … while calling the 'head' builtin + at /nix/store/p2hby44a0qzrnd1vxcpcgfav6160rmcv-source/lib/attrsets.nix:1575:11: + 1574| || pred here (elemAt values 1) (head values) then + 1575| head values + | ^ + 1576| else + + … while evaluating the attribute 'value' + at /nix/store/p2hby44a0qzrnd1vxcpcgfav6160rmcv-source/lib/modules.nix:821:9: + 820| in warnDeprecation opt // + 821| { value = addErrorContext "while evaluating the option `${showOption loc}':" value; + | ^ + 822| inherit (res.defsFinal') highestPrio; + + … while evaluating the option `system.build.toplevel': + + … while evaluating definitions from `/nix/store/p2hby44a0qzrnd1vxcpcgfav6160rmcv-source/nixos/modules/system/activation/top-level.nix': + + … while evaluating the option `system.systemBuilderArgs': + + … while evaluating definitions from `/nix/store/p2hby44a0qzrnd1vxcpcgfav6160rmcv-source/nixos/modules/system/activation/activatable-system.nix': + + … while evaluating the option `system.activationScripts.etc.text': + + … while evaluating definitions from `/nix/store/p2hby44a0qzrnd1vxcpcgfav6160rmcv-source/nixos/modules/system/etc/etc-activation.nix': + + … while evaluating definitions from `/nix/store/p2hby44a0qzrnd1vxcpcgfav6160rmcv-source/nixos/modules/system/etc/etc.nix': + + … while evaluating the option `environment.etc.dbus-1.source': + + … while evaluating the option `environment.systemPackages': + + … while evaluating definitions from `/nix/store/vxrd24hjs9k56cjfhchyy57zs0n8kg84-source/use-module-binding.nix': + + (stack trace truncated; use '--show-trace' to show the full, detailed trace) + + error: The option `_includeVim' in `/nix/store/vxrd24hjs9k56cjfhchyy57zs0n8kg84-source/use-module-binding.nix' is already declared in `/nix/store/vxrd24hjs9k56cjfhchyy57zs0n8kg84-source/use-module-binding.nix'. +``` diff --git a/base.nix b/base.nix new file mode 100644 index 0000000..996be98 --- /dev/null +++ b/base.nix @@ -0,0 +1,8 @@ +{ + nixpkgs.hostPlatform = "x86_64-linux"; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + system.stateVersion = "24.05"; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..dab2fd3 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1727122398, + "narHash": "sha256-o8VBeCWHBxGd4kVMceIayf5GApqTavJbTa44Xcg5Rrk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "30439d93eb8b19861ccbe3e581abf97bdc91b093", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..79a91f8 --- /dev/null +++ b/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A very basic flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + }; + + outputs = + { nixpkgs, ... }: + { + nixosConfigurations.use-module-binding = nixpkgs.lib.nixosSystem { + modules = [ + "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" + ./base.nix + ./use-module-binding.nix + ]; + }; + nixosConfigurations.use-module-filepath = nixpkgs.lib.nixosSystem { + modules = [ + "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" + ./base.nix + ./use-module-filepath.nix + ]; + }; + }; +} diff --git a/use-module-binding.nix b/use-module-binding.nix new file mode 100644 index 0000000..054df89 --- /dev/null +++ b/use-module-binding.nix @@ -0,0 +1,17 @@ +{ + lib, + pkgs, + config, + ... +}: +let + vim-option = import ./vim-option.nix; +in +{ + imports = [ + vim-option + vim-option + ]; + + environment.systemPackages = lib.mkIf config._includeVim [ pkgs.vim ]; +} diff --git a/use-module-filepath.nix b/use-module-filepath.nix new file mode 100644 index 0000000..2033d4a --- /dev/null +++ b/use-module-filepath.nix @@ -0,0 +1,14 @@ +{ + lib, + pkgs, + config, + ... +}: +{ + imports = [ + ./vim-option.nix + ./vim-option.nix + ]; + + environment.systemPackages = lib.mkIf config._includeVim [ pkgs.vim ]; +} diff --git a/vim-option.nix b/vim-option.nix new file mode 100644 index 0000000..c0527db --- /dev/null +++ b/vim-option.nix @@ -0,0 +1,13 @@ +{ lib, ... }: +{ + options._includeVim = builtins.trace "declaring _includeVim" ( + lib.mkOption { + internal = true; + default = false; + } + ); + + # Interestingly, this does not reproduce the same issue: + # options._includeVim = builtins.trace "declaring _includeVim" (lib.mkOption {internal = true;}); + # config._includeVim = true; +}