From ee7462f2c659ced7b9dd3abfe927345c9f2681cc Mon Sep 17 00:00:00 2001 From: XYenon Date: Tue, 24 Mar 2026 20:38:33 +0800 Subject: [PATCH] feat: expose nixosModules, homeModules, darwinModules, flakeModules as flake outputs Closes #799. Adds standard flake outputs so modules can be accessed via: nur.nixosModules.repos.${repo}.${module} nur.homeModules.repos.${repo}.${module} nur.darwinModules.repos.${repo}.${module} nur.flakeModules.repos.${repo}.${module} nixosModules falls back to the legacy 'modules' attribute when 'nixosModules' is not present in a repo. Missing attributes in any repo gracefully return {}. Amp-Thread-ID: https://ampcode.com/threads/T-019d1fc6-58ae-750f-bac6-f5e66598ddfc Co-authored-by: Amp --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++-------- flake.nix | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3e1951c0f..44996cd3b 100644 --- a/README.md +++ b/README.md @@ -164,8 +164,10 @@ Using overlays and modules from NUR in your configuration is fairly straightforw modules = [ # Adds the NUR overlay nur.modules.nixos.default - # NUR modules to import - nur.legacyPackages."${system}".repos.iopq.modules.xraya + # NUR modules can be imported directly via nixosModules: + nur.nixosModules.repos.iopq.xraya + # Or via legacyPackages (legacy path): + # nur.legacyPackages."${system}".repos.iopq.modules.xraya # This adds the NUR nixpkgs overlay. # Example: # ({ pkgs, ... }: { @@ -182,12 +184,12 @@ Using overlays and modules from NUR in your configuration is fairly straightforw Integrating with [Home Manager](https://github.com/rycee/home-manager) can be done by adding your modules to the `imports` attribute. You can then configure your services like usual. +When using flakes, Home Manager modules can be accessed directly: + ```nix -let - nur-no-pkgs = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") {}; -in +# In your Home Manager configuration { - imports = lib.attrValues nur-no-pkgs.repos.moredhel.hmModules.rawModules; + imports = lib.attrValues nur.homeModules.repos.moredhel; services.unison = { enable = true; @@ -202,6 +204,17 @@ in } ``` +Without flakes: + +```nix +let + nur-no-pkgs = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") {}; +in +{ + imports = lib.attrValues nur-no-pkgs.repos.moredhel.homeModules; +} +``` + ## Finding packages You can find all packages using @@ -407,11 +420,11 @@ they must be put them in their own namespace within the repository. #### Providing NixOS modules -NixOS modules should be placed in the `modules` attribute: +NixOS modules should be placed in the `nixosModules` attribute: ```nix { pkgs }: { - modules = import ./modules; + nixosModules = import ./modules; } ``` @@ -422,10 +435,48 @@ NixOS modules should be placed in the `modules` attribute: } ``` +These modules are then accessible as `nur.nixosModules.repos..` in flakes. + +The legacy `modules` attribute is also supported as a fallback for `nixosModules`. + An example can be found [here](https://github.com/Mic92/nur-packages/tree/master/modules). Modules should be defined as paths, not functions, to avoid conflicts if imported from multiple locations. -A module with no [_class](https://nixos.org/manual/nixpkgs/stable/index.html#module-system-lib-evalModules-param-class) will be assumed to be both a NixOS and Home Manager module. If a module is NixOS or Home Manager specific, the `_class` attribute should be set to `"nixos"` or [`"home-manager"`](https://github.com/nix-community/home-manager/commit/26e72d85e6fbda36bf2266f1447215501ec376fd). +#### Providing Home Manager modules + +Home Manager modules should be placed in the `homeModules` attribute: + +```nix +{ pkgs }: { + homeModules = import ./hm-modules; +} +``` + +These modules are then accessible as `nur.homeModules.repos..` in flakes. + +#### Providing Darwin modules + +Darwin (nix-darwin) modules should be placed in the `darwinModules` attribute: + +```nix +{ pkgs }: { + darwinModules = import ./darwin-modules; +} +``` + +These modules are then accessible as `nur.darwinModules.repos..` in flakes. + +#### Providing flake-parts modules + +Flake-parts modules should be placed in the `flakeModules` attribute: + +```nix +{ pkgs }: { + flakeModules = import ./flake-modules; +} +``` + +These modules are then accessible as `nur.flakeModules.repos..` in flakes. #### Providing Overlays diff --git a/flake.nix b/flake.nix index 8116b5ea6..afe1d8d3b 100644 --- a/flake.nix +++ b/flake.nix @@ -20,6 +20,33 @@ pkgs = prev; }; }; + + lockedRevisions = (builtins.fromJSON (builtins.readFile ./repos.json.lock)).repos; + repoSource = + name: attr: + import ./lib/repoSource.nix { + inherit + name + attr + manifest + lockedRevisions + lib + ; + fetchgit = builtins.fetchGit or lib.id; + fetchzip = builtins.fetchTarball or lib.id; + }; + # Lazily evaluate each repo with pkgs = null; the result is only forced + # when a specific repo's attribute is accessed. + repos = lib.mapAttrs ( + name: attr: + import ./lib/evalRepo.nix { + inherit name lib; + inherit (attr) url; + src = repoSource name attr + ("/" + (attr.file or "")); + pkgs = null; + } + ) manifest; + collectModules = attrName: lib.mapAttrs (name: _: repos.${name}.${attrName} or { }) manifest; in flake-parts.lib.mkFlake { inherit inputs; } { systems = builtins.filter ( @@ -62,5 +89,19 @@ # This trick with the overlay is used because it allows NUR packages to depend on other NUR packages legacyPackages = (pkgs.extend overlay).nur; }; + } + // { + # Expose modules from individual NUR repos as standard flake outputs. + # Merged outside flake-parts to avoid deferredModule type wrapping. + nixosModules.repos = lib.mapAttrs ( + name: _: + let + r = repos.${name}; + in + r.nixosModules or r.modules or { } + ) manifest; + homeModules.repos = collectModules "homeModules"; + darwinModules.repos = collectModules "darwinModules"; + flakeModules.repos = collectModules "flakeModules"; }; }