Haumea Documentation
repository·main·Indexed 19 days ago
https://github.com/nix-community/haumeaA filesystem-based module system for Nix that maps directory structures into attribute sets. Haumea provides automatic imports, visibility rules via underscore prefixes, and hierarchical references using self, super, and root. It includes a flexible API for loading files via custom loaders and matchers (supporting Nix, JSON, TOML, and regex), as well as transformers like hoistAttrs and hoistLists to manipulate the resulting attribute tree.
What's inside Haumea
- Haumea is a tool designed to help users manage and interact with Nix flakes and Nix configurations more effectively. It provides a structured way to explore, manage, and potentially automate tasks related to Nix ecosystem components, specifically focusing on making Nix flake management more intuitive.
Key features of Haumea
mainHaumea provides several core benefits for Nix developers:
- Automatic Imports: Eliminates the need for manual
import ./path/to/file.nixstatements by automatically loading files into an attribute set. - Module Abstractions: Introduces
self,super, androotto facilitate self-referencing, fixed points, and hierarchical access. - Organized Layout: The attribute set structure matches the filesystem layout by default.
- Extensibility: Users can customize the loading process using a
loaderor manipulate the resulting tree using atransformer.
- Automatic Imports: Eliminates the need for manual
What is Haumea?
mainHaumea is a filesystem-based module system for Nix. Unlike NixOS modules, Haumea functions more like the module systems found in traditional programming languages, providing support for file hierarchies and visibility.
Its primary function is to map a directory of Nix files into a structured attribute set, where the directory structure is preserved in the resulting attribute tree.
How Haumea maps files to attribute sets
mainHaumea automatically converts a directory tree of
.nixfiles into a nested attribute set. By default, the resulting attribute set mirrors the file hierarchy.Files prefixed with
__(e.g.,__internal.nix) or located in directories like_utils/are handled according to visibility rules (though the specific mapping for these prefixes is part of the internal module logic), allowing you to organize code without manual imports.# Example mapping: # From: # ├─ foo/ # │ ├─ bar.nix # │ ├─ baz.nix # │ └─ __internal.nix # ├─ bar.nix # └─ _utils/ # └─ foo.nix # To: { foo = { bar = <...>; baz = <...>; }; bar = <...>; }How Matchers work in Haumea
mainMatchers allow Haumea to load non-Nix files by defining how to identify a file and how to parse it. Matchers are used with the
loaderoption of theloadfunction.How matching works
When Haumea evaluates a file, it passes the filename to the
matchesfunction. The filename is processed by removing up to two preceding underscores (_). For example:bar.nixbecomesbar.nixfoo/__bar.nixbecomesbar.nix
How loading works
The
loaderfunction in a matcher works identically to a standard loader function passed toload. It receives the standard context ({ self, super, root, ... }) and thePathto the file.Attribute naming convention
When using matchers, the resulting attribute name in the loaded set is the filename with its last extension removed.
foo.nix$\rightarrow$foobar/_foo.nix$\rightarrow$foobaz/foo$\rightarrow$foofar.bar.baz$\rightarrow$far.bar
Understand `self`, `super`, and `root` in loaded files
mainWhen a file loaded by
loadis a function, Haumea automatically passes three reserved arguments to it:self: Represents the current file's own attribute set (the result of the function's own evaluation).super: Represents the attribute set of the directory containing the current file.root: Represents the entire attribute set produced by theloadcall at thesrcroot.
Example Usage
If
foo/bar.nixcontains:{ self, super, root }: { a = 42; b = self.a * 2; }self.awill be42.self.bwill be84.superwill contain the other files in thefoo/directory (e.g.,bar,baz, and__internalfiles).rootwill contain the full structure of thesrcdirectory.
{ self, super, root }: { a = 42; b = self.a * 2; }Pin Haumea to a specific version tag
mainHaumea follows semantic versioning. Because breaking changes can occur on the
mainbranch at any time, it is highly recommended to pin your Haumea dependency to a specific version tag to ensure build stability and prevent unexpected breakage in your environment.You can find a list of all available stable versions on the GitHub releases page.
Initialize a new project using the Haumea template
mainYou can quickly scaffold a new Nix library project using the Haumea template. This generates a
flake.nixand other necessary files in your current directory.To initialize in the current directory:
nix flake init -t github:nix-community/haumeaTo initialize in a new directory:
nix flake new <dir> -t github:nix-community/haumeanix flake init -t github:nix-community/haumeaAccess Haumea functions via Nix Flakes
mainIf you are using Haumea within a Nix Flake, the library's functions and logic are exposed through thehaumea.libattribute. Use this attribute to access the core API when building your Nix expressions.Run Haumea evaluation tests
mainTo verify your library, you can use
haumea.lib.loadEvalTests(which behaves similarly toload) to define tests. You can execute these checks using the standard Nix command:nix flake checknix flake checkUse Haumea without the template
mainIf you do not want to use the full template, you can simply add Haumea as a flake input in your existing
flake.nix. It is recommended to pin Haumea to a specific tag to avoid breaking changes from themainbranch.inputs.haumea.url = "github:nix-community/haumea/v0.2.2";Use `loaders.path` to retrieve a file path
mainUse
loaders.pathwhen you simply need the filesystem path of a file without actually importing or evaluating its contents.Type: `{ ... } -> Path -> Path`