Home

Awesome

<!-- SPDX-FileCopyrightText: 2022 The Standard Authors SPDX-License-Identifier: Unlicense -->

Paisano Core

Organize your Flakes-based projects

Paisano implements an API for organizing Nix code into folders.

It then maps that folder structure into Flake outputs, once per system.

To type outputs, an output type system is provided and traits (i.e. "abstract behaviour") may be implemented on them.

Motivation

Nix flakes make it easy to create self-contained projects with a common top-level interface that has been standardized througout the Nix Community. However, as an upstream standard it was built (mostly) for the packaging use case of Nix in the context of small package-centric repositories. It is, therefore, less suited for a DevOps centric usage pattern.

With Paisano, we attempt to solve the following problems:

Terminology

Regsitry Schema Spec

The current schema version is v0 (unstable).

The Jsonschema specification of the registry can be found inside ./registry.schema.json. It can be explored interactively with this link.

Usage

# flake.nix
{
  inputs.paisano.url = "github:divnix/paisano";
  inputs.paisano.inputs.nixpkgs.follows = "nixpkgs";

  outputs = { paisano, self }@inputs:
    paisano.growOn {
      /*
        the grow function needs `inputs` to desystemize
        them and make them available to your cell blocks
      */
      inherit inputs;
      /*
        sepcify from where to grow the cells
        `./nix` is a typical choice that signals
        to everyone where the nix code lies
      */
      cellsFrom = ./nix;
      /*
        These blocks may or may not be found in a particular cell.
        But blocks that aren't defined here, cannot exist in any cell.
      */
      cellBlocks = [
        {
          /*
            Because the name is `mycellblock`, paisano's importer
            will be hooking into any file `<cell>/mycellblock.nix`
            or `<cell>/mycellblock/default.nix`.
            Block tragets are exposed under:
            #<system>.<cell>.<block>.<target>
          */
          name = "mycellblock";
          type = "mytype";

          /*
            Optional

            Actions are exposed in paisano's "registry" under
            #__std.actions.<system>.<cell>.<block>.<target>.<action>
          */
          actions = {
            system,
            flake,
            fragment,
            fragmentRelPath,
          }: [
            {
              name = "build";
              description = "build this target";
              command = ''
                nix build ${flake}#${fragment}
              '';
            }
          ];
          /*
            Optional

            The CI registry flattens the targets and
            the actions to run for each target into a list
            so that downstream tooling can discover what to
            do in the CI. The invokable action is determined
            by the attribute name: ci.<action> = true

            #__std.ci.<system> = [ {...} ... ];
          */
          ci.build = true;
        }
      ];
    }
    {
      /* Soil */
      # Here, we make our domain layout compatible with the Nix CLI, among others
      devShells = paisano.harvest self [ "<cellname>" "<blockname>"];
      packages = paisano.winnow (n: v: n == "<targetname>" && v != null ) self [ "<cellname>" "<blockname>"];
      templates = paisano.pick self [ "<cellname>" "<blockname>"];
    };
}