diff --git a/API_GUIDE.md b/API_GUIDE.md index e13102c..ff7ba13 100644 --- a/API_GUIDE.md +++ b/API_GUIDE.md @@ -721,15 +721,24 @@ Alternatively, the configurations can be functions, in which case those functions will be passed `moduleArgs` and must return a standard configuration (this is useful when using autoloads with the `nixDir` feature). +The `propagationModule` config provides a module to apply flakelight +configuration to other module systems such as NixOS and home-manager. Applying +this module will give modules in the nested modules system access to a `flake` +module arg that contains the flakelight module args as well as `inputs'` and +`outputs'`. Flakelight's packages configuration will also be applied to the pkgs +of the nested module system (This includes flakelight's additional pkgs values, +`withOverlays` overlays, and the flake's packages. + For example: ```nix { inputs.flakelight.url = "github:nix-community/flakelight"; outputs = { flakelight, ... }: - flakelight ./. ({ lib, ... }: { + flakelight ./. ({ lib, config, ... }: { nixosConfigurations.system = lib.nixosSystem { # nixosSystem arguments + modules = [ config.propagationModule ]; }; }); } @@ -742,11 +751,12 @@ For example: home-manger.url = "github:nix-community/home-manager"; }; outputs = { flakelight, home-manager, ... }: - flakelight ./. { + flakelight ./. ({ config, ... }: { homeConfigurations.user = home-manager.lib.homeManagerConfiguration { # homeManagerConfiguration arguments + modules = [ config.propagationModule ]; }; - }; + }); } ``` diff --git a/builtinModules/propagationModule.nix b/builtinModules/propagationModule.nix new file mode 100644 index 0000000..8212926 --- /dev/null +++ b/builtinModules/propagationModule.nix @@ -0,0 +1,48 @@ +# flakelight -- Framework for simplifying flake setup +# Copyright (C) 2023 Archit Gupta +# SPDX-License-Identifier: MIT + +# This provides a module that can be added to module systems nested inside of +# flakelight, for example NixOS or home-manager configurations. + +{ lib, config, flakelight, moduleArgs, inputs, outputs, ... }: +let + inherit (lib) composeManyExtensions mapAttrs mkOption optionalAttrs; + inherit (flakelight.types) module; +in +{ + options.propagationModule = mkOption { type = module; }; + + config.propagationModule = + { lib, pkgs, options, ... }: + let + inherit (pkgs.stdenv.hostPlatform) system; + in + { + config = (optionalAttrs (options ? nixpkgs.overlays) { + # Apply flakelight overlays to NixOS/home-manager configurations + nixpkgs.overlays = lib.mkOrder 10 [ + # Avoid re-applying overlays + # This can happen when home-manager's pkgs arg already has them + (final: prev: optionalAttrs (! prev ? flakelight) ( + (composeManyExtensions + (config.withOverlays ++ [ config.packageOverlay ])) + final + prev + )) + ]; + }) + // (optionalAttrs (options ? home-manager.sharedModules) { + # Propagate module to home-manager when using its nixos module + home-manager.sharedModules = [ config.propagationModule ]; + }) + // { + # Give access to flakelight module args under `flake` arg. + # Also include inputs'/outputs' which depend on `pkgs`. + _module.args.flake = { + inputs' = mapAttrs (_: mapAttrs (_: v: v.${system} or { })) inputs; + outputs' = mapAttrs (_: v: v.${system} or { }) outputs; + } // moduleArgs; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 63f41a2..ee1c85a 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -596,6 +596,26 @@ in })) (f: f ? nixosConfigurations.test.config.system.build.toplevel); + nixosConfigurationsWithProp = test + (flakelight ./empty ({ lib, config, ... }: { + nixosConfigurations.test = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + config.propagationModule + ({ flake, ... }: { + system.stateVersion = "24.05"; + environment.variables = { + TEST1 = flake.inputs.nixpkgs.legacyPackages.x86_64-linux.hello; + TEST2 = flake.inputs'.nixpkgs.legacyPackages.hello; + }; + }) + ]; + }; + })) + (f: (f ? nixosConfigurations.test.config.system.build.toplevel) + && (f.nixosConfigurations.test.config.environment.variables.TEST1 == + f.nixosConfigurations.test.config.environment.variables.TEST2)); + nixosModule = test (flakelight ./empty { nixosModule = _: { };