From 63a8dfab9c207ead3acb70f1440bf04457a14af6 Mon Sep 17 00:00:00 2001 From: technofab Date: Tue, 2 Sep 2025 15:57:28 +0200 Subject: [PATCH] docs: write docs --- docs/index.md | 104 +++++++++++ docs/integrations.md | 3 + docs/usage.md | 423 +++++++++++++++++++++++++++++++++++++++++++ nix/repo/docs.nix | 2 + 4 files changed, 532 insertions(+) create mode 100644 docs/integrations.md create mode 100644 docs/usage.md diff --git a/docs/index.md b/docs/index.md index 36a0d45..986e3aa 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1 +1,105 @@ # Soonix + +Soonix is a lightweight, declarative tool for managing configuration files, build scripts, and other project assets using the Nix module system. It provides a clean alternative to Nixago with reduced complexity and removed legacy code. + +## What is Soonix? + +Soonix helps you: + +- **Generate configuration files** from Nix data structures +- **Template complex configurations** using Go templates or Jinja2 +- **Manage file lifecycles** automatically with shell hooks +- **Keep generated files in sync** with your Nix configuration +- **Integrate seamlessly** with development environments + +## Key Features + +### Multiple Generation Engines + +- **nix**: Convert Nix data to JSON, YAML, TOML, INI, XML formats +- **string**: Output raw string content with optional executable permissions +- **derivation**: Use existing Nix derivations as file content +- **gotmpl**: Advanced Go template rendering via gomplate +- **jinja**: Python Jinja2 template rendering + +### Automatic File Management + +Shell hooks automatically update files when entering your development environment, with intelligent change detection and status reporting. + +### Flexible File Handling + +Choose between symlinks or file copies on a per-file basis. + +### GitIgnore Integration + +Automatically manage .gitignore entries for generated files to keep your repository clean. + +## Quick Example + +```nix +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + soonix.url = "gitlab:TECHNOFAB/soonix?dir=lib"; + }; + + outputs = { nixpkgs, soonix, ... }: let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + + shellHook = (soonix.lib { inherit pkgs; }).mkShellHook { + hooks = { + eslintrc = { + output = ".eslintrc.json"; + generator = "nix"; + data = { + extends = ["eslint:recommended"]; + rules = { + "no-unused-vars" = "error"; + }; + }; + opts = { format = "json"; }; + }; + + dockerfile = { + output = "Dockerfile"; + generator = "gotmpl"; + data = { + baseImage = "node:18-alpine"; + port = 3000; + }; + opts.template = ./templates/dockerfile.tmpl; + }; + }; + }; + in { + devShells.${system}.default = pkgs.mkShell { + packages = [ pkgs.nodejs pkgs.docker ]; + inherit shellHook; + }; + }; +} +``` + +When you enter this development environment, Soonix will: + +1. Generate `.eslintrc.json` with your ESLint configuration +1. Render `Dockerfile` from your template with the provided data +1. Add both files to `.gitignore` automatically +1. Report status of file updates + +## Why Soonix over Nixago? + +Soonix is designed as a cleaner, more maintainable alternative to Nixago: + +- **Reduced complexity**: Streamlined codebase without legacy features +- **Better error handling**: Clear error messages and status reporting +- **Modern architecture**: Built with current Nix best practices +- **Focused scope**: Does one thing well rather than trying to be everything + +## Getting Started + +Ready to start using Soonix? Check out the [Usage Guide](./usage.md) for detailed +setup instructions and examples, or browse the [Integration Guide](./integrations.md) +to see how to use Soonix with different development tools and frameworks. + diff --git a/docs/integrations.md b/docs/integrations.md new file mode 100644 index 0000000..76698bb --- /dev/null +++ b/docs/integrations.md @@ -0,0 +1,3 @@ +# Integrations + +- [Nix-GitLab-CI](https://nix-gitlab-ci.projects.tf/soonix) diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..2153ab2 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,423 @@ +--- +render_macros: false +--- + +# Usage Guide + +This guide covers how to use Soonix to manage your project's configuration files, templates, and other assets. + +## Installation + +Add Soonix to your flake inputs: + +```nix +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + soonix.url = "gitlab:TECHNOFAB/soonix?dir=lib"; + }; +} +``` + +## Basic Usage + +### 1. Simple Configuration File Generation + +Generate a JSON configuration file from Nix data: + +```nix +let + shellHook = (soonix.lib { inherit pkgs; }).mkShellHook { + hooks = { + package-json = { + output = "package.json"; + generator = "nix"; + data = { + name = "my-project"; + version = "1.0.0"; + scripts = { + dev = "vite dev"; + build = "vite build"; + }; + dependencies = { + vite = "^4.0.0"; + }; + }; + opts = { format = "json"; }; + }; + }; + }; +in + pkgs.mkShell { inherit shellHook; } +``` + +### 2. Multiple Format Support + +The `nix` generator supports various formats: + +```nix +hooks = { + # YAML configuration + docker-compose = { + output = "docker-compose.yml"; + generator = "nix"; + data = { + version = "3.8"; + services = { + web = { + image = "nginx:alpine"; + ports = ["80:80"]; + }; + }; + }; + opts = { format = "yaml"; }; + }; + + # TOML configuration + pyproject = { + output = "pyproject.toml"; + generator = "nix"; + data = { + build-system = { + requires = ["hatchling"]; + build-backend = "hatchling.build"; + }; + project = { + name = "my-python-project"; + version = "0.1.0"; + }; + }; + opts = { format = "toml"; }; + }; +}; +``` + +### 3. Template-Based Generation + +Use Go templates for more complex file generation: + +```nix +hooks = { + dockerfile = { + output = "Dockerfile"; + generator = "gotmpl"; + data = { + baseImage = "node:18-alpine"; + workdir = "/app"; + port = 3000; + deps = ["curl" "git"]; + }; + opts.template = pkgs.writeText "dockerfile.tmpl" '' + FROM {{ .baseImage }} + + WORKDIR {{ .workdir }} + + {{- if .deps }} + RUN apk add --no-cache \ + {{- range $i, $dep := .deps }} + {{- if $i }} \{{- end }} + {{ $dep }} + {{- end }} + {{- end }} + + COPY package*.json ./ + RUN npm ci --only=production + + COPY . . + + EXPOSE {{ .port }} + CMD ["npm", "start"] + ''; + }; +}; +``` + +### 4. Jinja2 Templates + +For Python-style templating: + +```nix +hooks = { + nginx-config = { + output = "nginx.conf"; + generator = "jinja"; + data = { + server_name = "example.com"; + port = 80; + root = "/var/www/html"; + locations = [ + { path = "/api"; proxy_pass = "http://backend:8000"; } + { path = "/static"; root = "/var/www/static"; } + ]; + }; + opts.template = pkgs.writeText "nginx.conf.j2" '' + server { + listen {{ port }}; + server_name {{ server_name }}; + root {{ root }}; + + {% for location in locations %} + location {{ location.path }} { + {% if location.proxy_pass %} + proxy_pass {{ location.proxy_pass }}; + {% elif location.root %} + root {{ location.root }}; + {% endif %} + } + {% endfor %} + } + ''; + }; +}; +``` + +### 5. Script Generation + +Create executable scripts: + +```nix +hooks = { + dev-script = { + output = "scripts/dev.sh"; + generator = "string"; + data = '' + #!/usr/bin/env bash + set -euo pipefail + + echo "Starting development environment..." + + # Start database + docker-compose up -d postgres + + # Run migrations + npm run db:migrate + + # Start dev server + npm run dev + ''; + opts.executable = true; + }; +}; +``` + +### 6. Using Existing Derivations + +Include pre-built files or derivations: + +```nix +hooks = { + config-file = { + output = ".myapprc"; + generator = "derivation"; + data = pkgs.writeText "myapprc" '' + # Generated configuration + api_url = "https://api.example.com" + debug = true + ''; + }; +}; +``` + +## Hook Configuration + +### File Management Modes + +Control how files are managed: + +```nix +hooks = { + # Symlink mode (default) + dev-config = { + output = "config.json"; + generator = "nix"; + data = { debug = true; }; + hook.mode = "link"; # Creates symlinks + }; + + # Copy mode - for tools that don't support symlinks or file is not gitignored and needs to be portable + editable-config = { + output = "editable.json"; + generator = "nix"; + data = { editable = true; }; + hook.mode = "copy"; # Copies files + }; +}; +``` + +### GitIgnore Management + +Control .gitignore entries: + +```nix +hooks = { + # Don't add to gitignore (you want to commit this file) + committed-config = { + output = "config.json"; + generator = "nix"; + data = { production = true; }; + hook.gitignore = false; + }; + + # Auto-add to gitignore (default behavior) + generated-file = { + output = "temp.json"; + generator = "nix"; + data = { temp = true; }; + hook.gitignore = true; # Default + }; +}; +``` + +### Post-Processing Commands + +Run commands after file operations: + +```nix +hooks = { + formatted-json = { + output = "package.json"; + generator = "nix"; + data = { /* ... */ }; + hook = { + mode = "copy"; + extra = "npx prettier --write package.json"; + }; + }; + + executable-script = { + output = "build.sh"; + generator = "string"; + data = "#!/bin/bash\necho 'Building...'"; + hook.extra = "chmod +x build.sh"; + }; +}; +``` + +## Advanced Usage + +### Environment-Specific Configurations + +```nix +let + mkConfig = env: { + database_url = if env == "development" + then "sqlite:///dev.db" + else "postgresql://prod-db:5432/app"; + debug = env == "development"; + log_level = if env == "development" then "debug" else "info"; + }; +in { + hooks = { + dev-config = { + output = "config.dev.json"; + generator = "nix"; + data = mkConfig "development"; + opts = { format = "json"; }; + }; + + prod-config = { + output = "config.prod.json"; + generator = "nix"; + data = mkConfig "production"; + opts = { format = "json"; }; + }; + }; +} +``` + +### Complex Template Logic + +```nix +hooks = { + kubernetes-manifest = { + output = "k8s/deployment.yaml"; + generator = "gotmpl"; + data = { + app = { + name = "my-app"; + version = "1.2.3"; + replicas = 3; + port = 8080; + }; + env = [ + { name = "NODE_ENV"; value = "production"; } + { name = "PORT"; value = "8080"; } + ]; + secrets = [ + { name = "DB_PASSWORD"; secretName = "db-secret"; key = "password"; } + ]; + resources = { + requests = { memory = "128Mi"; cpu = "100m"; }; + limits = { memory = "512Mi"; cpu = "500m"; }; + }; + }; + opts.template = ./templates/deployment.yaml.tmpl; + }; +}; +``` + +## Integration Patterns + +### With Development Shells + +Standard mkShell integration: + +```nix +pkgs.mkShell { + packages = with pkgs; [ nodejs python3 docker ]; + shellHook = soonix.mkShellHook { inherit hooks; }; +} +``` + +### With Devshell + +Using the devshell module: + +```nix +{ + inputs = { + devshell.url = "github:rensa-nix/devshell?dir=lib"; + soonix.url = "gitlab:TECHNOFAB/soonix?dir=lib"; + }; + + outputs = { devshell, soonix, ... }: { + # load pkgs etc... + devShells.default = (devshell.lib { inherit pkgs; }).mkShell { + imports = [ soonix.devshellModule ]; + + packages = [ pkgs.hello ]; + + soonix.hooks = { + # Your hooks here + }; + }; + }; +} +``` + +## Troubleshooting + +### Enable Logging + +Set `SOONIX_LOG=true` to see detailed status messages: + +```bash +SOONIX_LOG=true nix develop +``` + +### Manual Updates + +Update the files without shellHook/devshells: + +```bash +nix run .#soonix:update +``` + +### Check Generated Files + +Inspect what Soonix would generate without writing files: + +```bash +nix build .#soonixFiles +ls result/ +``` diff --git a/nix/repo/docs.nix b/nix/repo/docs.nix index 4c1e755..9f1e5cd 100644 --- a/nix/repo/docs.nix +++ b/nix/repo/docs.nix @@ -43,6 +43,8 @@ in }; nav = [ {"Introduction" = "index.md";} + {"Usage" = "usage.md";} + {"Integrations" = "integrations.md";} {"Options" = "options.md";} ]; markdown_extensions = [