divnix/std

repository·main·Indexed 19 days ago

https://github.com/divnix/std

A horizontal integration framework designed to wrap Nix-based component tools like devshell and nixago into a cohesive user experience. It uses Cells and Cell Blocks to automate repository tasks, CI/CD, and development environments across the Software Development Life Cycle (SDLC). The library provides utilities for data merging via std.dmerge, local Cell configuration with std.growOn, and a CLI/TUI for interacting with project blocks.

Tokens
14.7K
Snippets
58
Records
97
Agent score
67%

What's inside divnix-std

  1. Overview of the Standard Library

    main
    The divnix/std library is designed to cover the Software Delivery Life Cycle (SDLC) using a standardized approach. The library is organized into Cell Blocks, where each block focuses on a specific topic within the SDLC.
  2. Included tools in the minimal template

    main

    The minimal template provides a standardized development stack including:

    • devshell: For managing contribution environments.
    • treefmt: For consistent formatting across various file types.
    • mdbook: For generating and managing project documentation.
    • lefthook: For managing git hooks and maintaining commit discipline.
    • GitHub Setting App: For declarative GitHub configuration.
  3. Understand the structure of the `std` Cell

    main

    The std Cell is the primary entry point for the divnix/std repository and provides a collection of core utilities and environments. Its functionality is organized into the following components:

    • TUI (Terminal User Interface): Located in ./cli.
    • Devshell Profiles: Pre-configured development environments found in ./devshellProfiles.
    • Library Functions: Second-level library functions located in ./lib.
    • Proxied Packages: Packages used within std devshells are proxied in ./packages.
  4. What is The Registry?

    main

    In the context of std, The Registry refers to the .#__std flake output. It contains various Registers used for discovery purposes, such as:

    • CLI Discovery: Allowing the command line interface to find relevant metadata.
    • CI Discovery: Allowing Continuous Integration pipelines to identify desired pipeline targets.
  5. Standard's Component Model

    main

    Standard's value is delivered through a layered approach built on top of divnix/paisano:

    1. Core (Paisano): Provides the fundamental abstractions of Block Types (artifact classes with shared functionality) and Cells (organizational units).
    2. Standard Block Types: A collection of specific, audited implementations of artifact types (e.g., how to build a specific type of package).
    3. Standard Cells: A curated library of functions and integrations that users can adopt to implement their packaging pipelines.

    This modularity allows users to benefit from optimized, audited implementations of common DevOps tasks (like pushing containers or building packages) without reinventing them locally.

  6. Understand the `inputs` argument in Cell Blocks

    main

    The inputs argument provides access to de-systemized flake inputs and several special reserved inputs. These inputs are automatically scoped to the current system, reducing the need for manual system handling in most scenarios.

    Special inputs available in the inputs set:

    • self: The sourceInfo of the current repository.
    • nixpkgs: An instantiated nixpkgs instance.
    • cells: The other cells within the current repository.
    inputs = {
      self = {};    # sourceInfo of the current repository
      nixpkgs = {}; # an _instantiated_ nixpkgs
      cells = {};   # the other cells in this repo
    };
  7. How to use overlays in the Nix package collection

    main

    Because std avoids first-class support for fix-point logic (like global overlays) at the framework level to maintain local reasoning, users who need to apply overlays must scope them to a specific Cell Block.

    When working with the Nix package collection, you can apply overlays using the appendOverlays method. Note that every time you move the fix-point via appendOverlays, it triggers a complete re-evaluation of nixpkgs, which carries a small performance penalty but preserves the project's goal of balancing productivity with ease of onboarding.

    nixpkgs.appendOverlays [ /* ... */ ]
  8. Understand binary contracts in Standard and Debug OCI Images

    main

    When consuming images produced by mkStandardOCI, you can rely on specific binary paths (contracts) being present.

    Standard Images

    Standard images are minimal. The following paths are guaranteed:

    • /bin/entrypoint: Always present.
    • /bin/runtime: Always present; used to drop into the runtime environment.
    • /bin/live: Present only if livenessProbe was configured.
    • /bin/ready: Present only if readinessProbe was configured.

    Debug Images

    Debug images wrap standard images with additional debugging packages. They are less minimal and have a larger attack surface. The following paths are guaranteed:

    • /bin/entrypoint: Always present.
    • /bin/runtime: Always present; used to drop into the runtime environment.
    • /bin/debug: Always present; used to drop into the debugging environment.
    • /bin/live: Present only if livenessProbe was configured.
    • /bin/ready: Present only if readinessProbe was configured.
  9. Use the Cell Block interface for organized Nix code

    main

    In std, Cell Blocks enforce a standardized interface to promote separation of concerns and clear contracts. When implementing a Cell Block, you must use the {inputs, cell} shape:

    • cell: The local Cell context.
    • inputs: The deSystemizeed flake inputs, which include:
      • inputs.self: A reference to the source code (self.sourceInfo), which can be filtered using std.incl. This is preferred over misusing the global self.
      • inputs.cells: Access to other cells by their name, providing documented boundaries.
      • inputs.nixpkgs: An instantiated nixpkgs specifically for the current system.

    By using this interface, you move away from a morphing global context toward organized, predictable Nix code.

  10. How Paisano differs from flake-utils and flake-parts

    main

    When organizing Nix flakes, you can choose between specialized schema tools or Paisano's organization-focused approach:

    • flake-utils: A lightweight utility focused on generating flake outputs specifically for Nix CLI packaging and NixOS use cases.
    • flake-parts: A component aggregator that uses the NixOS module system to implement domain-specific interfaces (like packages or devShells) based on the Nix CLI schema.
    • Paisano: An importer focused on code organization. Unlike the tools above, Paisano is not optimized for a specific schema, giving you the freedom to use an output schema that fits your problem domain. It uses generic interfaces to connect high-level code boundaries while maintaining Nix's functional style.

    To bridge the gap between Paisano's flexible organization and the strict Nix Flakes output schema, use the harvester family of utility functions (winnow, harvest, and pick). Note that converting to the Flakes schema via these functions can be lossy due to the limited expressivity of the standard Flakes output schema.

  11. Understand the core concept of Nix as a configuration language

    main
    Nix is a functional configuration language designed to manage complexity in configuration management. While simple data formats (like JSON) are sufficient for basic tasks, Nix provides 'configuration combinators'—the ability to use a full-blown language to efficiently render complex configurations. It is conceptually similar to other configuration languages like dhall, cue, jsonnet, or nickel, but with unique capabilities regarding dependency tracking.