196 lines
5.4 KiB
Markdown
196 lines
5.4 KiB
Markdown
# AGENTS.md
|
|
|
|
Guide for AI coding agents working in this repository.
|
|
|
|
## Project Overview
|
|
|
|
This is a **pure Nix flake** project that exposes custom Nix packages, a development
|
|
shell, checks, and a nixpkgs overlay. All source files are written in the **Nix
|
|
expression language** (`.nix` files). There is no traditional programming language
|
|
involved -- this is purely Nix infrastructure/packaging code.
|
|
|
|
## Repository Structure
|
|
|
|
```
|
|
flake.nix # Main flake entry point (inputs, outputs, nixConfig)
|
|
flake.lock # Pinned flake dependency versions
|
|
.envrc # direnv integration ("use flake")
|
|
.gitignore # Ignores result, result-*, .direnv
|
|
pkgs/
|
|
default.nix # Package set aggregator (barrel file)
|
|
example-a/default.nix
|
|
example-b/default.nix
|
|
checks/
|
|
default.nix # Flake checks (formatting enforcement)
|
|
devshells/
|
|
default.nix # Development shell with tooling
|
|
overlays/
|
|
default.nix # Nixpkgs overlay re-exporting packages
|
|
```
|
|
|
|
Every directory uses `default.nix` as its entry point -- this is the Nix equivalent
|
|
of index/barrel files. The top-level `flake.nix` imports each module via
|
|
`import ./pkgs`, `import ./checks`, etc.
|
|
|
|
## Build / Check / Format Commands
|
|
|
|
```sh
|
|
# Build the default package
|
|
nix build
|
|
|
|
# Build a specific package
|
|
nix build .#example-a
|
|
nix build .#example-b
|
|
|
|
# Run all flake checks (currently: formatting validation)
|
|
nix flake check
|
|
|
|
# Format all Nix files (MUST pass before committing)
|
|
nixfmt flake.nix pkgs checks devshells overlays
|
|
|
|
# Check formatting without modifying files
|
|
nixfmt --check flake.nix pkgs checks devshells overlays
|
|
|
|
# Enter the development shell (provides nixfmt, nil, nix-tree)
|
|
nix develop
|
|
|
|
# View the dependency tree of a package
|
|
nix-tree .#example-a
|
|
|
|
# Update flake inputs
|
|
nix flake update
|
|
```
|
|
|
|
### Testing
|
|
|
|
There are no unit/integration tests. The only check is **formatting validation**
|
|
via `nix flake check`, which runs `nixfmt --check` against all `.nix` files.
|
|
Always run `nix flake check` before committing to ensure formatting is correct.
|
|
|
|
## Code Style Guidelines
|
|
|
|
### Formatter
|
|
|
|
**`nixfmt-rfc-style`** is enforced via `nix flake check`. Always format files with
|
|
`nixfmt` before committing. The formatter is available in the dev shell.
|
|
|
|
### Indentation and Whitespace
|
|
|
|
- **2 spaces** for indentation (no tabs)
|
|
- Opening brace on the same line as context
|
|
- Trailing semicolons on all attribute definitions
|
|
|
|
### Naming Conventions
|
|
|
|
| Entity | Convention | Examples |
|
|
|---------------------|----------------|---------------------------------------|
|
|
| Files / directories | `kebab-case` | `example-a`, `example-b` |
|
|
| Entry point files | `default.nix` | Always `default.nix` per directory |
|
|
| Attributes/variables| `camelCase` | `installPhase`, `buildInputs` |
|
|
| Package names | `kebab-case` | `example-a`, `nixfmt-rfc-style` |
|
|
|
|
### Function Parameters
|
|
|
|
Always list parameters **one per line** with a trailing comma, enclosed in braces:
|
|
|
|
```nix
|
|
{
|
|
lib,
|
|
stdenv,
|
|
}:
|
|
```
|
|
|
|
### Imports and Dependency Injection
|
|
|
|
- Use **relative path imports**: `import ./pkgs { inherit pkgs; }`
|
|
- Pass dependencies via **function arguments** (dependency injection), never globals
|
|
- Use `inherit` to concisely forward bindings: `{ inherit pkgs system; }`
|
|
- Use `pkgs.callPackage` to auto-inject dependencies into package definitions
|
|
|
|
### Package Definition Template
|
|
|
|
Every package follows this pattern:
|
|
|
|
```nix
|
|
{
|
|
lib,
|
|
stdenv,
|
|
}:
|
|
stdenv.mkDerivation {
|
|
pname = "package-name";
|
|
version = "0.1.0";
|
|
src = ./.;
|
|
|
|
installPhase = ''
|
|
# build/install commands
|
|
'';
|
|
|
|
meta = {
|
|
description = "Short description of the package";
|
|
license = lib.licenses.mit;
|
|
platforms = lib.platforms.all;
|
|
};
|
|
}
|
|
```
|
|
|
|
### Module / Barrel File Pattern
|
|
|
|
Aggregator files (`pkgs/default.nix`) collect sub-packages and define a default:
|
|
|
|
```nix
|
|
{ pkgs }:
|
|
let
|
|
self = {
|
|
example-a = pkgs.callPackage ./example-a { };
|
|
example-b = pkgs.callPackage ./example-b { };
|
|
};
|
|
in
|
|
self // { default = self.example-a; }
|
|
```
|
|
|
|
### Overlay Pattern
|
|
|
|
Overlays use `inherit` to selectively re-export packages:
|
|
|
|
```nix
|
|
final: prev:
|
|
let
|
|
customPkgs = import ../pkgs { pkgs = final; };
|
|
in
|
|
{
|
|
inherit (customPkgs) example-a example-b;
|
|
}
|
|
```
|
|
|
|
### Comments
|
|
|
|
- Prefer **self-documenting code** via `description` attributes in `meta` blocks
|
|
- Inline comments are used sparingly and only when the intent is non-obvious
|
|
- No JSDoc or similar documentation patterns -- Nix is declarative
|
|
|
|
### Error Handling
|
|
|
|
- Nix is a purely functional language; errors are build-time evaluation failures
|
|
- Use `assert` for preconditions when needed
|
|
- Use `lib.warn` or `lib.info` for non-fatal diagnostics
|
|
- Use `builtins.throw` for fatal errors with descriptive messages
|
|
|
|
### Flake Outputs
|
|
|
|
Follow the standard flake output schema:
|
|
|
|
- `packages.<system>.<name>` -- built packages
|
|
- `packages.<system>.default` -- the default package
|
|
- `devShells.<system>.default` -- development shell
|
|
- `checks.<system>.<name>` -- CI checks
|
|
- `overlays.default` -- nixpkgs overlay
|
|
|
|
The flake uses `flake-utils.lib.eachDefaultSystem` for multi-platform support.
|
|
|
|
## Dev Environment
|
|
|
|
- **direnv** auto-activates the dev shell (`.envrc` contains `use flake`)
|
|
- **nil** (Nix LSP) is available in the dev shell for editor integration
|
|
- **nix-tree** is available for inspecting dependency trees
|
|
- Binary cache: `nix-community.cachix.org` is configured as an extra substituter
|