diff --git a/README.md b/README.md index 17fbcb2..f3a7e6c 100644 --- a/README.md +++ b/README.md @@ -5,52 +5,51 @@ _Foundational flake attributes represented using the module system._ `flake-modules-core` provides common options for an ecosystem of modules to extend. -This allows anyone to bundle up tooling into reusable modules. +# Why Modules? -For users, this makes Flakes easier to wire up. +Flakes are configuration. The module system lets you refactor configuration +into modules that can be shared. -_Non-goals_: - - Replace general Nix expressions, which are needed for advanced and/or ad-hoc use cases. - - Accumulate everything into a single repository. As the name might suggest, it focuses only on options that have to do with well-known Nix Flakes attributes. +It reduces the proliferation of custom Nix glue code, similar to what the +module system has done for NixOS configurations. +Unlike NixOS, but following Flakes' spirit, `flake-modules-core` is not a +monorepo with the implied goal of absorbing all of open source, but rather +a single module that other repositories can build upon, while ensuring a +baseline level of compatibility: which core attribute make up a flake and +how these are represented as module options. -# Example Flake +# Getting Started -```nix -{ - description = "A very basic flake"; +If your project does not have a flake yet: - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; +```console +nix flake init -t github:hercules-ci/flake-modules-core +``` + +Otherwise, add the input, + +``` flake-modules-core.url = "github:hercules-ci/flake-modules-core"; flake-modules-core.inputs.nixpkgs.follows = "nixpkgs"; - devshell.url = "github:hercules-ci/devshell/flake-modules"; # credit to numtide - }; +``` - outputs = { self, nixpkgs, flake-modules-core, devshell, ... }: +then slide `evalFlakeModule` between your outputs function head and body, + +``` + outputs = { self, flake-modules-core, ... }: (flake-modules-core.lib.evalFlakeModule { inherit self; } { - systems = [ "x86_64-linux" ]; - imports = [ - devshell.flakeModule - ]; flake = { - nixosConfigurations.foo = lib.nixosSystem { /* ... */ }; - }; - perSystem = system: { config, pkgs, self', inputs', ... }: { - _module.args.pkgs = inputs'.nixpkgs.legacyPackages; - devshell.settings.commands = [ - { - help = "format nix code"; - package = pkgs.nixpkgs-fmt; - } - ]; - packages.hello = pkgs.hello; - packages.hello2 = self'.packages.hello; - checks.hello = self'.packages.hello; - }; - }).config.flake; - -} + # Put your original flake attributes here. + } + } + ).config.flake; ``` + +Now you can add the remaining module attributes like in the [the template](./template/flake.nix). + +# Example + +See [the template](./template/flake.nix). diff --git a/all-modules.nix b/all-modules.nix index 0e8019f..bc194a5 100644 --- a/all-modules.nix +++ b/all-modules.nix @@ -3,6 +3,7 @@ imports = [ ./modules/checks.nix ./modules/devShell.nix + ./modules/flake.nix ./modules/legacyPackages.nix ./modules/packages.nix ./modules/perSystem.nix diff --git a/flake.nix b/flake.nix index 045bfca..e294346 100644 --- a/flake.nix +++ b/flake.nix @@ -7,8 +7,11 @@ outputs = { self, nixpkgs, ... }: { lib = import ./lib.nix { inherit (nixpkgs) lib; }; - flakeModules = { - core = ./all-modules.nix; + defaultTemplate = { + path = ./template; + description = '' + A minimal flake using flake-modules-core. + ''; }; }; diff --git a/lib.nix b/lib.nix index 1a1a71d..5f84901 100644 --- a/lib.nix +++ b/lib.nix @@ -16,6 +16,17 @@ let specialArgs = { inherit self flake-modules-core-lib; } // specialArgs; modules = [ ./all-modules.nix module ]; }; + + # For extending options in an already declared submodule. + # Workaround for https://github.com/NixOS/nixpkgs/issues/146882 + mkSubmoduleOptions = + options: + mkOption { + type = types.submoduleWith { + modules = [ { inherit options; } ]; + }; + }; }; + in flake-modules-core-lib diff --git a/modules/checks.nix b/modules/checks.nix index 5ef468a..f20bd56 100644 --- a/modules/checks.nix +++ b/modules/checks.nix @@ -8,13 +8,19 @@ let optionalAttrs types ; + inherit (flake-modules-core-lib) + mkSubmoduleOptions + ; in { options = { - flake = { + flake = mkSubmoduleOptions { checks = mkOption { type = types.lazyAttrsOf (types.lazyAttrsOf types.package); default = { }; + description = '' + Derivations to be built by nix flake check. + ''; }; }; }; @@ -38,6 +44,9 @@ in checks = mkOption { type = types.lazyAttrsOf types.package; default = { }; + description = '' + Derivations to be built by nix flake check. + ''; }; }; }; diff --git a/modules/devShell.nix b/modules/devShell.nix index 12ca2ac..27534db 100644 --- a/modules/devShell.nix +++ b/modules/devShell.nix @@ -8,13 +8,19 @@ let optionalAttrs types ; + inherit (flake-modules-core-lib) + mkSubmoduleOptions + ; in { options = { - flake = { + flake = mkSubmoduleOptions { devShell = mkOption { type = types.lazyAttrsOf types.package; default = { }; + description = '' + For each system a derivation that nix develop bases its environment on. + ''; }; }; }; @@ -37,6 +43,9 @@ in options = { devShell = mkOption { type = types.nullOr types.package; + description = '' + A derivation that nix develop bases its environment on. + ''; }; }; }; diff --git a/modules/flake.nix b/modules/flake.nix new file mode 100644 index 0000000..7202bee --- /dev/null +++ b/modules/flake.nix @@ -0,0 +1,27 @@ +{ config, lib, ... }: +let + inherit (lib) + filterAttrs + genAttrs + mapAttrs + mkOption + optionalAttrs + types + ; +in +{ + options = { + flake = mkOption { + type = types.submoduleWith { + modules = [ + { freeformType = types.lazyAttrsOf types.anything; } + ]; + }; + description = '' + Raw flake attributes. Any attribute can be set here, but some + attributes are represented by options, to provide appropriate + configuration merging. + ''; + }; + }; +} diff --git a/modules/legacyPackages.nix b/modules/legacyPackages.nix index 7e963c5..492984d 100644 --- a/modules/legacyPackages.nix +++ b/modules/legacyPackages.nix @@ -8,13 +8,19 @@ let optionalAttrs types ; + inherit (flake-modules-core-lib) + mkSubmoduleOptions + ; in { options = { - flake = { + flake = mkSubmoduleOptions { legacyPackages = mkOption { type = types.lazyAttrsOf (types.lazyAttrsOf types.anything); default = { }; + description = '' + Per system, an attribute set of anything. This is also used by nix build .#. + ''; }; }; }; @@ -38,6 +44,9 @@ in legacyPackages = mkOption { type = types.lazyAttrsOf types.anything; default = { }; + description = '' + An attribute set of anything. This is also used by nix build .#. + ''; }; }; }; diff --git a/modules/packages.nix b/modules/packages.nix index da2c234..3829800 100644 --- a/modules/packages.nix +++ b/modules/packages.nix @@ -8,13 +8,20 @@ let optionalAttrs types ; + inherit (flake-modules-core-lib) + mkSubmoduleOptions + ; in { options = { - flake = { + flake = mkSubmoduleOptions { packages = mkOption { type = types.lazyAttrsOf (types.lazyAttrsOf types.package); default = { }; + description = '' + Per system an attribute set of packages. + nix build .# will build packages... + ''; }; }; }; @@ -38,6 +45,10 @@ in packages = mkOption { type = types.lazyAttrsOf types.package; default = { }; + description = '' + An attribute set of packages to be built by nix build .#. + nix build .# will build packages.. + ''; }; }; }; diff --git a/modules/perSystem.nix b/modules/perSystem.nix index 5ee9193..5fcf86e 100644 --- a/modules/perSystem.nix +++ b/modules/perSystem.nix @@ -14,7 +14,6 @@ in systems = mkOption { description = "All the system types to enumerate in the flake."; type = types.listOf types.str; - default = [ ]; }; perInput = mkOption { diff --git a/modules/self.nix b/modules/self.nix deleted file mode 100644 index 38cf73b..0000000 --- a/modules/self.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ lib, ... }: { - options.self = lib.mkOption { - description = "The current flake."; - type = type.lazyAttrsOf type.unspecified; - }; -} diff --git a/template/flake.nix b/template/flake.nix new file mode 100644 index 0000000..7b1fd37 --- /dev/null +++ b/template/flake.nix @@ -0,0 +1,37 @@ +{ + description = /* ... */; + + inputs = { + flake-modules-core.url = "github:hercules-ci/flake-modules-core"; + flake-modules-core.inputs.nixpkgs.follows = "nixpkgs"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = { self, flake-modules-core, ... }: + (flake-modules-core.lib.evalFlakeModule + { inherit self; } + { + imports = [ + # To import a flake module + # 1. Add foo to inputs + # 2. Add foo as a parameter to the outputs function + # 3. Add here: foo.flakeModule + + ]; + systems = [ "x86_64-linux" "aarch64-darwin" ]; + perSystem = system: { config, self', inputs', ... }: { + # Per-system attributes can be defined here. The self' and inputs' + # module parameters provide easy access to attributes of the same + # system. + + packages.hello = inputs'.nixpkgs.legacyPackages.hello; + }; + flake = { + # The usual flake attributes can be defined here, including system- + # agnostic ones like nixosModule and system-enumerating ones, although + # those are more easily expressed in perSystem. + + }; + } + ).config.flake; +}