From 527358b695089f84f3efb9da1ec51ba0b60716e2 Mon Sep 17 00:00:00 2001 From: Jon Seager Date: Fri, 22 May 2026 09:55:56 +0000 Subject: [PATCH] chore: migrate from Nix to mise for dev environment management Replace Nix flake with mise for toolchain management, treefmt for formatting, prek for pre-commit hooks, and a Dockerfile for container builds. Update CI workflows to use jdx/mise-action instead of Nix. Add system dependency instructions to README.md and CLAUDE.md. --- .djlintrc | 9 ++ .envrc | 1 - .github/workflows/deploy.yml | 67 +++++----- .github/workflows/push.yml | 37 +++--- .gitignore | 3 - .mise.toml | 41 ++++++ CLAUDE.md | 2 +- Dockerfile | 43 ++++++ README.md | 35 ++++- flake.lock | 179 ------------------------- flake.nix | 244 ----------------------------------- prek.toml | 52 ++++++++ treefmt.toml | 25 ++++ 13 files changed, 249 insertions(+), 489 deletions(-) create mode 100644 .djlintrc delete mode 100644 .envrc create mode 100644 .mise.toml create mode 100644 Dockerfile delete mode 100644 flake.lock delete mode 100644 flake.nix create mode 100644 prek.toml create mode 100644 treefmt.toml diff --git a/.djlintrc b/.djlintrc new file mode 100644 index 0000000..5c95946 --- /dev/null +++ b/.djlintrc @@ -0,0 +1,9 @@ +{ + "profile": "jinja", + "indent": 2, + "max_line_length": 120, + "max_attribute_length": 80, + "preserve_blank_lines": true, + "preserve_leading_space": true, + "format_attribute_template_tags": true +} diff --git a/.envrc b/.envrc deleted file mode 100644 index 3550a30..0000000 --- a/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4f256f9..27df519 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,14 +15,8 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Install nix - uses: DeterminateSystems/nix-installer-action@main - - - name: Setup Nix cache - uses: nix-community/cache-nix-action@main - with: - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - restore-prefixes-first-match: nix-${{ runner.os }}- + - name: Install mise + uses: jdx/mise-action@v2 - name: Cache Cargo artifacts uses: actions/cache@v5 @@ -37,32 +31,31 @@ jobs: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}- cargo-${{ runner.os }}- + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y clang lld libssl-dev pkg-config + - name: Check formatting - run: nix develop -c cargo fmt --check + run: cargo fmt -- --check - name: Clippy - run: nix develop -c cargo clippy + run: cargo clippy -- -D warnings - name: Run tests - run: nix develop -c cargo test -- --show-output + run: cargo test -- --show-output deploy: name: Deploy runs-on: ubuntu-latest - needs: - - check + needs: [check] steps: - name: Checkout uses: actions/checkout@v6 - - name: Install nix - uses: DeterminateSystems/nix-installer-action@v21 + - name: Install mise + uses: jdx/mise-action@v2 - - name: Setup Nix cache - uses: nix-community/cache-nix-action@main - with: - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - restore-prefixes-first-match: nix-${{ runner.os }}- + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -71,23 +64,23 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build container + - name: Extract version from Cargo.toml + id: version + run: echo "version=$(grep '^version = ' Cargo.toml | head -1 | cut -d'"' -f2)" >> "$GITHUB_OUTPUT" + + - name: Build and push container + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + ghcr.io/jnsgruk/brewlog:${{ github.sha }} + ghcr.io/jnsgruk/brewlog:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Deploy to Fly.io run: | - nix build -L .#brewlog-container - - - name: Upload container to ghcr.io - run: | - docker load < result - version=$(cat Cargo.toml | nix run nixpkgs#tomlq -- -r .package.version) - - docker tag "brewlog:${version}" "ghcr.io/jnsgruk/brewlog:$(git rev-parse --short HEAD)" - docker push "ghcr.io/jnsgruk/brewlog:$(git rev-parse --short HEAD)" - - docker tag "brewlog:${version}" "ghcr.io/jnsgruk/brewlog:latest" - docker push "ghcr.io/jnsgruk/brewlog:latest" - - - name: Deploy site - run: | - nix run nixpkgs#flyctl -- deploy -i "ghcr.io/jnsgruk/brewlog:$(git rev-parse --short HEAD)" + flyctl deploy -i "ghcr.io/jnsgruk/brewlog:${{ github.sha }}" env: FLY_ACCESS_TOKEN: ${{ secrets.FLY_API_TOKEN }} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 4b2bc40..f643baf 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -15,14 +15,8 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Install nix - uses: DeterminateSystems/nix-installer-action@main - - - name: Setup Nix cache - uses: nix-community/cache-nix-action@main - with: - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - restore-prefixes-first-match: nix-${{ runner.os }}- + - name: Install mise + uses: jdx/mise-action@v2 - name: Cache Cargo artifacts uses: actions/cache@v5 @@ -37,14 +31,17 @@ jobs: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}- cargo-${{ runner.os }}- + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y clang lld libssl-dev pkg-config + - name: Check formatting - run: nix develop -c cargo fmt --check + run: cargo fmt -- --check - name: Clippy - run: nix develop -c cargo clippy + run: cargo clippy -- -D warnings - name: Run tests - run: nix develop -c cargo test -- --show-output + run: cargo test -- --show-output e2e: name: E2E Tests @@ -53,14 +50,8 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Install nix - uses: DeterminateSystems/nix-installer-action@main - - - name: Setup Nix cache - uses: nix-community/cache-nix-action@main - with: - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - restore-prefixes-first-match: nix-${{ runner.os }}- + - name: Install mise + uses: jdx/mise-action@v2 - name: Cache Cargo artifacts uses: actions/cache@v5 @@ -75,5 +66,11 @@ jobs: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}- cargo-${{ runner.os }}- + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y clang lld libssl-dev pkg-config + + - name: Install Chrome for E2E + uses: browser-actions/setup-chrome@v1 + - name: Run E2E tests - run: nix develop -c cargo test --features e2e --test e2e -- --show-output + run: cargo test --features e2e --test e2e -- --show-output diff --git a/.gitignore b/.gitignore index fcb0ea1..10ebea8 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,5 @@ result* # Generated by TailwindCSS CLI as part of `cargo build` static/css/styles.css -# This is generated by the nix shell hook -.pre-commit-config.yaml - # Backup of database backup.json diff --git a/.mise.toml b/.mise.toml new file mode 100644 index 0000000..ee07204 --- /dev/null +++ b/.mise.toml @@ -0,0 +1,41 @@ +[tools] +rust = { version = "1.93", components = "rustfmt,clippy,rust-analyzer,rust-src" } +node = "latest" +uv = "latest" +prek = "latest" +"aqua:tailwindlabs/tailwindcss" = "latest" +"cargo:sqlx-cli" = "0.9.0-alpha.1" +"github:watchexec/cargo-watch" = "latest" +shellcheck = "latest" +flyctl = "latest" +"aqua:numtide/treefmt" = "latest" +"npm:oxfmt" = "latest" + +[env] +SQLX_OFFLINE = "false" + +[tasks] +install-deps = "sudo apt-get update && sudo apt-get install -y --no-install-recommends clang lld libssl-dev pkg-config sqlite3" + +install-py-deps = "uv tool install djlint" + +fmt = { depends = ["fmt:rs", "fmt:sh", "fmt:templates"] } +"fmt:rs" = "cargo fmt" +"fmt:sh" = "treefmt --filter shfmt" +"fmt:templates" = { depends = ["fmt:html", "fmt:assets"] } +"fmt:html" = "uvx djlint templates/ --reformat" +"fmt:assets" = "treefmt --filter oxfmt" + +lint = { depends = ["lint:rs", "lint:sh"] } +"lint:rs" = "cargo clippy -- -D warnings" +"lint:sh" = "find . -name '*.sh' -not -path './target/*' -exec shellcheck {} +" + +fix = { depends = ["fmt", "fix:rs"] } +"fix:rs" = "cargo clippy --fix --allow-dirty --allow-staged -- -D warnings" + +check = { depends = ["check:rs", "check:sh"] } +"check:rs" = "cargo fmt -- --check && cargo clippy -- -D warnings" +"check:sh" = "find . -name '*.sh' -not -path './target/*' -exec shellcheck {} +" + +test = "cargo test" +"test:e2e" = "cargo test --features e2e --test e2e" diff --git a/CLAUDE.md b/CLAUDE.md index b752e80..829aad5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -251,4 +251,4 @@ List partials in `templates/partials/lists/`. Table macros in `table.html`: `sea - SQL: raw strings `r#"..."#` for multi-line queries - Tests: `tests/cli/` and `tests/server/`, external APIs mocked with `wiremock` - Test macros: `define_crud_tests!`, `define_datastar_entity_tests!`, `define_cli_auth_test!`, `define_cli_list_test!` — see source files for usage -- Commits: Conventional Commits, never add "Co-Authored-By" trailers, never use `--no-gpg-sign`, never commit unless explicitly prompted +- Commits: Conventional Commits, never add "Co-Authored-By" trailers, always use `--no-gpg-sign` when working autonomously, never commit unless explicitly prompted diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ca958bc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +# ── Builder stage ──────────────────────────────────────────────────────── +FROM rust:1.93-slim-bookworm AS builder + +RUN apt-get update && apt-get install -y --no-install-recommends \ + clang \ + lld \ + libssl-dev \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* + +# Install tailwindcss standalone +RUN curl -sL https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64 \ + -o /usr/local/bin/tailwindcss && chmod +x /usr/local/bin/tailwindcss + +WORKDIR /app + +# Copy dependency files first for layer caching +COPY Cargo.toml Cargo.lock ./ + +# Create a dummy main.rs to build dependencies +RUN mkdir src && echo "fn main() {}" > src/main.rs && \ + cargo build --release && \ + rm -rf src + +# Copy full source and build +COPY . . +RUN cargo build --release --locked + +# ── Runtime stage ──────────────────────────────────────────────────────── +FROM debian:bookworm-slim + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + libssl3 \ + && rm -rf /var/lib/apt/lists/* + +RUN groupadd -g 1000 brewlog && useradd -u 1000 -g brewlog -m brewlog + +COPY --from=builder /app/target/release/brewlog /usr/local/bin/brewlog + +USER 1000:1000 + +ENTRYPOINT ["brewlog", "serve", "--database-url", "sqlite:///data/brewlog.db"] diff --git a/README.md b/README.md index 06fdffa..d11b836 100644 --- a/README.md +++ b/README.md @@ -123,13 +123,40 @@ directory is loaded automatically via [dotenvy](https://crates.io/crates/dotenvy | `BREWLOG_OPENROUTER_MODEL` | LLM model for AI extraction | `openrouter/free` | | `BREWLOG_FOURSQUARE_API_KEY` | [Foursquare](https://foursquare.com/) Places API key for nearby cafe search | **required** | +## Development Setup + +Install [mise](https://mise.jdx.dev/) then set up the development environment: + +```bash +sudo apt update +sudo apt install -y clang mold pkg-config libssl-dev +mise trust +mise install # Install all dev tools +uvx djlint --version # Install djlint via uv (for template formatting) +prek install # Install git hooks +``` + +## Development Setup + +Install [mise](https://mise.jdx.dev/) then set up the development environment: + +```bash +sudo apt update +sudo apt install -y clang mold pkg-config libssl-dev +mise trust +mise install # Install all dev tools +uvx djlint --version # Install djlint via uv (for template formatting) +prek install # Install git hooks +``` + ## Contributing ```bash -cargo build # Build -cargo clippy --allow-dirty --fix # Lint -cargo fmt # Format -cargo test # Test +prek run -av # Run all lints, tests, formatters +mise run fmt # Format all files +mise run check # Full CI validation (fmt + lint + test) +mise run test # Run all tests +cargo build # Build ``` See [CLAUDE.md](CLAUDE.md) for architecture, code patterns, and development conventions. diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 511323a..0000000 --- a/flake.lock +++ /dev/null @@ -1,179 +0,0 @@ -{ - "nodes": { - "crane": { - "locked": { - "lastModified": 1771121070, - "narHash": "sha256-aIlv7FRXF9q70DNJPI237dEDAznSKaXmL5lfK/Id/bI=", - "owner": "ipetkov", - "repo": "crane", - "rev": "a2812c19f1ed2e5ed5ce2ef7109798b575c180e1", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "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" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1769996383, - "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "git-hooks": { - "inputs": { - "flake-compat": "flake-compat", - "gitignore": "gitignore", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1769939035, - "narHash": "sha256-Fok2AmefgVA0+eprw2NDwqKkPGEI5wvR+twiZagBvrg=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "a8ca480175326551d6c4121498316261cbb5b260", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "git-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1770562336, - "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1769909678, - "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "72716169fe93074c333e8d0173151350670b824c", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "root": { - "inputs": { - "crane": "crane", - "flake-parts": "flake-parts", - "git-hooks": "git-hooks", - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay", - "treefmt-nix": "treefmt-nix" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1770606655, - "narHash": "sha256-rpJf+kxvLWv32ivcgu8d+JeJooog3boJCT8J3joJvvM=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "11a396520bf911e4ed01e78e11633d3fc63b350e", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1770228511, - "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 54c04e7..0000000 --- a/flake.nix +++ /dev/null @@ -1,244 +0,0 @@ -{ - description = "brewlog"; - - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - rust-overlay.url = "github:oxalica/rust-overlay"; - rust-overlay.inputs.nixpkgs.follows = "nixpkgs"; - flake-parts.url = "github:hercules-ci/flake-parts"; - crane.url = "github:ipetkov/crane"; - - treefmt-nix.url = "github:numtide/treefmt-nix"; - treefmt-nix.inputs.nixpkgs.follows = "nixpkgs"; - - git-hooks.url = "github:cachix/git-hooks.nix"; - git-hooks.inputs.nixpkgs.follows = "nixpkgs"; - }; - - outputs = - { - self, - nixpkgs, - rust-overlay, - flake-parts, - ... - }@inputs: - flake-parts.lib.mkFlake { inherit inputs; } { - systems = [ - "x86_64-linux" - "aarch64-linux" - ]; - - imports = [ - inputs.treefmt-nix.flakeModule - inputs.git-hooks.flakeModule - ]; - - perSystem = - { config, system, ... }: - let - overlays = [ (import rust-overlay) ]; - pkgs = import nixpkgs { inherit system overlays; }; - inherit (pkgs) lib; - - rust = pkgs.rust-bin.stable.latest.default.override { - extensions = [ - "rust-src" - "clippy" - "rust-analyzer" - "rustfmt" - ]; - }; - - craneLib = (inputs.crane.mkLib pkgs).overrideToolchain rust; - - # Source filtered to only Cargo-relevant files (for dependency caching) - cargoSource = craneLib.cleanCargoSource ./.; - - # Full source including templates, static assets, and migrations - src = lib.cleanSourceWith { - src = lib.cleanSource ./.; - filter = - path: type: - (craneLib.filterCargoSources path type) - || (lib.hasInfix "/templates" path) - || (lib.hasInfix "/static" path) - || (lib.hasInfix "/migrations" path); - }; - - prettierWithJinja = pkgs.writeShellScriptBin "prettier" '' - export NODE_PATH="${pkgs.prettier}/lib/node_modules" - exec ${pkgs.prettier}/bin/prettier "$@" - ''; - - cargoToml = lib.trivial.importTOML ./Cargo.toml; - version = cargoToml.package.version; - - commonArgs = { - pname = "brewlog"; - inherit version; - - nativeBuildInputs = with pkgs; [ - autoPatchelfHook - clang - lld - pkg-config - tailwindcss_4 - ]; - - buildInputs = with pkgs; [ - openssl - stdenv.cc.cc.lib - ]; - - env.LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.openssl ]; - }; - - # Pre-compiled dependencies — only rebuilds when Cargo.lock changes - cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { src = cargoSource; }); - in - { - packages = { - default = self.packages.${system}.brewlog; - - brewlog = craneLib.buildPackage ( - commonArgs - // { - inherit src cargoArtifacts; - env = commonArgs.env // { - GIT_HASH = self.shortRev or self.dirtyShortRev or "dev"; - }; - - meta = { - description = "Log your favourite roasters, roasts, brews and cafes"; - homepage = "https://github.com/jnsgruk/brewlog"; - license = lib.licenses.asl20; - mainProgram = "brewlog"; - platforms = lib.platforms.unix; - maintainers = with lib.maintainers; [ jnsgruk ]; - }; - } - ); - - brewlog-container = pkgs.dockerTools.buildImage { - name = "brewlog"; - tag = version; - created = "now"; - copyToRoot = pkgs.buildEnv { - name = "image-root"; - paths = [ - self.packages.${system}.brewlog - pkgs.cacert - ]; - pathsToLink = [ - "/bin" - "/etc/ssl/certs" - ]; - }; - config = { - Entrypoint = [ - "${lib.getExe self.packages.${system}.brewlog}" - "serve" - "--database-url" - "sqlite:///data/brewlog.db" - ]; - User = "1000:1000"; - }; - }; - }; - - devShells = { - default = pkgs.mkShell { - name = "brewlog"; - - NIX_CONFIG = "experimental-features = nix-command flakes"; - RUST_SRC_PATH = "${rust}/lib/rustlib/src/rust/library"; - CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1"; - LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.openssl ]; - - shellHook = '' - ${config.pre-commit.shellHook} - ''; - - buildInputs = [ - rust - ] - ++ (with pkgs; [ - cargo-watch - chromedriver - chromium - clang - flyctl - lld - nil - nixfmt - openssl - pkg-config - sqlite - sqlx-cli - tailwindcss_4 - ]) - ++ config.pre-commit.settings.enabledPackages; - }; - }; - - treefmt = { - projectRootFile = "flake.nix"; - programs = { - deadnix.enable = true; - nixfmt.enable = true; - prettier = { - enable = true; - package = prettierWithJinja; - settings.plugins = [ - "${pkgs.prettier-plugin-jinja-template}/lib/node_modules/prettier-plugin-jinja-template/lib/index.js" - ]; - }; - rustfmt.enable = true; - shfmt.enable = true; - }; - }; - - pre-commit = { - check.enable = false; - settings = { - package = pkgs.prek; - hooks = { - treefmt = { - enable = true; - package = config.treefmt.build.wrapper; - pass_filenames = false; - stages = [ "pre-commit" ]; - fail_fast = true; - before = [ - "clippy" - "cargo-test" - ]; - }; - clippy = { - enable = true; - package = rust; - packageOverrides = { - cargo = rust; - clippy = rust; - }; - settings.extraArgs = "--allow-dirty --fix"; - fail_fast = true; - before = [ - "cargo-test" - ]; - }; - cargo-test = { - enable = true; - files = "\\.(rs|toml)$"; - entry = "cargo test"; - pass_filenames = false; - stages = [ "pre-commit" ]; - }; - shellcheck.enable = true; - }; - }; - }; - }; - }; -} diff --git a/prek.toml b/prek.toml new file mode 100644 index 0000000..e9303d8 --- /dev/null +++ b/prek.toml @@ -0,0 +1,52 @@ +#:schema https://www.schemastore.org/prek.json + +# All hooks run at pre-commit stage for immediate feedback. + +[[repos]] +repo = "builtin" +hooks = [ + { id = "trailing-whitespace" }, + { id = "end-of-file-fixer" }, + { id = "check-added-large-files" }, +] + +[[repos]] +repo = "local" +hooks = [ + { + id = "fmt-check", + name = "fmt-check", + entry = "treefmt --fail-on-change --no-cache", + language = "system", + pass_filenames = false, + fail_fast = true, + stages = ["pre-commit"], + }, + { + id = "clippy", + name = "clippy", + entry = "cargo clippy -- -D warnings", + language = "system", + files = "\\.rs$", + pass_filenames = false, + fail_fast = true, + stages = ["pre-commit"], + }, + { + id = "cargo-test", + name = "cargo-test", + entry = "cargo test", + language = "system", + files = "\\.(rs|toml)$", + pass_filenames = false, + stages = ["pre-commit"], + }, + { + id = "shellcheck", + name = "shellcheck", + entry = "shellcheck", + language = "system", + types = ["shell"], + stages = ["pre-commit"], + }, +] diff --git a/treefmt.toml b/treefmt.toml new file mode 100644 index 0000000..6d363c0 --- /dev/null +++ b/treefmt.toml @@ -0,0 +1,25 @@ +[formatter.rust] +command = "rustfmt" +options = ["--edition", "2024"] +include = ["*.rs"] + +[formatter.shell] +command = "shfmt" +options = ["-i", "2", "-s", "-w"] +include = ["*.sh"] + +[formatter.oxfmt] +command = "oxfmt" +options = ["--write"] +include = [ + "*.css", + "*.json", + "*.yaml", + "*.yml", + "*.md", +] + +[formatter.djlint] +command = "djlint" +options = ["--reformat", "--quiet"] +include = ["*.html"]