From de1fcf3c213b1f9d633b49173566de55a8f3f601 Mon Sep 17 00:00:00 2001 From: Paul Grillenberger Date: Sat, 5 Sep 2026 15:58:49 +0200 Subject: [PATCH] chore: manage dev environment with devenv - add devenv.yaml/lock/nix with GHC, Cabal, HLS, hpack and hlint - migrate pre-commit hooks from .pre-commit-config.yaml to git-hooks.nix (config file is now autogenerated and gitignored) - add cert-prep build/test/lint tasks - pull GEMINI_API_KEY in via secretspec instead of a manual export - update README development section --- .gitignore | 5 ++ .pre-commit-config.yaml | 24 --------- README.md | 19 +++++-- devenv.lock | 117 ++++++++++++++++++++++++++++++++++++++++ devenv.nix | 60 +++++++++++++++++++++ devenv.yaml | 8 +++ secretspec.toml | 6 +++ 7 files changed, 210 insertions(+), 29 deletions(-) delete mode 100644 .pre-commit-config.yaml create mode 100644 devenv.lock create mode 100644 devenv.nix create mode 100644 devenv.yaml create mode 100644 secretspec.toml diff --git a/.gitignore b/.gitignore index 69acf64..d0730ac 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,8 @@ report.html # Ignore exports export-*.json export-*.md + +# devenv +.devenv/ +# autogenerated pre-commit config (managed by git-hooks.nix) +.pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 9cc6da9..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,24 +0,0 @@ -repos: - - repo: local - hooks: - - id: hpack - name: hpack - entry: hpack - language: system - files: ^(package\.yaml|cert-prep\.cabal)$ - pass_filenames: false - - id: fourmolu - name: fourmolu - entry: fourmolu --quiet --mode inplace - language: system - files: \.hs$ - - id: hlint - name: hlint - entry: hlint - language: system - files: \.hs$ - - repo: https://github.com/adrienverge/yamllint.git - rev: v1.38.0 - hooks: - - id: yamllint - args: [--strict, -c, .yamllint] diff --git a/README.md b/README.md index 0ddcd51..17f8f06 100644 --- a/README.md +++ b/README.md @@ -193,11 +193,20 @@ cabal run cert-prep -- ./config.json ### Development -Pre-commit hooks (hpack, fourmolu, hlint) are configured in -`.pre-commit-config.yaml` and run with [prek](https://github.com/j178/prek). -They expect `hpack`, `fourmolu`, and `hlint` on your PATH (e.g. via ghcup or -`cabal install`). Activate them once per clone: +The development environment is managed with [devenv](https://devenv.sh/). It provides GHC, Cabal, Haskell Language Server, linters, and git hooks. ```bash -prek install +devenv shell ``` + +Entering the shell automatically installs and configures the git hooks (`hpack`, `fourmolu`, `hlint`, `yamllint`). + +Common tasks: + +```bash +devenv tasks run cert-prep:build # build using cabal.fast.project +devenv tasks run cert-prep:test # run test suite +devenv tasks run cert-prep:lint # run hlint +``` + +For AI explanations during development, set `GEMINI_API_KEY` in a `.env` file (managed via Secretspec). diff --git a/devenv.lock b/devenv.lock new file mode 100644 index 0000000..317a019 --- /dev/null +++ b/devenv.lock @@ -0,0 +1,117 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1788550903, + "narHash": "sha256-XMMZULOICeCNuJPFzUyy6KRws26ug78HmbAqtEmXVxk=", + "owner": "cachix", + "repo": "devenv", + "rev": "2769b83ebd3e259192740ee40e39af59c5642774", + "type": "github" + }, + "original": { + "dir": "src/modules", + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", + "owner": "NixOS", + "repo": "flake-compat", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "flake-compat", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1788267358, + "narHash": "sha256-nt+lUqYVpc9Y6JeMd2WmXzCDojasdadKo0mWcluvY2Y=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "27555e2624241fb116b49095df4caaee85a25691", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1787631388, + "narHash": "sha256-vMiXptXarfSdJb1Gkc+FYVOAibuBRj7qxGa8z68q1Uw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ac6b2166e7a9375683b8e98f860f273222337b16", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-src": { + "flake": false, + "locked": { + "lastModified": 1787394516, + "narHash": "sha256-pRGOQSClnXNI2iLUG6DYpsGvYcuw0drOutVZFTJNw90=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c8f90650c15282fa8656a041bfbbd2403997a9a7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "inputs": { + "nixpkgs-src": "nixpkgs-src" + }, + "locked": { + "lastModified": 1787753358, + "narHash": "sha256-Tl77VbWyAKrOfRNQhL6JbQtb/MLzbYa/1RG1gWWfICk=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "256551e45f6303e142ab4a98be1bf243feb77dc0", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "git-hooks": "git-hooks", + "nixpkgs": "nixpkgs_2" + } + } + }, + "root": "root", + "version": 7 +} \ No newline at end of file diff --git a/devenv.nix b/devenv.nix new file mode 100644 index 0000000..9f167f7 --- /dev/null +++ b/devenv.nix @@ -0,0 +1,60 @@ +{ pkgs, config, ... }: +{ + packages = [ + pkgs.hlint + pkgs.hpack + ]; + languages.haskell = { + enable = true; + # Enable this as soon as lsp supports 9.14.1 + # package = pkgs.haskell.compiler.ghc9141; + cabal.enable = true; + lsp.enable = true; + stack.enable = false; + }; + + # Replaces .pre-commit-config.yaml with an autogenerated symlink. + git-hooks.hooks = { + hpack = { + enable = true; + entry = "hpack"; + files = "^(package\\.yaml|cert-prep\\.cabal)$"; + pass_filenames = false; + }; + local-fourmolu = { + enable = true; + name = "fourmolu"; + entry = "fourmolu"; + files = ".*\\.hs$"; + args = [ + "--mode" + "inplace" + ]; + }; + hlint.enable = true; + yamllint = { + enable = true; + args = [ + "--strict" + "-c" + ".yamllint" + ]; + }; + }; + + tasks = { + "cert-prep:build".exec = "cabal build --project-file=cabal.fast.project"; + "cert-prep:test" = { + exec = "cabal test --project-file=cabal.fast.project --test-show-details=always"; + after = [ "cert-prep:build" ]; + before = [ "devenv:enterTest" ]; + }; + "cert-prep:lint".exec = "hlint src app test"; + }; + + env = { + GEMINI_API_KEY = config.secretspec.secrets.GEMINI_API_KEY; + GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai"; + GEMINI_MODEL = "gemini-3.7-flash"; + }; +} diff --git a/devenv.yaml b/devenv.yaml new file mode 100644 index 0000000..a197cb5 --- /dev/null +++ b/devenv.yaml @@ -0,0 +1,8 @@ +inputs: + nixpkgs: + url: github:cachix/devenv-nixpkgs/rolling + git-hooks: + url: github:cachix/git-hooks.nix +secretspec: + enable: true + provider: dotenv diff --git a/secretspec.toml b/secretspec.toml new file mode 100644 index 0000000..6bb4774 --- /dev/null +++ b/secretspec.toml @@ -0,0 +1,6 @@ +[project] +name = "cert-prep" +revision = "1.0" + +[profiles.default] +GEMINI_API_KEY = { description = "GEMINI_API_KEY secret", required = true }