commit e0a85229daa6fb63d6ad7dcd8de6f2e26aa36711
parent 7c0465d649a5d3ff4a44488e0163be36983ec84b
Author: figsoda <figsoda@pm.me>
Date: Sun, 7 May 2023 22:34:14 -0400
parent 7c0465d649a5d3ff4a44488e0163be36983ec84b
Author: figsoda <figsoda@pm.me>
Date: Sun, 7 May 2023 22:34:14 -0400
docs: move to book
19 files changed, 487 insertions(+), 218 deletions(-)
A
|
101
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
|
73
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml @@ -0,0 +1,44 @@ +name: pages + +on: + push: + branches: + - main + +concurrency: pages + +jobs: + build: + name: build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install nix + uses: cachix/install-nix-action@v20 + + - name: Setup pages + uses: actions/configure-pages@v3 + + - name: Build docs + run: nix build ./docs + + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: result + + deploy: + name: deploy + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + permissions: + id-token: write + pages: write + steps: + - name: Deploy pages + id: deployment + uses: actions/deploy-pages@v2
diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +/docs/book +/docs/theme +result
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md @@ -9,8 +9,8 @@ This doesn't apply to bug fixes. - Discuss before opening a pull request, so your work doesn't go to waste. Anything from GitHub issues to Matrix discussions is fine. -- Update documentation accordingly. Everything in `haumea.lib` should to be documented. -- Add [tests](tests) when necessary. +- Update documentation accordingly. Everything in `haumea.lib` should be documented. +- Add [tests](https://github.com/nix-community/haumea/tree/main/tests) when necessary. Test your changes with `nix flake check`. Make sure new files are added to git. ## Scope
diff --git a/README.md b/README.md @@ -6,229 +6,31 @@ Haumea is not related to or a replacement for NixOS modules. It is closer to the module systems of traditional programming languages, with support for file hierarchy and visibility. -```bash -nix flake init -t github:nix-community/haumea -``` +Haumea's source code is hosted on [GitHub](https://github.com/nix-community/haumea) +under the [MPL-2.0](http://mozilla.org/MPL/2.0) license. -## Versioning +## Why Haumea? -Haumea follows [semantic versioning](https://semver.org). -Breaking changes can happen in main branch at any time, -so it is recommended to pin haumea to a specific tag. -A list of available versions can be found on the -[releases](https://github.com/nix-community/haumea/releases) page. +- No more manual imports -## Usage + Manually importing files can be tedious, especially when there are many of them. + Haumea takes care of all of that by automatically importing the files into an attribute set. -### [`load`](src/load.nix) +- Modules -Type: `{ src, loader?, inputs?, transformer? } -> { ... }` + Haumea takes inspiration from traditional programming languages. + Visibility makes it easy to create utility modules, + and haumea makes self-referencing and creating fixed points a breeze + with the introduction of `self`, `super`, and `root`. -Arguments: +- Organized directory layout -- `src` : `Path` + What you see is what you get. + By default[^1], the file tree will look exactly like the resulting attribute set. - The directory to load files from. +- Extensibility -- (optional) `loader` : `{ self, super, root, ... } -> Path -> a` + Changing how the files are loaded is as easy as specifying a `loader`, + and the `transformer` option makes it possible to extensively manipulate the tree. - Loader for the files, defaults to [`loaders.default`]. - -- (optional) `inputs` : `{ ... }` - - Extra inputs to be passed to the loader. - - `self`, `super`, and `root` are reserved names that cannot be passed as an input. - To work around that, remove them using `removeAttrs`, or pass them by overriding the loader. - -- (optional) `transformer` : `(cursor : [ String ]) -> { ... } -> a` or a list of transformers - - Module transformer, defaults to `[ ]` (no transformation). - This will transform each directory module in `src`, including the root. - `cursor` represents the position of the directory being transformed, where `[ ]` - means root and `[ "foo" "bar" ]` means `root.foo.bar`. - -The main entry point of haumea. This is probably the function you are looking for. - -Nix files found in `src` are loaded into an attribute set with the specified `loader`. -As an example, the entirety of haumea's API is `load`ed from the [src](src) directory. - -For a directory like this: - -``` -<src> -├─ foo/ -│ ├─ bar.nix -│ └─ __baz.nix -├─ _bar/ -│ └─ baz.nix -└─ baz.nix -``` - -The output will look like this: - -```nix -{ - foo.bar = <...>; - baz = <...>; -} -``` - -Notice that there is no `bar.baz`. -This is because files and directories that start with `_` are only visible inside the directory being loaded, -and will not be present in the final output. - -Similarly, files and directories that start with `__` are only visible if they are in the same directory, -meaning `foo/__bar.nix` is only accessible if it is being accessed from within `foo`. - -By default, the specified `inputs`, in addition to `self`, `super`, and `root`, -will be passed to the file being loaded, if the file is a function. - -- `self` represents the current file. -- `super` represents the directory the file is in. -- `root` represents the root of the `src` directory being loaded. - -Continuing the example above, this is the content of `foo/bar.nix` (`super` and `root` are unused, they are just here for demonstration purposes): - -```nix -{ self, super, root }: - -{ - a = 42; - b = self.a * 2; -} -``` - -`self.a` will be `42`, which will make `b` `84`. -Accessing anything other than `self.a` (e.g. `self.c`) will cause infinite recursion. - -`super` will be `{ bar = self; baz = <...>; }`. - -And `root` will be: - -```nix -{ - # foo = super; - foo = { - bar = <...>; - baz = <...>; - }; - baz = <...>; -} -``` - -Note that this is different from the return value of `load`. -`foo.baz` is accessible here because it is being accessed from within `foo`; - -### [`loadEvalTests`](src/loadEvalTests.nix) - -Type: `{ src, loader?, inputs? } -> { }` - -A wrapper around [`load`] to run eval tests using -[`runTests`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.debug.runTests). - -The accepted arguments are exactly the same as [`load`]. - -This function will throw an error if at least one test failed, -otherwise it will always return `{ }` (an empty attribute set). - -As an example, haumea's [tests](tests) are loaded with `loadEvalTests`. - -Alternatively, [namaka](https://github.com/nix-community/namaka) -provides utilities for snapshot testing, -which can save you some time from writing reference values. - -### [`loaders.callPackage`](src/loaders/callPackage.nix) - -Type: `{ self, super, root, ... } -> Path -> a` - -A wrapper around `callPackageWith`. -It adds `override` and `overrideDerivation` to the output (as `makeOverridable` does), -and requires the file being loaded to be a function that returns an attribute set. -Unlike [`loaders.default`], it will respect optional function arguments, -as they can be overridden with the added `override` attribute. - -### [`loaders.default`](src/loaders/default.nix) - -Type: `{ self, super, root, ... } -> Path -> a` - -This is the default loader. -It imports the file, and provides it the necessary inputs if the file is a function. - -Default values of optional function arguments will be ignored, e.g. -for `{ foo ? "bar" }: foo`, `"bar"` will be ignored, and it requires `inputs` to contain `foo`. -For that reason, although not strictly forbidden, optional arguments are discouraged since they are no-ops. - -### [`loaders.path`](src/loaders/path.nix) - -Type: `{ ... } -> Path -> Path` - -This loader will simply return the path of the file without `import`ing it. - -### [`loaders.scoped`](src/loaders/scoped.nix) - -Type: `{ self, super, root, ... } -> Path -> a` - -This is like [`loaders.default`], except it uses `scoepdImport` instead of `import`. -With this loader, you don't have to explicitly declare the inputs with a lambda, -since `scopedImport` will take care of it as if the file being loaded is wrapped with `with inputs;`. - -### [`loaders.verbatim`](src/loaders/verbatim.nix) - -Type: `{ ... } -> Path -> a` - -This loader will simply `import` the file without providing any input. -It is useful when the files being loaded are mostly functions that don't require any external input. - -### [`transformers.hoistAttrs`](src/transformers/hoistAttrs.nix) - -Type: `(from : String) -> (to : String) -> [ String ] -> { ... } -> { ... }` - -This transformer will hoist any attribute of type Attrs with key -`${from}` up the chain. When the root node is reached, it will -be renamed to an attribute of type Attrs with key `${to}` and -as such presented back to the consumer. - -Neighbouring lists are concatenated (`recursiveUpdate`) during hoisting. -Root doesn't concat `${from}` declarations, use `${to}` at the root. - -This can be used to declare `options` locally at the leaves -of the configuration tree, where the NixOS module system would -not otherwise tolerate them. - -### [`transformers.hoistLists`](src/transformers/hoistLists.nix) - -Type: `(from : String) -> (to : String) -> [ String ] -> { ... } -> { ... }` - -This transformer will hoist any attribute of type List with key -`${from}` up the chain. When the root node is reached, it will -be renamed to an attribute of type List with key `${to}` and -as such presented back to the consumer. - -Neighbouring lists are concatenated (`++`) during hoisting. -Root doesn't concat `${from}` declarations, use `${to}` at -the root. - -This can be used to declare `imports` locally at the leaves -of the configuration tree, where the NixOS module system would -not otherwise tolerate them. - -### [`transformers.liftDefault`](src/transformers/liftDefault.nix) - -Type: `[ String ] -> { ... } -> { ... }` - -This transformer will lift the contents of `default` into the module. -It will fail if `default` is not an attribute set, -or has any overlapping attributes with the module. - -## Alternatives - -[std](https://github.com/divnix/std) is a more full-featured framework that also has filesystem-based auto-importing. -Haumea has very different goals, with more focus on Nix libraries. - -[digga](https://github.com/divnix/digga) has similar functionality via `rakeLeaves`, -but it is more focused on system and home configurations, -and haumea has more features in this specific aspect. - -[`load`]: #load -[`loaders.default`]: #loadersdefault +[^1]: Unless you are doing transformer magic
diff --git a/docs/book.toml b/docs/book.toml @@ -0,0 +1,10 @@ +[book] +authors = ["figsoda"] +description = "Filesystem-based module system for Nix" +title = "haumea" + +[output.html] +edit-url-template = "https://github.com/nix-community/haumea/edit/main/docs/{path}" +git-repository-url = "https://github.com/nix-community/haumea" +preferred-dark-theme = "ayu" +site-url = "/haumea/"
diff --git a/docs/flake.lock b/docs/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1683408522, + "narHash": "sha256-9kcPh6Uxo17a3kK3XCHhcWiV1Yu1kYj22RHiymUhMkU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "897876e4c484f1e8f92009fd11b7d988a121a4e7", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +}
diff --git a/docs/flake.nix b/docs/flake.nix @@ -0,0 +1,39 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + }; + + outputs = { self, nixpkgs }: + let + inherit (nixpkgs.lib) + genAttrs + ; + + eachSystem = f: genAttrs + [ + "aarch64-darwin" + "aarch64-linux" + "x86_64-darwin" + "x86_64-linux" + ] + (system: f nixpkgs.legacyPackages.${system}); + in + { + packages = eachSystem (pkgs: { + default = pkgs.stdenv.mkDerivation { + pname = "haumea-docs"; + version = self.shortRev or "0000000"; + + src = ../. + "/docs"; + + nativeBuildInputs = [ pkgs.mdbook ]; + + buildPhase = '' + mkdir theme + ln -s ${pkgs.documentation-highlighter}/highlight.pack.js theme/highlight.js + mdbook build -d $out + ''; + }; + }); + }; +}
diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md @@ -0,0 +1,13 @@ +# Summary + +- [Introduction](intro/introduction.md) +- [Getting Started](intro/getting-started.md) +- [Versioning](intro/versioning.md) +- [API Reference](api/README.md) + - [`load`](api/load.md) + - [`loadEvalTests`](api/loadEvalTests.md) + - [`loaders`](api/loaders.md) + - [`transformers`](api/transformers.md) +- [Contributing to Haumea](notes/contributing.md) +- [See Also](notes/see-also.md) +- [Changelog](notes/changelog.md)
diff --git a/docs/src/api/README.md b/docs/src/api/README.md @@ -0,0 +1,5 @@ +# API Reference + +The following sections documents everything in the library. + +If you are using haumea with flakes, that would be `haumea.lib`.
diff --git a/docs/src/api/load.md b/docs/src/api/load.md @@ -0,0 +1,101 @@ +# `load` + +Source: [`src/load.nix`](https://github.com/nix-community/haumea/blob/main/src/load.nix) + +Type: `{ src, loader?, inputs?, transformer? } -> { ... }` + +Arguments: + +- `src` : `Path` + + The directory to load files from. + +- (optional) `loader` : `{ self, super, root, ... } -> Path -> a` + + Loader for the files, defaults to [`loaders.default`](loaders.html#loadersdefault). + +- (optional) `inputs` : `{ ... }` + + Extra inputs to be passed to the loader. + + `self`, `super`, and `root` are reserved names that cannot be passed as an input. + To work around that, remove them using `removeAttrs`, or pass them by overriding the loader. + +- (optional) `transformer` : `(cursor : [ String ]) -> { ... } -> a` or a list of transformers + + Module transformer, defaults to `[ ]` (no transformation). + This will transform each directory module in `src`, including the root. + `cursor` represents the position of the directory being transformed, + where `[ ]` means root and `[ "foo" "bar" ]` means `root.foo.bar`. + +Nix files found in `src` are loaded into an attribute set with the specified `loader`. +As an example, the entirety of haumea's API is `load`ed from the +[src](https://github.com/nix-community/haumea/tree/main/src) directory. + +For a directory like this: + +``` +<src> +├─ foo/ +│ ├─ bar.nix +│ └─ __baz.nix +├─ _bar/ +│ └─ baz.nix +└─ baz.nix +``` + +The output will look like this: + +```nix +{ + foo.bar = <...>; + baz = <...>; +} +``` + +Notice that there is no `bar.baz`. +This is because files and directories that start with `_` are only visible +inside the directory being loaded, and will not be present in the final output. + +Similarly, files and directories that start with `__` are only visible if they are in the same directory, +meaning `foo/__bar.nix` is only accessible if it is being accessed from within `foo`. + +By default, the specified `inputs`, in addition to `self`, `super`, and `root`, +will be passed to the file being loaded, if the file is a function. + +- `self` represents the current file. +- `super` represents the directory the file is in. +- `root` represents the root of the `src` directory being loaded. + +Continuing the example above, this is the content of `foo/bar.nix` (`super` and `root` are unused, they are just here for demonstration purposes): + +```nix +{ self, super, root }: + +{ + a = 42; + b = self.a * 2; +} +``` + +`self.a` will be `42`, which will make `b` `84`. +Accessing `self.b` here would cause infinite recursion, +and accessing anything else would fail due to missing attributes. + +`super` will be `{ bar = self; baz = <...>; }`. + +And `root` will be: + +```nix +{ + # foo = super; + foo = { + bar = <...>; + baz = <...>; + }; + baz = <...>; +} +``` + +Note that this is different from the return value of `load`. +`foo.baz` is accessible here because it is being accessed from within `foo`.
diff --git a/docs/src/api/loadEvalTests.md b/docs/src/api/loadEvalTests.md @@ -0,0 +1,22 @@ +# `loadEvalTests` + +Source: [`src/loadEvalTests.nix`](https://github.com/nix-community/haumea/blob/main/src/loadEvalTests.nix) + +Type: `{ src, loader?, inputs? } -> { }` + +A wrapper around [`load`] to run eval tests using +[`runTests`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.debug.runTests). + +The accepted arguments are exactly the same as [`load`]. + +This function will throw an error if at least one test failed, +otherwise it will always return `{ }` (an empty attribute set). + +As an example, haumea's [tests](https://github.com/nix-community/haumea/tree/main/tests) +are loaded with `loadEvalTests`. + +Alternatively, [namaka](https://github.com/nix-community/namaka) +provides utilities for snapshot testing, +which can save you some time from writing reference values. + +[`load`]: load.html
diff --git a/docs/src/api/loaders.md b/docs/src/api/loaders.md @@ -0,0 +1,55 @@ +# Loaders + +## `loaders.callPackage` + +Source: [`src/loaders/callPackage.nix`](https://github.com/nix-community/haumea/blob/main/src/loaders/callPackage.nix) + +Type: `{ self, super, root, ... } -> Path -> a` + +A wrapper around `callPackageWith`. +It adds `override` and `overrideDerivation` to the output (as `makeOverridable` does), +and requires the file being loaded to be a function that returns an attribute set. +Unlike [`loaders.default`], it will respect optional function arguments, +as they can be overridden with the added `override` attribute. + +## `loaders.default` + +Source: [`src/loaders/default.nix`](https://github.com/nix-community/haumea/blob/main/src/loaders/default.nix) + +Type: `{ self, super, root, ... } -> Path -> a` + +This is the default loader. +It imports the file, and provides it the necessary inputs if the file is a function. + +Default values of optional function arguments will be ignored, e.g. +for `{ foo ? "bar" }: foo`, `"bar"` will be ignored, and it requires `inputs` to contain `foo`. +For that reason, although not strictly forbidden, optional arguments are discouraged since they are no-ops. + +## `loaders.path` + +Source: [`src/loaders/path.nix`](https://github.com/nix-community/haumea/blob/main/src/loaders/path.nix) + +Type: `{ ... } -> Path -> Path` + +This loader will simply return the path of the file without `import`ing it. + +## `loaders.scoped` + +Source: [`src/loaders/scoped.nix`](https://github.com/nix-community/haumea/blob/main/src/loaders/scoped.nix) + +Type: `{ self, super, root, ... } -> Path -> a` + +This is like [`loaders.default`], except it uses `scoepdImport` instead of `import`. +With this loader, you don't have to explicitly declare the inputs with a lambda, +since `scopedImport` will take care of it as if the file being loaded is wrapped with `with inputs;`. + +## `loaders.verbatim` + +Source: [`src/loaders/verbatim.nix`](https://github.com/nix-community/haumea/blob/main/src/loaders/verbatim.nix) + +Type: `{ ... } -> Path -> a` + +This loader will simply `import` the file without providing any input. +It is useful when the files being loaded are mostly functions that don't require any external input. + +[`loaders.default`]: #loadersdefault
diff --git a/docs/src/api/transformers.md b/docs/src/api/transformers.md @@ -0,0 +1,48 @@ +# Transformers + +## `transformers.hoistAttrs` + +Source: [`src/transformers/hoistAttrs.nix`](https://github.com/nix-community/haumea/blob/main/src/transformers/hoistAttrs.nix) + +Type: `(from : String) -> (to : String) -> [ String ] -> { ... } -> { ... }` + +This transformer will hoist any attribute of type Attrs with key +`${from}` up the chain. When the root node is reached, it will +be renamed to an attribute of type Attrs with key `${to}` and +as such presented back to the consumer. + +Neighbouring lists are concatenated (`recursiveUpdate`) during hoisting. +Root doesn't concat `${from}` declarations, use `${to}` at the root. + +This can be used to declare `options` locally at the leaves +of the configuration tree, where the NixOS module system would +not otherwise tolerate them. + +## `transformers.hoistLists` + +Source: [`src/transformers/hoistLists.nix`](https://github.com/nix-community/haumea/blob/main/src/transformers/hoistLists.nix) + +Type: `(from : String) -> (to : String) -> [ String ] -> { ... } -> { ... }` + +This transformer will hoist any attribute of type List with key +`${from}` up the chain. When the root node is reached, it will +be renamed to an attribute of type List with key `${to}` and +as such presented back to the consumer. + +Neighbouring lists are concatenated (`++`) during hoisting. +Root doesn't concat `${from}` declarations, use `${to}` at +the root. + +This can be used to declare `imports` locally at the leaves +of the configuration tree, where the NixOS module system would +not otherwise tolerate them. + +## `transformers.liftDefault` + +Source: [`src/transformers/liftDefault.nix`](https://github.com/nix-community/haumea/blob/main/src/transformers/liftDefault.nix) + +Type: `[ String ] -> { ... } -> { ... }` + +This transformer will lift the contents of `default` into the module. +It will fail if `default` is not an attribute set, +or has any overlapping attributes with the module.
diff --git a/docs/src/intro/getting-started.md b/docs/src/intro/getting-started.md @@ -0,0 +1,73 @@ +# Getting Started + +Haumea comes with a template for a simple Nix library. +You can try out the template with: + +```bash +nix flake init -t github:nix-community/haumea +``` + +This will generate `flake.nix` and some other relevant files in the current directory. +Or if you want to create a new directory for this, run: + +```bash +nix flake new <dir> -t github:nix-community/haumea +``` + +You can use haumea without the template by adding it to your flake inputs: + +```nix +{{#include ../../../templates/default/flake.nix:2:8}} +``` + +Haumea is pinged to a tag here so potential breaking changes in the main +wouldn't break downstream consumers. +See the [Versioning](versioning.html) chapter for information. + +The rest of this chapter will be using this template. + +--- + +In `flake.nix`, the main thing you want to look at is `lib`: + +```nix +{{#include ../../../templates/default/flake.nix:18:23}} +``` + +`haumea.lib.load` is the main entry point of haumea. +It loads a directory (`./src`) of Nix files into an attribute set. +You can see the result of this by running `nix eval .#lib`: + +```nix +{ answer = 42; } +``` + +If you open `src/answer.nix`, you can see that it is a lambda that returns 42. + +```nix +{{#include ../../../templates/default/src/answer.nix}} +``` + +The `lib` here is provided by the `inputs` option of [`load`]: + +```nix +{{#include ../../../templates/default/flake.nix:20:22}} +``` + +The `lib.id 42` in `answer.nix` becomes `nixpkgs.lib.id 42`, which evaluates to 42. + +By default, the file doesn't have to specify the inputs that it does not use, +or even specify any inputs at all if it is not using any inputs. +Both `{ }: 42` and `42` are valid in this case and will do exactly the same thing. + +`self`, `super`, and `root` are special inputs that are always available. +You might already be familiar with them based on the names. +These names are reserved, haumea will throw an error if you try to override them. + +The documentation for [`load`] explains this more thoroughly and talks about some workarounds. + +`checks` works basically the same, just with +[`loadEvalTests`](../api/loadEvalTests.html) instead of [`load`]. +You can run the checks with `nix flake check`. + +[`load`]: ../api/load.html
diff --git a/docs/src/intro/introduction.md b/docs/src/intro/introduction.md @@ -0,0 +1 @@ +{{#include ../../../README.md}}
diff --git a/docs/src/intro/versioning.md b/docs/src/intro/versioning.md @@ -0,0 +1,8 @@ +# Versioning + +Haumea follows [semantic versioning](https://semver.org). +Breaking changes can happen on the main branch at any time, +so it is recommended to pin haumea to a specific tag. + +A list of available versions can be found on the +[GitHub releases](https://github.com/nix-community/haumea/releases) page.
diff --git a/docs/src/notes/changelog.md b/docs/src/notes/changelog.md @@ -0,0 +1 @@ +{{#include ../../../CHANGELOG.md}}
diff --git a/docs/src/notes/contributing.md b/docs/src/notes/contributing.md @@ -0,0 +1 @@ +{{#include ../../../CONTRIBUTING.md}}
diff --git a/docs/src/notes/see-also.md b/docs/src/notes/see-also.md @@ -0,0 +1,16 @@ +# See Also + +- [namaka](https://github.com/nix-community/namaka) is a snapshot testing tool + for Nix built on top of haumea with an interface similar to + [`loadEvalTests`](../api/loadEvalTests.html). + +- [paisano](https://github.com/paisano-nix/core) defines a directory structure + for auto-importing. It is currently being reimplemented with haumea on the + [paisano-haumea](https://github.com/paisano-nix/core/tree/paisano-haumea) branch. + +- [std](https://github.com/divnix/std) is a more full-featured framework based on + the directory structure defined by paisano. + Paisano was originally split out of std as a way to modularize std. + +- [hive](https://github.com/divnix/hive) is a project built on top of haumea and paisano + with a focus on building system and home configurations.