Files
nixpkgs/docs/ARCHITECTURE.md
m3tm3re 44485c4c72 docs: update zellij-ps to reflect project switcher functionality
- Update package description and fix mainProgram typo
- Rewrite documentation to describe project switching, not process viewing
- Add PROJECT_FOLDERS configuration and usage examples
- Update all references across docs (README, guides, module overviews)
2025-12-30 15:42:52 +01:00

474 lines
10 KiB
Markdown

# Architecture
Understanding the design and structure of m3ta-nixpkgs.
## Overview
m3ta-nixpkgs is organized as a modern Nix flake with a focus on reusability, consistency, and maintainability. The repository follows clear conventions and patterns to make it easy to understand, extend, and contribute to.
## Repository Structure
```
m3ta-nixpkgs/
├── flake.nix # Main entry point, defines all outputs
├── pkgs/ # Custom packages (callPackage registry)
│ ├── default.nix # Package registry (entry point)
│ ├── code2prompt/ # Individual packages
│ ├── hyprpaper-random/
│ ├── mem0/
│ └── ...
├── modules/
│ ├── nixos/ # NixOS modules
│ │ ├── default.nix # Module aggregator
│ │ ├── mem0.nix
│ │ └── ports.nix
│ └── home-manager/ # Home Manager modules
│ ├── default.nix # Module aggregator
│ ├── ports.nix
│ ├── cli/ # Categorized modules
│ │ ├── default.nix
│ │ └── zellij-ps.nix
│ └── coding/
│ ├── default.nix
│ └── editors.nix
├── lib/ # Shared utilities
│ ├── default.nix # Library aggregator
│ └── ports.nix # Port management functions
├── shells/ # Development environments
│ ├── default.nix # Shell registry
│ ├── python.nix
│ └── devops.nix
├── overlays/ # Package modifications
│ ├── default.nix # Overlay aggregator
│ └── mods/
│ └── default.nix # Individual overlays
├── templates/ # Boilerplate for new items
│ ├── package/
│ ├── nixos-module/
│ └── home-manager-module/
├── examples/ # Usage examples
│ ├── nixos-configuration.nix
│ └── home-manager-standalone.nix
└── docs/ # Documentation
```
## Flake Outputs
`flake.nix` is the entry point that defines all outputs:
### Packages
```nix
packages = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./pkgs {inherit pkgs;});
```
- Built for all supported systems
- Uses `callPackage` pattern for lazy evaluation
- Available via `nix build .#<package-name>`
### Overlays
```nix
overlays = {
# Default overlay: adds all custom packages
default = final: prev: import ./pkgs {pkgs = final;};
# Additions overlay: same as default
additions = final: prev: import ./pkgs {pkgs = final;};
# Modifications overlay: modifies existing nixpkgs packages
modifications = final: prev: import ./overlays/mods {inherit prev;};
};
```
- `default`: Adds all custom packages to nixpkgs
- `additions`: Individual package additions
- `modifications`: Overrides existing packages
### NixOS Modules
```nix
nixosModules = {
default = ./modules/nixos; # Import all modules
ports = ./modules/nixos/ports.nix; # Specific module
mem0 = ./modules/nixos/mem0.nix;
};
```
- System-level configuration modules
- Use `m3ta.*` namespace
- Can import all modules or individual ones
### Home Manager Modules
```nix
homeManagerModules = {
default = import ./modules/home-manager;
ports = import ./modules/home-manager/ports.nix;
zellij-ps = import ./modules/home-manager/zellij-ps.nix;
};
```
- User-level configuration modules
- Categorized by function (cli, coding)
- Use `m3ta.*` namespace
### Library Functions
```nix
lib = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./lib {lib = pkgs.lib;});
```
- Helper functions for configuration
- Port management utilities
- Can be used in your configurations
### Development Shells
```nix
devShells = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./shells {inherit pkgs;});
```
- Pre-configured development environments
- Available: `default`, `python`, `devops`
- Usage: `nix develop .#<shell-name>`
### Templates
```nix
templates = {
package = {
path = ./templates/package;
description = "Template for a new package";
};
nixos-module = {
path = ./templates/nixos-module;
description = "Template for a new NixOS module";
};
home-manager-module = {
path = ./templates/home-manager-module;
description = "Template for a new Home Manager module";
};
};
```
- Boilerplate for quick start
- Usage: `nix flake init -t .#template-name`
## Package Organization
### Registry Pattern
`pkgs/default.nix` acts as a central registry:
```nix
{
inherit (pkgs) callPackage;
} rec {
code2prompt = callPackage ./code2prompt {};
hyprpaper-random = callPackage ./hyprpaper-random {};
mem0 = callPackage ./mem0 {};
# ...
}
```
**Benefits**:
- Lazy evaluation: only builds requested packages
- Consistent interface: all packages use `callPackage`
- Easy discovery: one file lists all packages
### Package Structure
Each package lives in its own directory:
```
pkgs/your-package/
├── default.nix # Package definition
├── source.py # Optional: source files
└── README.md # Optional: package documentation
```
**Conventions**:
- Directory name matches registry attribute
- Use `callPackage` for dependencies
- Always include `meta` with all fields
### Common Package Patterns
#### Rust Packages
```nix
rustPlatform.buildRustPackage rec {
pname = "myapp";
version = "1.0.0";
src = fetchFromGitHub { ... };
cargoLock.lockFile = src + "/Cargo.lock";
# ...
}
```
#### Python Packages
```nix
python3.pkgs.buildPythonPackage rec {
pname = "mypythonapp";
version = "1.0.0";
src = fetchFromGitHub { ... };
dependencies = with python3.pkgs; [requests click];
# ...
}
```
#### Shell Scripts
```nix
writeShellScriptBin "myscript" ''
#!/usr/bin/env bash
echo "Hello World"
''
```
#### AppImage
```nix
appimageTools.wrapType2 rec {
name = "myapp";
src = fetchurl { ... };
# ...
}
```
## Module Organization
### NixOS Modules
Located in `modules/nixos/`:
```
modules/nixos/
├── default.nix # Imports all modules
├── ports.nix # Port management
├── mem0.nx # Individual module
```
**Pattern**:
```nix
{config, lib, pkgs, ...}:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "description";
# ... options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
### Home Manager Modules
Located in `modules/home-manager/` with categories:
```
modules/home-manager/
├── default.nix # Imports all modules
├── ports.nix # Port management
├── cli/
│ ├── default.nix # Aggregates CLI modules
│ └── zellij-ps.nix
└── coding/
├── default.nix # Aggregates coding modules
└── editors.nix
```
**Categories**:
- `cli/`: Command-line tools and utilities
- `coding/`: Development tools and editors
**Pattern** (same as NixOS):
```nix
{config, lib, pkgs, ...}:
with lib; let
cfg = config.m3ta.coding.editors;
in {
options.m3ta.coding.editors = {
enable = mkEnableOption "editor configuration";
# ... options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
## Library Functions
Located in `lib/`:
```nix
{lib}: {
# Port management utilities
ports = import ./ports.nix {inherit lib;};
}
```
### Port Management
Centralized port management across hosts:
```nix
# Usage in configuration
portHelpers = inputs.m3ta-nixpkgs.lib.${system}.ports.mkPortHelpers myPorts;
# Get port with host override
services.nginx.port = portHelpers.getPort "nginx" "laptop";
# Get all ports for host
allLaptopPorts = portHelpers.getHostPorts "laptop";
```
**Benefits**:
- Single source of truth for ports
- Host-specific overrides
- Avoid port conflicts
## Naming Conventions
| Context | Convention | Example |
|---------|------------|---------|
| Packages | `lowercase-hyphen` | `hyprpaper-random` |
| Variables | `camelCase` | `portHelpers` |
| Module options | `m3ta.*` | `m3ta.ports.enable` |
| Files | `lowercase-hyphen` | `my-module.nix` |
| Directories | `lowercase-hyphen` | `cli/`, `coding/` |
## Code Patterns
### Module Options
Always use `mkEnableOption` for enable flags:
```nix
options.m3ta.myModule = {
enable = mkEnableOption "description";
};
```
### Conditional Configuration
Use `mkIf` for conditional config:
```nix
config = mkIf cfg.enable {
# Only applied when cfg.enable is true
};
```
### Multiple Conditions
Use `mkMerge` for multiple conditions:
```nix
config = mkMerge [
(mkIf cfg.feature1.enable { ... })
(mkIf cfg.feature2.enable { ... })
];
```
### Imports
Multi-line, trailing commas:
```nix
{
lib,
stdenv,
fetchFromGitHub,
}:
```
### Meta Fields
Always include all fields:
```nix
meta = with lib; {
description = "...";
homepage = "...";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
```
## Design Decisions
### Flakes-Only
**Decision**: Use flakes exclusively, no channels.
**Rationale**:
- Reproducible builds
- Explicit dependencies
- Better integration with modern Nix tooling
### CallPackage Pattern
**Decision**: Use `callPackage` for all packages.
**Rationale**:
- Lazy evaluation
- Clear dependency graph
- Consistent interface
### Module Categorization
**Decision**: Categorize Home Manager modules by function.
**Rationale**:
- Easier to find related modules
- Logical organization
- Follows user mental model
### Port Management
**Decision**: Centralized port management with host overrides.
**Rationale**:
- Avoid port conflicts
- Easy to manage multiple hosts
- Single source of truth
### Namespace Convention
**Decision**: Use `m3ta.*` namespace for all modules.
**Rationale**:
- Avoid conflicts
- Clear attribution
- Easy to discover
## Supported Systems
- `x86_64-linux` - Primary development target
- `aarch64-linux` - ARM Linux
- `x86_64-darwin` - macOS Intel
- `aarch64-darwin` - macOS Apple Silicon
**Note**: Some packages may be Linux-only (check `meta.platforms`).