- 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)
474 lines
10 KiB
Markdown
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`).
|