diff --git a/.clinerules b/.clinerules
deleted file mode 100644
index 04ec2df..0000000
--- a/.clinerules
+++ /dev/null
@@ -1,5 +0,0 @@
-# Project Guidelines
-
-## Documentation Requirements
-
-- Keep README.md in sync with new capabilities
diff --git a/.github/workflows/ci-steps.yml b/.github/workflows/ci-steps.yml
index bb106eb..4657318 100644
--- a/.github/workflows/ci-steps.yml
+++ b/.github/workflows/ci-steps.yml
@@ -75,7 +75,7 @@ jobs:
path: |
~/.cache/mise
~/.local/share/mise
- key: mise-${{ runner.os }}-${{ inputs.cache_suffix }}-${{ hashFiles('mise.toml', 'template/mise.toml.jinja', 'devbox.json', 'devbox.lock') }}
+ key: mise-${{ runner.os }}-${{ inputs.cache_suffix }}-${{ hashFiles('mise.toml', 'template/mise.toml.jinja') }}
restore-keys: |
mise-${{ runner.os }}-${{ inputs.cache_suffix }}-
mise-${{ runner.os }}-
@@ -89,24 +89,24 @@ jobs:
run: |
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
+ - name: Run dev-setup.sh
+ run: |
+ ./scripts/dev-setup.sh
+
- name: Setup mise
uses: jdx/mise-action@v2
with:
install: true
cache: true
- - name: Setup Devbox
- uses: jetify-com/devbox-install-action@v0.11.0
- with:
- enable-cache: true
-
- name: Generate Test Project
run: |
- devbox run copier copy . ../test-project --vcs-ref HEAD \
+ copier copy . ../test-project --vcs-ref HEAD \
--data project_name="Test Project" \
--data project_slug=test-project \
--data project_slug_underscore=test_project \
--data author_name="CI Bot" \
+ --data github_username="ci-bot" \
--data include_wasm=${{ inputs.wasm }} \
--data include_python=${{ inputs.python }} \
--data include_go=${{ inputs.go }} \
@@ -116,5 +116,6 @@ jobs:
working-directory: ../test-project
run: |
git init
- devbox install
- devbox run just setup copyright ci
+ ./scripts/dev-setup.sh
+ mise install
+ just setup copyright ci
diff --git a/.gitignore b/.gitignore
index a4515dd..4d67604 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
-.devbox
*.code-workspace
diff --git a/README.md b/README.md
index d83fbd0..0b90f6c 100644
--- a/README.md
+++ b/README.md
@@ -29,8 +29,8 @@ Python extensions, and Go bindings from a single codebase.
To use this template, you need to install the following tools:
-- **[Devbox](https://www.jetify.com/docs/devbox/):** Sets up your development
- environment by installing Rust, wasm‑pack, Node, PNPM, and Mise automatically.
+- **[Mise](https://mise.jdx.dev/):** Installs and manages Rust, Node, Python, PNPM, and every other tool used by this template.
+ If you don't have Mise yet, simply run `scripts/dev-setup.sh` and follow the prompts.
- **[Copier](https://copier.readthedocs.io/):** Generates a new project from
this template.
@@ -50,11 +50,11 @@ git init
jj git init --colocate
```
-Enter the Devbox shell:
+Install dependencies (Mise will take care of everything):
```bash
-devbox install
-devbox run direnv allow
+./scripts/dev-setup.sh # one-time, installs mise if missing
+mise install # installs the toolchain versions specified in mise.toml
```
Set up tools:
@@ -77,8 +77,8 @@ just ci
## Development Tools & Workflow
-The template provides a comprehensive development environment powered by Devbox
-and Mise. No manual tool installation required—everything from Rust nightly to
+The template provides a comprehensive development environment powered by Mise.
+No manual tool installation required—everything from Rust nightly to
WebAssembly toolchains is automatically configured.
**Testing & Quality** Comprehensive test suites run across all platforms, with
@@ -144,8 +144,7 @@ Your generated project will include:
**Development Environment**
-- `devbox.json`: Zero-config development environment
-- `mise.toml`: Task runner for common operations
+- `mise.toml`: Toolchain configuration and common operations
- `.envrc`: Automatic environment activation
- `.pre-commit-config.yaml`: Git hooks for quality checks
@@ -153,19 +152,20 @@ Your generated project will include:
```plain
cd ~/workplace && \
- rm -rf ~/workplace/ouchie && \
- copier copy ~/workplace/copier_rust_template ~/workplace/ouchie \
+ rm -rf ~/workplace/foobaz && \
+ copier copy ~/workplace/copier_rust_template ~/workplace/foobaz \
--data include_wasm=true \
--data include_python=true \
--data include_go=true \
- --data project_name="Ouchie" \
- --data project_slug=ouchie \
- --data project_slug_underscore=ouchie \
+ --data project_name="Foobaz" \
+ --data project_slug=foobaz \
+ --data project_slug_underscore=foobaz \
--data author_name="Local Test" \
--force && \
- cd ~/workplace/ouchie && \
+ cd ~/workplace/foobaz && \
git init && \
- devbox install && \
+ ./scripts/dev-setup.sh && \
+ mise install && \
just setup copyright ci ; \
cd go-wasm && \
just setup test test-go && \
diff --git a/copier.yml b/copier.yml
index 8281757..b0bcc61 100644
--- a/copier.yml
+++ b/copier.yml
@@ -36,6 +36,11 @@ author_name:
help: "Enter the author's name."
default: "Your Name"
+github_username:
+ type: str
+ help: "Enter your GitHub username."
+ default: "your-username"
+
_exclude:
- ".git"
- "__skip_wasm__"
diff --git a/devbox.json b/devbox.json
deleted file mode 100644
index 7d563a8..0000000
--- a/devbox.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
- "packages": [
- "copier@latest",
- "mise@latest"
- ],
- "shell": {
- "init_hook": [
- "echo 'Welcome to devbox!' > /dev/null"
- ],
- "scripts": {
- "test": [
- "echo \"Error: no test specified\" && exit 1"
- ]
- }
- }
-}
diff --git a/devbox.lock b/devbox.lock
deleted file mode 100644
index d133f73..0000000
--- a/devbox.lock
+++ /dev/null
@@ -1,117 +0,0 @@
-{
- "lockfile_version": "1",
- "packages": {
- "copier@latest": {
- "last_modified": "2025-02-03T20:50:02Z",
- "resolved": "github:NixOS/nixpkgs/494b2407ef95997176211a8758638205916873a9#copier",
- "source": "devbox-search",
- "version": "9.4.1",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/yzy367xiwvi73kmpcx27gcpsfax0c13j-copier-9.4.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/hah6lvv6bd96w5his88yjn7y0pv5ak2p-copier-9.4.1-dist"
- }
- ],
- "store_path": "/nix/store/yzy367xiwvi73kmpcx27gcpsfax0c13j-copier-9.4.1"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/jimrvrcq22vwqzpprfg2fkzgq8jfkxy0-copier-9.4.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/xhvhkkyx41f4s5hwyb64ic834mvdzsdd-copier-9.4.1-dist"
- }
- ],
- "store_path": "/nix/store/jimrvrcq22vwqzpprfg2fkzgq8jfkxy0-copier-9.4.1"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/yxyrrqah4yzd8fv289mcmms8rlbsfgyh-copier-9.4.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/zyfc2a04nh7n4yp4pz5xr7sk2na876fd-copier-9.4.1-dist"
- }
- ],
- "store_path": "/nix/store/yxyrrqah4yzd8fv289mcmms8rlbsfgyh-copier-9.4.1"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/nvgx23q73f8p36jh60n54mgjpi5xblai-copier-9.4.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/42ydxc1xfs9pzriixxrnmdvxlx7fl5kd-copier-9.4.1-dist"
- }
- ],
- "store_path": "/nix/store/nvgx23q73f8p36jh60n54mgjpi5xblai-copier-9.4.1"
- }
- }
- },
- "mise@latest": {
- "last_modified": "2025-02-07T11:26:36Z",
- "resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#mise",
- "source": "devbox-search",
- "version": "2025.2.0",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/8fhc7i1i2k5r67v51yj3b78wgzm7qlba-mise-2025.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/8fhc7i1i2k5r67v51yj3b78wgzm7qlba-mise-2025.2.0"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/kyvzkvgvaakp796xxk8mi61mbyfr5fiq-mise-2025.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/kyvzkvgvaakp796xxk8mi61mbyfr5fiq-mise-2025.2.0"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/5mp0bq3kfmpjyilbhbqjcalj6jk4r6y3-mise-2025.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/5mp0bq3kfmpjyilbhbqjcalj6jk4r6y3-mise-2025.2.0"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/lln0ycm6yg5v6h1bz16ydgaqiyijg3vl-mise-2025.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/lln0ycm6yg5v6h1bz16ydgaqiyijg3vl-mise-2025.2.0"
- }
- }
- }
- }
-}
diff --git a/mise.toml b/mise.toml
index 6652a62..43d6650 100644
--- a/mise.toml
+++ b/mise.toml
@@ -1,2 +1,3 @@
[tools]
+copier = "latest"
python = "prefix:3.12"
diff --git a/scripts/dev-setup.sh b/scripts/dev-setup.sh
new file mode 100755
index 0000000..9359901
--- /dev/null
+++ b/scripts/dev-setup.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+# Install mise
+if command -v mise >/dev/null 2>&1; then
+ echo "mise is already installed"
+else
+ echo "mise is not installed"
+ if command -v brew >/dev/null 2>&1; then
+ echo "brew is installed"
+ brew install mise
+ else
+ echo "brew is not installed"
+ curl https://mise.run | sh
+ fi
+fi
+
+mise settings add idiomatic_version_file_enable_tools rust
+
+# Need to install rust first
+mise use "rust@prefix:1.87"
\ No newline at end of file
diff --git a/scripts/test.sh b/scripts/test.sh
new file mode 100755
index 0000000..349e75c
--- /dev/null
+++ b/scripts/test.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
+ROOT_DIR=$(dirname "$SCRIPT_DIR")
+pushd "$ROOT_DIR"
+trap 'popd' EXIT
+
+cd ~/workplace
+
+rm -rf ~/workplace/foobaz
+copier copy ~/workplace/copier_rust_template ~/workplace/foobaz \
+ --data include_wasm=true \
+ --data include_python=true \
+ --data include_go=true \
+ --data project_name="Foobaz" \
+ --data project_slug=foobaz \
+ --data project_slug_underscore=foobaz \
+ --data author_name="Local Test" \
+ --data github_username="local-test" \
+ --force
+
+cd ~/workplace/foobaz
+git init
+
+./scripts/dev-setup.sh
+touch mise.lock
+mise trust
+mise install
+
+just setup copyright ci
+cd go-wasm
+just setup test test-go
diff --git a/template/.cargo/config.toml b/template/.cargo/config.toml
index 684c866..54fdc20 100644
--- a/template/.cargo/config.toml
+++ b/template/.cargo/config.toml
@@ -1,3 +1,14 @@
+[target.'cfg(not(build))'.build]
+# Prevents unavoidable warnings from build.rs scripts from failing the build
+rustflags = ["-D", "warnings"]
+
+[env]
+RUST_BACKTRACE = "1"
+
+# Nextest configuration
+[test]
+runner = "cargo nextest"
+
[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
diff --git a/template/.clippy.toml b/template/.clippy.toml
index e1236c6..56835be 100644
--- a/template/.clippy.toml
+++ b/template/.clippy.toml
@@ -1,3 +1,15 @@
-cognitive-complexity-threshold = 10
-too-many-arguments-threshold = 5
-type-complexity-threshold = 200
+msrv = "1.87.0"
+
+# ---------- Structural size limits ----------
+cognitive-complexity-threshold = 20
+enum-variant-size-threshold = 128 # bytes
+excessive-nesting-threshold = 6
+future-size-threshold = 8192 # bytes; keeps async state small
+too-many-arguments-threshold = 6
+too-many-lines-threshold = 100 # per-function and per-method
+type-complexity-threshold = 200
+
+# ---------- Misc quality-of-life ----------
+disallowed-methods = [
+ "std::mem::transmute",
+]
diff --git a/template/.envrc b/template/.envrc
deleted file mode 100644
index 2f05af9..0000000
--- a/template/.envrc
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-# Automatically sets up your devbox environment whenever you cd into this
-# directory via our direnv integration:
-
-eval "$(devbox generate direnv --print-envrc)"
-
-# check out https://www.jetpack.io/devbox/docs/ide_configuration/direnv/
-# for more details
diff --git a/template/.github/workflows/ci.yml b/template/.github/workflows/ci.yml
index 5389137..514b5e5 100644
--- a/template/.github/workflows/ci.yml
+++ b/template/.github/workflows/ci.yml
@@ -6,53 +6,120 @@ on:
pull_request:
branches: [main]
-defaults:
- run:
- shell: bash
+env:
+ CARGO_TERM_COLOR: always
+ RUST_BACKTRACE: 1
jobs:
+ check:
+ name: Check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: jdx/mise-action@v2
+ with:
+ experimental: true
+ - name: Cache cargo
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.cargo/registry
+ ~/.cargo/git
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-check
+ - name: Setup environment
+ run: just setup
+ - name: Check formatting
+ run: just check-format
+ - name: Check clippy
+ run: just check-clippy
+ - name: Check dependencies
+ run: just audit
+
test:
- name: Test
+ name: Test Suite
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ubuntu-latest]
-
+ include:
+ - {os: ubuntu-latest , rust: stable}
+ - {os: ubuntu-latest , rust: nightly}
+ - {os: ubuntu-latest , rust: "1.87.0"} # MSRV
+ - {os: windows-latest, rust: stable}
+ - {os: macos-latest , rust: stable}
steps:
- uses: actions/checkout@v4
-
- uses: jdx/mise-action@v2
with:
- cache: true
-
- - name: Setup Devbox
- uses: jetify-com/devbox-install-action@v0.11.0
+ experimental: true
+ - name: Cache cargo
+ uses: actions/cache@v4
with:
- enable-cache: true
+ path: |
+ ~/.cargo/registry
+ ~/.cargo/git
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.rust }}
+ - name: Install Rust
+ run: rustup toolchain install ${{ matrix.rust }} --component rustfmt clippy miri
+ - name: Setup environment
+ run: just setup
+ - name: Run tests
+ run: just test
+ - name: Run doc tests
+ run: just test-doc
+ - name: Run miri (nightly only)
+ if: matrix.rust == 'nightly'
+ run: just test-miri
+ coverage:
+ name: Coverage
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: jdx/mise-action@v2
+ with:
+ experimental: true
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
- target
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- restore-keys: ${{ runner.os }}-cargo-
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-coverage
+ - name: Setup environment
+ run: just setup
+ - name: Generate coverage
+ run: just coverage
+ - name: Upload to codecov
+ uses: codecov/codecov-action@v3
+ with:
+ files: lcov.info
+ - name: Upload HTML report artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: coverage-report
+ path: target/llvm-cov/html/
- - name: Cache pnpm dependencies
+ cross-compile:
+ name: Cross Compile
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ target: [x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu]
+ steps:
+ - uses: actions/checkout@v4
+ - uses: jdx/mise-action@v2
+ with:
+ experimental: true
+ - name: Cache cargo
uses: actions/cache@v4
with:
path: |
- ~/.pnpm-store
- web/node_modules
- key: ${{ runner.os }}-pnpm-${{ hashFiles('web/pnpm-lock.yaml') }}
- restore-keys: |
- ${{ runner.os }}-pnpm-
-
+ ~/.cargo/registry
+ ~/.cargo/git
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-cross-${{ matrix.target }}
+ - name: Install cross
+ run: cargo install cross --locked
- name: Setup environment
- run: |
- devbox run -- just setup
-
- - name: CI
- run: devbox run -- just ci
+ run: just setup
+ - name: Cross compile and test
+ run: cross test --release --all-features --target ${{ matrix.target }}
diff --git a/template/.gitignore b/template/.gitignore
index 9b0a920..5ce0619 100644
--- a/template/.gitignore
+++ b/template/.gitignore
@@ -20,5 +20,4 @@ Cargo.lock
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
-.devbox
.jj
diff --git a/template/.pre-commit-config.yaml b/template/.pre-commit-config.yaml
index c767827..529abd8 100644
--- a/template/.pre-commit-config.yaml
+++ b/template/.pre-commit-config.yaml
@@ -22,14 +22,14 @@ repos:
hooks:
- id: rust-fmt
name: Rust formatter
- entry: devbox run -- just rust-fmt
+ entry: just format
types: [rust]
language: system
pass_filenames: false
- - id: rust-check
- name: Rust checker
- entry: devbox run -- just rust-check
+ - id: rust-check-format
+ name: Rust format check
+ entry: just check-format
types: [rust]
language: system
pass_filenames: false
@@ -37,7 +37,7 @@ repos:
- id: rust-clippy
name: Rust clippy
- entry: devbox run -- just rust-clippy
+ entry: just check-clippy
types: [rust]
language: system
pass_filenames: false
@@ -45,14 +45,14 @@ repos:
- id: web-lint
name: Web lint and format
- entry: devbox run -- just web-lint
+ entry: just web-lint
types: [javascript, ts, jsx, tsx]
language: system
pass_filenames: false
- id: copyright-check
name: Copyright check
- entry: devbox run -- just copyright-check
+ entry: just copyright-check
types: [rust, javascript, ts, jsx, tsx]
language: system
pass_filenames: false
diff --git a/template/CHANGELOG.md b/template/CHANGELOG.md
new file mode 100644
index 0000000..0b8e45c
--- /dev/null
+++ b/template/CHANGELOG.md
@@ -0,0 +1,24 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Added
+
+- Initial project structure
+- Core library functionality
+- CLI interface
+
+### Changed
+
+### Deprecated
+
+### Removed
+
+### Fixed
+
+### Security
diff --git a/template/CONTRIBUTING.md b/template/CONTRIBUTING.md
new file mode 100644
index 0000000..499284f
--- /dev/null
+++ b/template/CONTRIBUTING.md
@@ -0,0 +1,56 @@
+# Contributing
+
+Thanks for your interest in contributing!
+
+## Quick Start
+
+Run `just check-all` before every PR to ensure your changes meet our quality standards.
+
+## Development Setup
+
+1. Install dependencies:
+
+ ```bash
+ ./scripts/dev-setup.sh
+ mise install
+ ```
+
+2. Set up the project:
+
+ ```bash
+ just setup
+ ```
+
+3. Run the development workflow:
+
+ ```bash
+ just dev
+ ```
+
+## Testing
+
+- Run all tests: `just test`
+- Run with coverage: `just coverage`
+- Run security audit: `just audit`
+
+## Code Style
+
+- Format code: `just format`
+- Check formatting: `just check-format`
+- Run clippy: `just check-clippy`
+
+## Submitting Changes
+
+1. Fork the repository
+2. Create a feature branch
+3. Make your changes
+4. Run `just check-all` to ensure quality
+5. Submit a pull request
+
+## Code of Conduct
+
+Please be respectful and follow our community guidelines.
+
+## Questions?
+
+Feel free to open an issue for any questions or clarifications.
diff --git a/template/Cargo.toml.jinja b/template/Cargo.toml.jinja
index ae1e881..dcb06e2 100644
--- a/template/Cargo.toml.jinja
+++ b/template/Cargo.toml.jinja
@@ -21,3 +21,16 @@ resolver = "2"
[profile.release]
lto = true
+
+[workspace.lints.rust]
+unsafe_code = "forbid"
+missing_docs = "warn"
+
+[workspace.lints.clippy]
+# Lint groups have lower priority than individual lints
+all = { level = "warn", priority = -1 }
+pedantic = { level = "warn", priority = -1 }
+nursery = { level = "warn", priority = -1 }
+# Individual lints with higher priority
+unwrap_used = "deny"
+expect_used = "deny"
diff --git a/template/Justfile.jinja b/template/Justfile.jinja
index eff40dc..cdbd558 100644
--- a/template/Justfile.jinja
+++ b/template/Justfile.jinja
@@ -18,11 +18,14 @@ mod go-wasm
@default:
@just --list
+# =============================================================================
+# Setup and Dependencies
+# =============================================================================
+
setup:
#!/usr/bin/env bash
set -e
- devbox install
mise trust
mise install
@@ -37,12 +40,9 @@ setup:
rustup toolchain install nightly
rustup target add wasm32-wasip1
- cargo binstall cargo-llvm-cov --secure --no-confirm
rustup component add llvm-tools-preview
rustup component add rustfmt
rustup component add clippy
- cargo binstall cargo-nextest --secure --no-confirm
- cargo binstall cargo-deny --secure --no-confirm
pre-commit install
pre-commit install-hooks
@@ -61,7 +61,6 @@ mac-setup:
fi
brew install libiconv llvm
- cargo binstall cargo-llvm-cov --secure --no-confirm
rustup component add llvm-tools-preview
rustup component add llvm-tools-preview --toolchain nightly-aarch64-apple-darwin
if ! xcode-select -p >/dev/null 2>&1; then
@@ -72,45 +71,84 @@ mac-setup:
update-deps:
cargo update
-# Development tasks
-watch:
+# =============================================================================
+# Rust Development Tasks
+# =============================================================================
+
+# Development workflow
+rust-dev: rust-format rust-clippy-fix rust-test
+
+# Watching for changes
+rust-watch:
cargo watch -x check -x test
-# Rust tasks
-rust-check:
- cargo check --all-targets
+# Formatting
+rust-check-format:
+ cargo fmt -- --check
+
+rust-format:
+ cargo fmt
+# Linting
+rust-check-clippy:
+ cargo clippy --all-targets --all-features -- -D warnings
+
+rust-clippy-fix:
+ cargo clippy --all-targets --all-features --fix -- -D warnings
+
+# Testing
rust-test:
- cargo nextest run --all-targets --no-fail-fast
- cargo test --doc --no-fail-fast
+ cargo nextest run --all-features
+
+rust-test-doc:
+ cargo test --doc
-rust-doc:
- cargo doc --no-deps --document-private-items
+# Miri testing (only on marked tests to avoid long wall-clock hits)
+rust-test-miri:
+ RUSTFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test -- --ignored
+# Coverage
+rust-coverage:
+ cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
+ cargo llvm-cov report --html
+
+rust-coverage-ci:
+ cargo llvm-cov --all-features --workspace
+ # cargo llvm-cov --all-features --workspace --fail-under-lines 80
+
+# Security & Dependencies
rust-audit:
- cargo audit || exit 1
- cargo deny check || exit 1
+ cargo audit
+ cargo deny check
+
+# MSRV verification
+rust-msrv-check:
+ cargo msrv verify
+
+# Feature matrix testing
+rust-hack-check:
+ cargo hack test --each-feature --no-dev-deps
+# Building
rust-build:
cargo build
-rust-fmt:
- cargo fmt --all
-
-rust-clippy:
- cargo clippy --all-targets -- -D warnings
+rust-build-release:
+ cargo build --release
+# Cleaning
rust-clean:
cargo clean
-copyright:
- mise x -- bash -c 'fd -e rs -e ts -e js -e jsx -e tsx -e go -e py | xargs addlicense -f copyright.tmpl -c "{{ author_name }}" -v -s'
+# Run all Rust checks (use in CI and pre-commit)
+rust-check-all: rust-check-format rust-check-clippy rust-test rust-coverage-ci rust-audit
-copyright-check:
- mise x -- bash -c 'fd -e rs -e ts -e js -e jsx -e tsx -e go -e py | xargs addlicense -f copyright.tmpl -c "{{ author_name }}" -v -s -check'
+# =============================================================================
+# Cross-Language Tasks (All Languages)
+# =============================================================================
-# Combined tasks
-check: rust-check rust-fmt rust-clippy rust-audit copyright-check
+# Combined linting across all languages
+lint-all: rust-check-clippy copyright-check
{%- if include_wasm %}
just web lint
{%- endif %}
@@ -122,7 +160,8 @@ check: rust-check rust-fmt rust-clippy rust-audit copyright-check
just go-wasm lint
{%- endif %}
-test: rust-test
+# Combined testing across all languages
+test-all: rust-test
{%- if include_wasm %}
just web test
{%- endif %}
@@ -134,27 +173,8 @@ test: rust-test
just go-wasm test
{%- endif %}
-cov:
- #!/usr/bin/env bash
- set -e
-
- if [[ "$OSTYPE" == "darwin"* ]]; then
- cargo +nightly llvm-cov nextest
- else
- cargo llvm-cov nextest
- fi
-
-cov-local:
- #!/usr/bin/env bash
- set -e
-
- if [[ "$OSTYPE" == "darwin"* ]]; then
- cargo +nightly llvm-cov nextest --no-fail-fast --text --show-missing-lines --mcdc
- else
- cargo llvm-cov nextest --no-fail-fast --text --show-missing-lines --mcdc
- fi
-
-build: rust-build
+# Combined building across all languages
+build-all: rust-build rust-build-release
{%- if include_wasm %}
just web build
{%- endif %}
@@ -166,7 +186,8 @@ build: rust-build
just go-wasm build
{%- endif %}
-clean: rust-clean
+# Combined cleaning across all languages
+clean-all: rust-clean
{%- if include_wasm %}
just web clean
{%- endif %}
@@ -178,10 +199,77 @@ clean: rust-clean
just go-wasm clean
{%- endif %}
+# =============================================================================
+# Copyright and Legal
+# =============================================================================
+
+copyright:
+ mise x -- bash -c 'fd -e rs -e ts -e js -e jsx -e tsx -e go -e py | xargs addlicense -f copyright.tmpl -c "{{ author_name }}" -v -s'
+
+copyright-check:
+ mise x -- bash -c 'fd -e rs -e ts -e js -e jsx -e tsx -e go -e py | xargs addlicense -f copyright.tmpl -c "{{ author_name }}" -v -s -check'
+
+# =============================================================================
+# Development Workflows
+# =============================================================================
+
{% if include_wasm %}
-web-dev: build
+# Start web development (builds dependencies first)
+web-dev: build-all
just web dev
{%- endif %}
-# CI tasks
-ci: build check test cov
+# Development workflow for all languages
+dev-all: rust-dev
+ {%- if include_wasm %}
+ just web dev &
+ {%- endif %}
+ {%- if include_python %}
+ just python dev &
+ {%- endif %}
+ {%- if include_go %}
+ just go dev &
+ {%- endif %}
+ wait
+
+# =============================================================================
+# CI and Release Tasks
+# =============================================================================
+
+# Full CI pipeline
+ci: build-all lint-all test-all
+
+# Release preparation
+release-prep: rust-check-all
+ git status
+ @echo "Ready for release if git status is clean"
+
+# =============================================================================
+# Legacy Aliases (for backwards compatibility)
+# =============================================================================
+
+# Legacy short aliases - prefer the explicit rust-* versions above
+alias format := rust-format
+alias clippy := rust-check-clippy
+alias test := rust-test
+alias build := rust-build
+alias clean := rust-clean
+alias dev := rust-dev
+alias watch := rust-watch
+alias audit := rust-audit
+
+# Legacy combined aliases - prefer the *-all versions above
+alias check := lint-all
+alias coverage := rust-coverage
+alias cov := rust-coverage-ci
+
+# Legacy coverage with platform-specific handling
+cov-local:
+ #!/usr/bin/env bash
+ set -e
+
+ if [[ "$OSTYPE" == "darwin"* ]]; then
+ cargo +nightly llvm-cov nextest --no-fail-fast --text --show-missing-lines --mcdc
+ else
+ cargo llvm-cov nextest --no-fail-fast --text --show-missing-lines --mcdc
+ fi
diff --git a/template/README.md.jinja b/template/README.md.jinja
index 81878c2..dfab019 100644
--- a/template/README.md.jinja
+++ b/template/README.md.jinja
@@ -1,10 +1,116 @@
# {{ project_name }}
-This project is generated from our multi-crate template. It contains:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-• A CLI binary crate
-• A core library crate
+{{ project_name }} is a multi-platform Rust project with:
-You can build and run the CLI using Cargo commands from the workspace root.
+- 🦀 **Core Library**: Shared functionality in `{{ project_slug }}-core`
+- 🖥️ **CLI Tool**: Command-line interface in `{{ project_slug }}-cli`
+{%- if include_wasm %}
+- 🌐 **WebAssembly**: Browser-compatible WASM bindings
+- 🎨 **Web Frontend**: TypeScript/React web interface
+{%- endif %}
+{%- if include_python %}
+- 🐍 **Python Bindings**: Native Python extension module
+{%- endif %}
+{%- if include_go %}
+- 🦫 **Go Bindings**: CGO-based Go library bindings
+{%- endif %}
-Happy coding!
+## Quick Start
+
+### Prerequisites
+
+- **[Mise](https://mise.jdx.dev/)**: Manages all tools and dependencies
+- **Git**: For version control
+
+### Installation
+
+1. **Clone and setup**:
+ ```bash
+ git clone https://github.com/{{ github_username }}/{{ project_slug }}.git
+ cd {{ project_slug }}
+ ./scripts/dev-setup.sh # Installs mise if needed
+ mise install # Installs all tools
+ ```
+
+2. **Initialize the project**:
+ ```bash
+ just setup # Sets up development environment
+ just copyright # Adds copyright headers
+ ```
+
+3. **Build and test**:
+ ```bash
+ just check-all # Run all quality checks
+ just build # Build all components
+ just test # Run test suite
+ ```
+
+## Development
+
+### Available Commands
+
+- `just check-all` - Run all checks (formatting, linting, tests, coverage, audit)
+- `just dev` - Development workflow (format, fix clippy issues, test)
+- `just format` - Format code with rustfmt
+- `just test` - Run test suite with nextest
+- `just coverage` - Generate code coverage report
+- `just audit` - Security and dependency audit
+- `just release-prep` - Prepare for release
+
+### Project Structure
+
+```
+{{ project_slug }}/
+├── core/ # Core library ({{ project_slug }}-core)
+├── cli/ # Command-line tool ({{ project_slug }}-cli)
+{%- if include_wasm %}
+├── wasm/ # WebAssembly bindings
+├── web/ # Web frontend (TypeScript)
+{%- endif %}
+{%- if include_python %}
+├── python/ # Python bindings
+{%- endif %}
+{%- if include_go %}
+├── go/ # Go bindings
+├── go-wasm/ # Go WebAssembly bindings
+{%- endif %}
+├── scripts/ # Development scripts
+└── Justfile # Task runner configuration
+```
+
+## Contributing
+
+We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
+
+### Development Workflow
+
+1. Fork the repository
+2. Create a feature branch: `git checkout -b feature/amazing-feature`
+3. Make your changes
+4. Run quality checks: `just check-all`
+5. Commit your changes: `git commit -m 'Add amazing feature'`
+6. Push to the branch: `git push origin feature/amazing-feature`
+7. Open a Pull Request
+
+## License
+
+This project is licensed under the Mozilla Public License 2.0 - see the [LICENSE](LICENSE) file for details.
diff --git a/template/cli/Cargo.toml.jinja b/template/cli/Cargo.toml.jinja
index bffcf98..3183934 100644
--- a/template/cli/Cargo.toml.jinja
+++ b/template/cli/Cargo.toml.jinja
@@ -2,8 +2,31 @@
name = "{{ project_slug }}-cli"
version = "0.1.0"
edition = "2021"
+rust-version = "1.87.0"
+authors = ["{{ author_name }}"]
license = "MPL-2.0"
+description = "Command-line interface for {{ project_name }}"
+homepage = "https://github.com/{{ github_username }}/{{ project_slug }}"
+repository = "https://github.com/{{ github_username }}/{{ project_slug }}"
+documentation = "https://docs.rs/{{ project_slug }}-cli"
+readme = "../README.md"
+keywords = ["{{ project_slug }}", "cli"]
+categories = ["command-line-utilities"]
+
+[dependencies]
+{{ project_slug }}-core = { path = "../core" }
[[bin]]
name = "{{ project_slug }}-cli"
path = "src/main.rs"
+
+[lints.rust]
+unsafe_code = "forbid"
+missing_docs = "warn"
+
+[lints.clippy]
+all = "warn"
+pedantic = "warn"
+nursery = "warn"
+unwrap_used = "deny"
+expect_used = "deny"
diff --git a/template/cli/src/main.rs.jinja b/template/cli/src/main.rs.jinja
index 0d85d19..83a51c9 100644
--- a/template/cli/src/main.rs.jinja
+++ b/template/cli/src/main.rs.jinja
@@ -1,3 +1,12 @@
+// Copyright 2025 {{ author_name }}
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+// If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+//! Command-line interface for {{ project_name }}.
+
fn main() {
println!("Welcome to {{ project_name }} CLI!");
}
diff --git a/template/core/Cargo.toml.jinja b/template/core/Cargo.toml.jinja
index f3bc4d3..b231aed 100644
--- a/template/core/Cargo.toml.jinja
+++ b/template/core/Cargo.toml.jinja
@@ -2,7 +2,16 @@
name = "{{ project_slug }}-core"
version = "0.1.0"
edition = "2021"
+rust-version = "1.87.0"
+authors = ["{{ author_name }}"]
license = "MPL-2.0"
+description = "Core library for {{ project_name }}"
+homepage = "https://github.com/{{ github_username }}/{{ project_slug }}"
+repository = "https://github.com/{{ github_username }}/{{ project_slug }}"
+documentation = "https://docs.rs/{{ project_slug }}-core"
+readme = "../README.md"
+keywords = ["{{ project_slug }}", "core"]
+categories = ["development-tools"]
[dependencies]
ariadne = "0.5.0"
@@ -12,3 +21,14 @@ thiserror = "2.0"
[lib]
path = "src/lib.rs"
crate-type = ["rlib", "cdylib"]
+
+[lints.rust]
+unsafe_code = "forbid"
+missing_docs = "warn"
+
+[lints.clippy]
+all = "warn"
+pedantic = "warn"
+nursery = "warn"
+unwrap_used = "deny"
+expect_used = "deny"
diff --git a/template/core/src/lib.rs.jinja b/template/core/src/lib.rs.jinja
index 6df1e37..ef1c864 100644
--- a/template/core/src/lib.rs.jinja
+++ b/template/core/src/lib.rs.jinja
@@ -1,26 +1,54 @@
-// Copyright 2025 Local Test
+// Copyright 2025 {{ author_name }}
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
//
// SPDX-License-Identifier: MPL-2.0
+//! Core library for {{ project_name }}.
+//!
+//! This library provides the core functionality for parsing and processing
+//! arithmetic expressions.
+
use chumsky::prelude::*;
use thiserror::Error;
/// Our custom error type for parsing failures.
#[derive(Error, Debug)]
pub enum ParseError {
+ /// A generic parsing error with a descriptive message.
#[error("Parse error: {0}")]
Generic(String),
}
/// A simple arithmetic expression parser that accepts expressions like "1+2+3"
/// and computes their sum.
+///
+/// # Errors
+///
+/// Returns a `ParseError` if:
+/// - The input contains non-numeric characters (except '+')
+/// - The input has invalid syntax (e.g., "1+" or "+2")
+/// - The input is empty or contains only whitespace
+///
+/// # Examples
+///
+/// ```
+/// use {{ project_slug_underscore }}_core::parse;
+///
+/// # fn main() -> Result<(), Box> {
+/// assert_eq!(parse("1+2+3")?, "6");
+/// assert_eq!(parse("10+20+30")?, "60");
+/// # Ok(())
+/// # }
+/// ```
pub fn parse(input: &str) -> Result {
// The parser for an integer.
let number = text::int::>(10)
- .map(|s: String| s.parse::().unwrap())
+ .try_map(|s: String, span| {
+ s.parse::()
+ .map_err(|e| Simple::custom(span, format!("Invalid number: {e}")))
+ })
.padded()
.labelled("number");
@@ -54,9 +82,20 @@ mod tests {
#[test]
fn test_parse() {
- assert_eq!(parse("1+2+3").unwrap(), "6");
- assert_eq!(parse("10+20+30").unwrap(), "60");
- assert_eq!(parse("100+200+300").unwrap(), "600");
+ match parse("1+2+3") {
+ Ok(result) => assert_eq!(result, "6"),
+ Err(e) => panic!("Expected successful parse of '1+2+3', got error: {e}"),
+ }
+
+ match parse("10+20+30") {
+ Ok(result) => assert_eq!(result, "60"),
+ Err(e) => panic!("Expected successful parse of '10+20+30', got error: {e}"),
+ }
+
+ match parse("100+200+300") {
+ Ok(result) => assert_eq!(result, "600"),
+ Err(e) => panic!("Expected successful parse of '100+200+300', got error: {e}"),
+ }
}
#[test]
@@ -70,7 +109,7 @@ mod tests {
);
} else {
println!("Expected an error, but got a result");
- println!("Result: {:?}", res);
+ println!("Result: {res:?}");
panic!("Expected an error, but got a result");
}
}
diff --git a/template/deny.toml b/template/deny.toml
index 594e2a6..41a5554 100644
--- a/template/deny.toml
+++ b/template/deny.toml
@@ -1,2 +1,38 @@
+[graph]
+all-features = true
+
+[advisories]
+# advisory DB configuration
+db-path = "~/.cargo/advisory-db"
+db-urls = ["https://github.com/rustsec/advisory-db"]
+
+# choose how to treat unmaintained advisories: all|workspace|transitive|none
+unmaintained = "workspace"
+
+# what to do on yanked crates: deny|warn|allow
+yanked = "deny"
+
[licenses]
-allow = ["Apache-2.0", "MIT", "MPL-2.0", "Unicode-3.0"]
+# only these SPDX licenses are permitted (everything else is denied by default)
+allow = [
+ "MIT",
+ "Apache-2.0",
+ "MPL-2.0",
+ "Unicode-DFS-2016",
+]
+
+# (optional) lint if an allowed license isn't actually used:
+# unused-allowed-license = "warn"
+
+# (optional) override AskAlono's confidence threshold:
+# confidence-threshold = 0.8
+
+[bans]
+# duplicate-version policy: warn | deny | allow
+multiple-versions = "warn"
+
+# wildcard dependencies: allow | deny
+wildcards = "allow"
+
+# graph coloring when dumping dotgraphs: none | all
+highlight = "all"
diff --git a/template/devbox.json b/template/devbox.json
deleted file mode 100644
index 35fbeb4..0000000
--- a/template/devbox.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
- "packages": [
- "bash@latest",
- "cargo-audit@latest",
- "cargo-deny@latest",
- "cargo-watch@latest",
- "mise@latest",
- "pnpm@latest",
- "rust-cbindgen@latest",
- "wabt@latest",
- "wasm-bindgen-cli@latest",
- "wasm-pack@latest"
- ],
- "env": {
- "COREPACK_ENABLE_DOWNLOAD_PROMPT": "0",
- "LIBRARY_PATH": "$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib:/opt/homebrew/opt/libiconv/lib",
- "MACOSX_DEPLOYMENT_TARGET": "11.0",
- "RUST_BACKTRACE": "1",
- "RUSTFLAGS": "-D warnings"
- },
- "shell": {
- "init_hook": [
- "mise trust",
- "mise install"
- ]
- }
-}
diff --git a/template/devbox.lock b/template/devbox.lock
deleted file mode 100644
index 4b7f4fc..0000000
--- a/template/devbox.lock
+++ /dev/null
@@ -1,1065 +0,0 @@
-{
- "lockfile_version": "1",
- "packages": {
- "addlicense@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#addlicense",
- "source": "devbox-search",
- "version": "1.1.1",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/mpkwfrp1lvszm651kc40vv99npyfg0c4-addlicense-1.1.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/mpkwfrp1lvszm651kc40vv99npyfg0c4-addlicense-1.1.1"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/dn584k3spxjac7y3ig7zcnhis66rs9j9-addlicense-1.1.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/dn584k3spxjac7y3ig7zcnhis66rs9j9-addlicense-1.1.1"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/dgw2wjx4rkjqlp85njd309dhgjqfj9mq-addlicense-1.1.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/dgw2wjx4rkjqlp85njd309dhgjqfj9mq-addlicense-1.1.1"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/433nyszq6q672km01a9af3gr4brv94sz-addlicense-1.1.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/433nyszq6q672km01a9af3gr4brv94sz-addlicense-1.1.1"
- }
- }
- },
- "bash@latest": {
- "last_modified": "2025-01-29T07:48:22Z",
- "resolved": "github:NixOS/nixpkgs/9a5db3142ce450045840cc8d832b13b8a2018e0c#bash",
- "source": "devbox-search",
- "version": "5.2p37",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/iv1k5wr7hbxm51qmdn6l2inq7rd2vfhk-bash-5.2p37",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/5wykqrk1bjvy5nwzgz9dwjjx223cgxbi-bash-5.2p37-man",
- "default": true
- },
- {
- "name": "dev",
- "path": "/nix/store/y1gbmyh6g72pwwmq8bfy3xqccf41c9kp-bash-5.2p37-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/4pymjfaz3c52sjm8gbbrjh8hjp132hbp-bash-5.2p37-doc"
- },
- {
- "name": "info",
- "path": "/nix/store/lkkrvm3ff638gj6kyq661g5wdmi18ix1-bash-5.2p37-info"
- }
- ],
- "store_path": "/nix/store/iv1k5wr7hbxm51qmdn6l2inq7rd2vfhk-bash-5.2p37"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/xgvqbslsa5km8q1bkhlhdr3r5kxblvn6-bash-5.2p37",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/air7z6nlsymq83pb0b3zkgpwgbz0xfk7-bash-5.2p37-man",
- "default": true
- },
- {
- "name": "info",
- "path": "/nix/store/hj9pwsa7k44hp7cdaqiwwgj1d8cbwqhq-bash-5.2p37-info"
- },
- {
- "name": "debug",
- "path": "/nix/store/0cjhc09c1950x79543wn4q44blyqxm2v-bash-5.2p37-debug"
- },
- {
- "name": "dev",
- "path": "/nix/store/yabpm2m2zlrw0n31wlzpkasa9xwimvif-bash-5.2p37-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/9ak22h5rx84n4psrf983a5wx1vz6sgqh-bash-5.2p37-doc"
- }
- ],
- "store_path": "/nix/store/xgvqbslsa5km8q1bkhlhdr3r5kxblvn6-bash-5.2p37"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/igfwnnvi05rz0mxdwh058v6n2h49zxi3-bash-5.2p37",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/djrihaw45f70x2b2az99drz896g33jsc-bash-5.2p37-man",
- "default": true
- },
- {
- "name": "dev",
- "path": "/nix/store/lpz39521cvyi7panxlp61gbq8qsz93ab-bash-5.2p37-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/wk6dpd9phm9vvd9drlwsj6gydcc0lg2x-bash-5.2p37-doc"
- },
- {
- "name": "info",
- "path": "/nix/store/24kgy563fhz3f5ya3l9iqb17yxj4ya6v-bash-5.2p37-info"
- }
- ],
- "store_path": "/nix/store/igfwnnvi05rz0mxdwh058v6n2h49zxi3-bash-5.2p37"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/4fvc5fm8bszmkydng1ivrvr5cbvr1g60-bash-5.2p37",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/fms780awxnslj7rk1wbiv5d89xp2zab4-bash-5.2p37-man",
- "default": true
- },
- {
- "name": "debug",
- "path": "/nix/store/mp6lxkvalsypqqk1mhzl3n5n42hm5ic4-bash-5.2p37-debug"
- },
- {
- "name": "dev",
- "path": "/nix/store/rrb1378zih3wygygg6j4h1nqz76ap940-bash-5.2p37-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/1jwrr261bfms7kcsy8ip3l3vvbvrkl3c-bash-5.2p37-doc"
- },
- {
- "name": "info",
- "path": "/nix/store/nb1bi8pj2i8xdpnmmxd3xrf2rmm4yzjd-bash-5.2p37-info"
- }
- ],
- "store_path": "/nix/store/4fvc5fm8bszmkydng1ivrvr5cbvr1g60-bash-5.2p37"
- }
- }
- },
- "cargo-audit@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#cargo-audit",
- "source": "devbox-search",
- "version": "0.21.0",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/g3j8vhq78ilx3z8xbyz6v8fq5616ks18-cargo-audit-0.21.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/g3j8vhq78ilx3z8xbyz6v8fq5616ks18-cargo-audit-0.21.0"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/icv89n81s6gwlbnx0yaymmpinzrjfgsw-cargo-audit-0.21.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/icv89n81s6gwlbnx0yaymmpinzrjfgsw-cargo-audit-0.21.0"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/n9y7m209hni7f9zifyzkml2i99zf3i75-cargo-audit-0.21.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/n9y7m209hni7f9zifyzkml2i99zf3i75-cargo-audit-0.21.0"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/v8vbpgmkcxfi6bad5c4yzckm6awhp60j-cargo-audit-0.21.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/v8vbpgmkcxfi6bad5c4yzckm6awhp60j-cargo-audit-0.21.0"
- }
- }
- },
- "cargo-binstall@latest": {
- "last_modified": "2025-01-25T23:17:58Z",
- "resolved": "github:NixOS/nixpkgs/b582bb5b0d7af253b05d58314b85ab8ec46b8d19#cargo-binstall",
- "source": "devbox-search",
- "version": "1.10.22",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/5jlq2j60k2mlgjg21zpr4bg7nxjif39s-cargo-binstall-1.10.22",
- "default": true
- }
- ],
- "store_path": "/nix/store/5jlq2j60k2mlgjg21zpr4bg7nxjif39s-cargo-binstall-1.10.22"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/fp3kdp5z0w1k66c4df6w8dvdpbi16qq7-cargo-binstall-1.10.22",
- "default": true
- }
- ],
- "store_path": "/nix/store/fp3kdp5z0w1k66c4df6w8dvdpbi16qq7-cargo-binstall-1.10.22"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/wfzgwccv89s483jbpg0a4rlnkwfrc6ql-cargo-binstall-1.10.22",
- "default": true
- }
- ],
- "store_path": "/nix/store/wfzgwccv89s483jbpg0a4rlnkwfrc6ql-cargo-binstall-1.10.22"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/6qjh7af81x1833rbnzf68n074q8267g6-cargo-binstall-1.10.22",
- "default": true
- }
- ],
- "store_path": "/nix/store/6qjh7af81x1833rbnzf68n074q8267g6-cargo-binstall-1.10.22"
- }
- }
- },
- "cargo-deny@latest": {
- "last_modified": "2025-01-22T23:44:18Z",
- "resolved": "github:NixOS/nixpkgs/1800f90db02ce58f3733498b8052d5d62bf44c2f#cargo-deny",
- "source": "devbox-search",
- "version": "0.16.4",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/ajqxngj26m7c8iqhbx6731hvgl7sa719-cargo-deny-0.16.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/ajqxngj26m7c8iqhbx6731hvgl7sa719-cargo-deny-0.16.4"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/c5qdfj599i8c8w2f8aj5kkbpbng7swfx-cargo-deny-0.16.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/c5qdfj599i8c8w2f8aj5kkbpbng7swfx-cargo-deny-0.16.4"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/6i89ad78sy56svkpv9m1svip247rj2h3-cargo-deny-0.16.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/6i89ad78sy56svkpv9m1svip247rj2h3-cargo-deny-0.16.4"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/iybz72v4yczl4szj319xsvg8mf12zpxr-cargo-deny-0.16.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/iybz72v4yczl4szj319xsvg8mf12zpxr-cargo-deny-0.16.4"
- }
- }
- },
- "cargo-watch@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#cargo-watch",
- "source": "devbox-search",
- "version": "8.5.3",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/3yzx1fmppdkmlaqyyw15v6cbahhg6b64-cargo-watch-8.5.3",
- "default": true
- }
- ],
- "store_path": "/nix/store/3yzx1fmppdkmlaqyyw15v6cbahhg6b64-cargo-watch-8.5.3"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/0bgvg7nnkrgs0x23jlv3pwz1v27l17l8-cargo-watch-8.5.3",
- "default": true
- }
- ],
- "store_path": "/nix/store/0bgvg7nnkrgs0x23jlv3pwz1v27l17l8-cargo-watch-8.5.3"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/k4r7xb1j909dk4zalby8rbm61k9gg41i-cargo-watch-8.5.3",
- "default": true
- }
- ],
- "store_path": "/nix/store/k4r7xb1j909dk4zalby8rbm61k9gg41i-cargo-watch-8.5.3"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/q1pw27krsxg8hzh3xpkrwf1lwzm6kipp-cargo-watch-8.5.3",
- "default": true
- }
- ],
- "store_path": "/nix/store/q1pw27krsxg8hzh3xpkrwf1lwzm6kipp-cargo-watch-8.5.3"
- }
- }
- },
- "direnv@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#direnv",
- "source": "devbox-search",
- "version": "2.35.0",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/q00mwz61l0kz3ikjafm8v42df79vw70m-direnv-2.35.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/q00mwz61l0kz3ikjafm8v42df79vw70m-direnv-2.35.0"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/5qjaj63mcpkbgg9dd7kq326d3zv1nfsq-direnv-2.35.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/5qjaj63mcpkbgg9dd7kq326d3zv1nfsq-direnv-2.35.0"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/7w42jcbp3gl8mswmqkfpm54znbb58116-direnv-2.35.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/7w42jcbp3gl8mswmqkfpm54znbb58116-direnv-2.35.0"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/5acgdhnifp5hsvhw2w34jhs5xqjgv0v3-direnv-2.35.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/5acgdhnifp5hsvhw2w34jhs5xqjgv0v3-direnv-2.35.0"
- }
- }
- },
- "fd@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#fd",
- "source": "devbox-search",
- "version": "10.2.0",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/ckay1nnlygljjn938c94xjc0669qn83r-fd-10.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/ckay1nnlygljjn938c94xjc0669qn83r-fd-10.2.0"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/2v2sycna6fjq8rpl1plp4pfyzg1jd7b3-fd-10.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/2v2sycna6fjq8rpl1plp4pfyzg1jd7b3-fd-10.2.0"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/jq45fqh31n5yrx551pg9fln104l1p2hv-fd-10.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/jq45fqh31n5yrx551pg9fln104l1p2hv-fd-10.2.0"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/4p0c62vy7jw06ygmffhjhgwn11g0bila-fd-10.2.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/4p0c62vy7jw06ygmffhjhgwn11g0bila-fd-10.2.0"
- }
- }
- },
- "golangci-lint@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#golangci-lint",
- "source": "devbox-search",
- "version": "1.63.4",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/p81vg4szd85xb1m5r17fn6h2cd433xv9-golangci-lint-1.63.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/p81vg4szd85xb1m5r17fn6h2cd433xv9-golangci-lint-1.63.4"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/45k8x4b0ygqwpf7di7rcglxsz8ykxz9z-golangci-lint-1.63.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/45k8x4b0ygqwpf7di7rcglxsz8ykxz9z-golangci-lint-1.63.4"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/2xslqh1iyjbhwyynxw09ygfaxzfhmakp-golangci-lint-1.63.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/2xslqh1iyjbhwyynxw09ygfaxzfhmakp-golangci-lint-1.63.4"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/71a493qsawf2gsh3s31zsbrw5pg8psmc-golangci-lint-1.63.4",
- "default": true
- }
- ],
- "store_path": "/nix/store/71a493qsawf2gsh3s31zsbrw5pg8psmc-golangci-lint-1.63.4"
- }
- }
- },
- "jq@latest": {
- "last_modified": "2025-02-08T12:54:32Z",
- "resolved": "github:NixOS/nixpkgs/fa35a3c8e17a3de613240fea68f876e5b4896aec#jq",
- "source": "devbox-search",
- "version": "1.7.1",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "bin",
- "path": "/nix/store/lmlmb3a5kzza0si8xfghr7x17vg8bzxb-jq-1.7.1-bin",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/afygplc4dm1ry7ww3702wafvy8bs9sxc-jq-1.7.1-man",
- "default": true
- },
- {
- "name": "dev",
- "path": "/nix/store/89q76wghz9xj2myglfwpv0n6yc19c8i6-jq-1.7.1-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/dw2717n906kj3xp090fg9cqvcm747jic-jq-1.7.1-doc"
- },
- {
- "name": "out",
- "path": "/nix/store/jm1bv0cha32k9967sv0z40kqgn5slz4i-jq-1.7.1"
- }
- ],
- "store_path": "/nix/store/lmlmb3a5kzza0si8xfghr7x17vg8bzxb-jq-1.7.1-bin"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "bin",
- "path": "/nix/store/vwpm32inl7g5w4p1hqkhjlj1wv0ic67y-jq-1.7.1-bin",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/m546xg6bwy8i785z5a7nx1ca3k9isd93-jq-1.7.1-man",
- "default": true
- },
- {
- "name": "dev",
- "path": "/nix/store/fn8f3hh3k8z3xxkl6al6qx78577w4hdx-jq-1.7.1-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/jzcllz8ry9hnlpq954ik9fi215iir24l-jq-1.7.1-doc"
- },
- {
- "name": "out",
- "path": "/nix/store/msmdzk125aal9mj8d0gd7r4sygh0mg4m-jq-1.7.1"
- }
- ],
- "store_path": "/nix/store/vwpm32inl7g5w4p1hqkhjlj1wv0ic67y-jq-1.7.1-bin"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "bin",
- "path": "/nix/store/j7hzqr3vfjghlm3wfy8va9b6abwhdkpf-jq-1.7.1-bin",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/1yr3pl2mrbb09i203bi1qppbzp4dvp7w-jq-1.7.1-man",
- "default": true
- },
- {
- "name": "dev",
- "path": "/nix/store/5sqag6l82rxxl24vj688vmqrqk4kg45z-jq-1.7.1-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/bg150ikzp69zfjb1klcckzpjy88djnag-jq-1.7.1-doc"
- },
- {
- "name": "out",
- "path": "/nix/store/jw6m3k9r4a7mvzcxr66fxib0s4182i9d-jq-1.7.1"
- }
- ],
- "store_path": "/nix/store/j7hzqr3vfjghlm3wfy8va9b6abwhdkpf-jq-1.7.1-bin"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "bin",
- "path": "/nix/store/n4xfh00cw7vnwnrlx9asp545z82pazgc-jq-1.7.1-bin",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/fj5sc6yb8v39min7kavc0i24nwmlsyki-jq-1.7.1-man",
- "default": true
- },
- {
- "name": "out",
- "path": "/nix/store/4b9rswbcgqiqidglpz6nrwlsfkhi7v22-jq-1.7.1"
- },
- {
- "name": "dev",
- "path": "/nix/store/lcjisy815hp4agl57xqh2w6mic1v8jlf-jq-1.7.1-dev"
- },
- {
- "name": "doc",
- "path": "/nix/store/41ir7g8plmi9257c4g8ag94jl9vhkp4l-jq-1.7.1-doc"
- }
- ],
- "store_path": "/nix/store/n4xfh00cw7vnwnrlx9asp545z82pazgc-jq-1.7.1-bin"
- }
- }
- },
- "just@latest": {
- "last_modified": "2025-01-29T07:48:22Z",
- "resolved": "github:NixOS/nixpkgs/9a5db3142ce450045840cc8d832b13b8a2018e0c#just",
- "source": "devbox-search",
- "version": "1.39.0",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/p0008v5xghjbvinj1cb0drlpa3ljgwps-just-1.39.0",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/pw81j3fwbq1agy0ai1cqzqffjbjffjm2-just-1.39.0-man",
- "default": true
- },
- {
- "name": "doc",
- "path": "/nix/store/vysi0rsapljs8nm13qd1q1m8x0rd1p70-just-1.39.0-doc"
- }
- ],
- "store_path": "/nix/store/p0008v5xghjbvinj1cb0drlpa3ljgwps-just-1.39.0"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/k9586qna4zpwhnsn76x2p7g6nm0vhgbv-just-1.39.0",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/ji62wi00zgj4vrpwywkdl8kwykv19i6n-just-1.39.0-man",
- "default": true
- },
- {
- "name": "doc",
- "path": "/nix/store/3i3dk8bjyz4q9wawm1dkv1vk0sl7gbzj-just-1.39.0-doc"
- }
- ],
- "store_path": "/nix/store/k9586qna4zpwhnsn76x2p7g6nm0vhgbv-just-1.39.0"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/s4w13zxwnly9z9j499fypx7kx7iffzfq-just-1.39.0",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/06ppryxxfnzklbxka8ycz8cabbklscpr-just-1.39.0-man",
- "default": true
- },
- {
- "name": "doc",
- "path": "/nix/store/rlv196k7vyi2g9gb0g0dbg34xh27nppg-just-1.39.0-doc"
- }
- ],
- "store_path": "/nix/store/s4w13zxwnly9z9j499fypx7kx7iffzfq-just-1.39.0"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/vnyj5n5pgljwmwb9a4938hhry4w4fylk-just-1.39.0",
- "default": true
- },
- {
- "name": "man",
- "path": "/nix/store/fsn8pwjpszqywx364njl1bx6zk5rgrhd-just-1.39.0-man",
- "default": true
- },
- {
- "name": "doc",
- "path": "/nix/store/bnxwbxb6mlyi0x8xfgh05j82w5z2szaw-just-1.39.0-doc"
- }
- ],
- "store_path": "/nix/store/vnyj5n5pgljwmwb9a4938hhry4w4fylk-just-1.39.0"
- }
- }
- },
- "mise@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#mise",
- "source": "devbox-search",
- "version": "2025.1.6",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/gl3i47g0098sgc3784l7s7776712whqk-mise-2025.1.6",
- "default": true
- }
- ],
- "store_path": "/nix/store/gl3i47g0098sgc3784l7s7776712whqk-mise-2025.1.6"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/5pzvsfql8wmgajinnja561fg69bi99dm-mise-2025.1.6",
- "default": true
- }
- ],
- "store_path": "/nix/store/5pzvsfql8wmgajinnja561fg69bi99dm-mise-2025.1.6"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/2cyfrdgvql7zcfkjsnc9kgsiynwz8amp-mise-2025.1.6",
- "default": true
- }
- ],
- "store_path": "/nix/store/2cyfrdgvql7zcfkjsnc9kgsiynwz8amp-mise-2025.1.6"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/lf4b7s9hlvzw2ais2621qvmkw56ww9bz-mise-2025.1.6",
- "default": true
- }
- ],
- "store_path": "/nix/store/lf4b7s9hlvzw2ais2621qvmkw56ww9bz-mise-2025.1.6"
- }
- }
- },
- "pnpm@latest": {
- "last_modified": "2025-02-07T11:26:36Z",
- "resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#pnpm",
- "source": "devbox-search",
- "version": "10.2.1",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/f69kr305skrj3zf7fn96fcw3mr87dh59-pnpm-10.2.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/f69kr305skrj3zf7fn96fcw3mr87dh59-pnpm-10.2.1"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/qww560lnjwb20ln7gjwq9ylb2sjkbbf5-pnpm-10.2.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/qww560lnjwb20ln7gjwq9ylb2sjkbbf5-pnpm-10.2.1"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/xcy99hb5djnijhpm4ql1iyif7lldjw4l-pnpm-10.2.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/xcy99hb5djnijhpm4ql1iyif7lldjw4l-pnpm-10.2.1"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/zk7vgm4h5d5sv3wsxmwknixnc1dhmm80-pnpm-10.2.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/zk7vgm4h5d5sv3wsxmwknixnc1dhmm80-pnpm-10.2.1"
- }
- }
- },
- "pre-commit@latest": {
- "last_modified": "2025-01-31T04:26:24Z",
- "resolved": "github:NixOS/nixpkgs/9189ac18287c599860e878e905da550aa6dec1cd#pre-commit",
- "source": "devbox-search",
- "version": "4.0.1",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/0wmqj4m2pz3kkqcsnvc0pzsyjqqx0zn3-pre-commit-4.0.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/68mri4rclghlcvvf1bldxfjl357qxzxn-pre-commit-4.0.1-dist"
- }
- ],
- "store_path": "/nix/store/0wmqj4m2pz3kkqcsnvc0pzsyjqqx0zn3-pre-commit-4.0.1"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/659xf9l2275gyw92ra5x5r6vhsfnamx6-pre-commit-4.0.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/91pf595x4pvlrh4qyp43sf2arnn6s63i-pre-commit-4.0.1-dist"
- }
- ],
- "store_path": "/nix/store/659xf9l2275gyw92ra5x5r6vhsfnamx6-pre-commit-4.0.1"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/0l7d2aj7j6hqc3wjln57dr2w0b1va8gk-pre-commit-4.0.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/y62pjir7a9qjxxg1aclxpr63hn7gvlbd-pre-commit-4.0.1-dist"
- }
- ],
- "store_path": "/nix/store/0l7d2aj7j6hqc3wjln57dr2w0b1va8gk-pre-commit-4.0.1"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/mysa4nbqz7i266qnrxng859gz436szjr-pre-commit-4.0.1",
- "default": true
- },
- {
- "name": "dist",
- "path": "/nix/store/0c5q7fb7rqy75yqhv44cy6g23ybwaa98-pre-commit-4.0.1-dist"
- }
- ],
- "store_path": "/nix/store/mysa4nbqz7i266qnrxng859gz436szjr-pre-commit-4.0.1"
- }
- }
- },
- "rust-cbindgen@latest": {
- "last_modified": "2025-02-07T11:26:36Z",
- "resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#rust-cbindgen",
- "source": "devbox-search",
- "version": "0.28.0",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/k2d8hd05fxsiwls6x2bppahg79563x90-rust-cbindgen-0.28.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/k2d8hd05fxsiwls6x2bppahg79563x90-rust-cbindgen-0.28.0"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/99k7mbqfab68ggzslhfcasdx6rzc1wxx-rust-cbindgen-0.28.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/99k7mbqfab68ggzslhfcasdx6rzc1wxx-rust-cbindgen-0.28.0"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/2hakjjfbjw717vz729d3g7gmp122qcrz-rust-cbindgen-0.28.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/2hakjjfbjw717vz729d3g7gmp122qcrz-rust-cbindgen-0.28.0"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/p3xwjvwwh33c81c6iq7y369lckyk5x0i-rust-cbindgen-0.28.0",
- "default": true
- }
- ],
- "store_path": "/nix/store/p3xwjvwwh33c81c6iq7y369lckyk5x0i-rust-cbindgen-0.28.0"
- }
- }
- },
- "uv@latest": {
- "last_modified": "2025-02-07T11:26:36Z",
- "resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#uv",
- "source": "devbox-search",
- "version": "0.5.29",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/2f9zdf7sxsva89p3fzxry5m9p6ivax05-uv-0.5.29",
- "default": true
- }
- ],
- "store_path": "/nix/store/2f9zdf7sxsva89p3fzxry5m9p6ivax05-uv-0.5.29"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/0imbdi62wdayj9ljk4ihjr83g8jwhsh8-uv-0.5.29",
- "default": true
- }
- ],
- "store_path": "/nix/store/0imbdi62wdayj9ljk4ihjr83g8jwhsh8-uv-0.5.29"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/2cj7x75haqxnn9ixcq6cglj14i4j5w4y-uv-0.5.29",
- "default": true
- }
- ],
- "store_path": "/nix/store/2cj7x75haqxnn9ixcq6cglj14i4j5w4y-uv-0.5.29"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/sjvnlrxn0145v7kqcx99ys5n27agy5cz-uv-0.5.29",
- "default": true
- }
- ],
- "store_path": "/nix/store/sjvnlrxn0145v7kqcx99ys5n27agy5cz-uv-0.5.29"
- }
- }
- },
- "wasm-bindgen-cli@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#wasm-bindgen-cli",
- "source": "devbox-search",
- "version": "0.2.100",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/rdiwxzp0b0iisdr60d44zi31lip5k5qr-wasm-bindgen-cli-0.2.100",
- "default": true
- }
- ],
- "store_path": "/nix/store/rdiwxzp0b0iisdr60d44zi31lip5k5qr-wasm-bindgen-cli-0.2.100"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/vd9dswj4jhgaxaimif66klszwx28i69g-wasm-bindgen-cli-0.2.100",
- "default": true
- }
- ],
- "store_path": "/nix/store/vd9dswj4jhgaxaimif66klszwx28i69g-wasm-bindgen-cli-0.2.100"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/l77mpcd8wrlhfnv0n8z1cpxqcfvd56d3-wasm-bindgen-cli-0.2.100",
- "default": true
- }
- ],
- "store_path": "/nix/store/l77mpcd8wrlhfnv0n8z1cpxqcfvd56d3-wasm-bindgen-cli-0.2.100"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/4nll8fdpzziq7glr6swbix4w32pkdxiq-wasm-bindgen-cli-0.2.100",
- "default": true
- }
- ],
- "store_path": "/nix/store/4nll8fdpzziq7glr6swbix4w32pkdxiq-wasm-bindgen-cli-0.2.100"
- }
- }
- },
- "wasm-pack@latest": {
- "last_modified": "2025-01-19T08:16:51Z",
- "resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#wasm-pack",
- "source": "devbox-search",
- "version": "0.13.1",
- "systems": {
- "aarch64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/kh6q4zgcj7sdn8jyciwg328lh391azci-wasm-pack-0.13.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/kh6q4zgcj7sdn8jyciwg328lh391azci-wasm-pack-0.13.1"
- },
- "aarch64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/a7fhfbsxvlrdxr16jz6c5v896bkhyvm3-wasm-pack-0.13.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/a7fhfbsxvlrdxr16jz6c5v896bkhyvm3-wasm-pack-0.13.1"
- },
- "x86_64-darwin": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/3qgxq8li64m1f4bwzzpfk6717g9biamm-wasm-pack-0.13.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/3qgxq8li64m1f4bwzzpfk6717g9biamm-wasm-pack-0.13.1"
- },
- "x86_64-linux": {
- "outputs": [
- {
- "name": "out",
- "path": "/nix/store/wvp89h4j0znccyj2kpmp2w3110z2lmvi-wasm-pack-0.13.1",
- "default": true
- }
- ],
- "store_path": "/nix/store/wvp89h4j0znccyj2kpmp2w3110z2lmvi-wasm-pack-0.13.1"
- }
- }
- }
- }
-}
diff --git a/template/mise.lock b/template/mise.lock
new file mode 100644
index 0000000..d10681c
--- /dev/null
+++ b/template/mise.lock
@@ -0,0 +1,99 @@
+[tools.cargo-binstall]
+version = "1.12.7"
+backend = "aqua:cargo-bins/cargo-binstall"
+
+[tools."cargo:cargo-audit"]
+version = "0.21.2"
+backend = "cargo:cargo-audit"
+
+[tools."cargo:cargo-deny"]
+version = "0.18.2"
+backend = "cargo:cargo-deny"
+
+[tools."cargo:cargo-hack"]
+version = "0.6.36"
+backend = "cargo:cargo-hack"
+
+[tools."cargo:cargo-llvm-cov"]
+version = "0.6.16"
+backend = "cargo:cargo-llvm-cov"
+
+[tools."cargo:cargo-msrv"]
+version = "0.18.4"
+backend = "cargo:cargo-msrv"
+
+[tools."cargo:cargo-nextest"]
+version = "0.9.98"
+backend = "cargo:cargo-nextest"
+
+[tools."cargo:cargo-outdated"]
+version = "0.17.0"
+backend = "cargo:cargo-outdated"
+
+[tools."cargo:cargo-watch"]
+version = "8.5.3"
+backend = "cargo:cargo-watch"
+
+[tools."cargo:cbindgen"]
+version = "0.29.0"
+backend = "cargo:cbindgen"
+
+[tools."cargo:wasm-bindgen-cli"]
+version = "0.2.100"
+backend = "cargo:wasm-bindgen-cli"
+
+[tools."cargo:wasm-pack"]
+version = "0.13.1"
+backend = "cargo:wasm-pack"
+
+[tools.fd]
+version = "10.2.0"
+backend = "aqua:sharkdp/fd"
+
+[tools.go]
+version = "1.24.4"
+backend = "core:go"
+
+[tools."go:github.com/google/addlicense"]
+version = "1.1.1"
+backend = "go:github.com/google/addlicense"
+
+[tools.golangci-lint]
+version = "2.1.6"
+backend = "aqua:golangci/golangci-lint"
+
+[tools.jq]
+version = "1.8.0"
+backend = "aqua:jqlang/jq"
+
+[tools.just]
+version = "1.40.0"
+backend = "ubi:casey/just"
+
+[tools.node]
+version = "22.16.0"
+backend = "core:node"
+
+[tools.pnpm]
+version = "10.11.1"
+backend = "aqua:pnpm/pnpm"
+
+[tools.pre-commit]
+version = "4.1.0"
+backend = "aqua:pre-commit/pre-commit"
+
+[tools.python]
+version = "3.12.11"
+backend = "core:python"
+
+[tools.rust]
+version = "1.87.0"
+backend = "core:rust"
+
+[tools."ubi:https://github.com/WebAssembly/wabt/releases/tag/1.0.37"]
+version = "latest"
+backend = "ubi:https://github.com/WebAssembly/wabt/releases/tag/1.0.37"
+
+[tools.uv]
+version = "0.7.9"
+backend = "aqua:astral-sh/uv"
diff --git a/template/mise.toml b/template/mise.toml
new file mode 100644
index 0000000..748b4a3
--- /dev/null
+++ b/template/mise.toml
@@ -0,0 +1,38 @@
+[tools]
+"cargo:cargo-audit" = "latest"
+"cargo:cargo-deny" = "latest"
+"cargo:cargo-hack" = "latest"
+"cargo:cargo-llvm-cov" = "latest"
+"cargo:cargo-msrv" = "latest"
+"cargo:cargo-nextest" = "latest"
+"cargo:cargo-outdated" = "latest"
+"cargo:cargo-watch" = "latest"
+"cargo:cbindgen" = "latest"
+"cargo:wasm-bindgen-cli" = "latest"
+"cargo:wasm-pack" = "latest"
+"go:github.com/google/addlicense" = "latest"
+"ubi:https://github.com/WebAssembly/wabt/releases/tag/1.0.37" = "latest"
+
+# Build tools
+cargo-binstall = "latest"
+fd = "latest"
+go = "prefix:1.24"
+golangci-lint = "latest"
+jq = "latest"
+just = "latest"
+node = "lts"
+pnpm = "latest"
+pre-commit = "latest"
+python = "prefix:3.12"
+rust = "prefix:1.87"
+uv = "latest"
+
+[env]
+COREPACK_ENABLE_DOWNLOAD_PROMPT = "1"
+LIBRARY_PATH = "$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib:/opt/homebrew/opt/libiconv/lib"
+MACOSX_DEPLOYMENT_TARGET = "11.0"
+RUST_BACKTRACE = "1"
+RUSTFLAGS = "-D warnings"
+
+[settings]
+experimental = true
diff --git a/template/mise.toml.jinja b/template/mise.toml.jinja
deleted file mode 100644
index d6b9b87..0000000
--- a/template/mise.toml.jinja
+++ /dev/null
@@ -1,17 +0,0 @@
-[tools]
-"go:github.com/google/addlicense" = "latest"
-cargo-binstall = "latest"
-direnv = "latest"
-fd = "latest"
-go = "prefix:1.24"
-golangci-lint = "latest"
-jq = "latest"
-just = "latest"
-node = "lts"
-pre-commit = "latest"
-python = "prefix:3.12"
-rust = "prefix:1.85"
-uv = "latest"
-
-[settings]
-experimental = true
diff --git a/template/nextest.toml b/template/nextest.toml
new file mode 100644
index 0000000..81c9a51
--- /dev/null
+++ b/template/nextest.toml
@@ -0,0 +1,13 @@
+[profile.default]
+# Run tests in parallel
+test-threads = "num-cpus"
+# Retry flaky tests
+retries = 1
+# Fail fast on first error
+fail-fast = false
+
+[profile.ci]
+# More conservative settings for CI - 3 is the sweet-spot for flaky network/filesystem tests
+test-threads = 4
+retries = 3
+fail-fast = true
\ No newline at end of file
diff --git a/template/rust-toolchain.toml b/template/rust-toolchain.toml
new file mode 100644
index 0000000..b4e9521
--- /dev/null
+++ b/template/rust-toolchain.toml
@@ -0,0 +1,3 @@
+[toolchain]
+channel = "1.87.0"
+components = ["rustfmt", "clippy", "miri", "rust-src"]
\ No newline at end of file
diff --git a/template/rustfmt.toml b/template/rustfmt.toml
index de2278a..7b4b5d8 100644
--- a/template/rustfmt.toml
+++ b/template/rustfmt.toml
@@ -1,16 +1,3 @@
-max_width = 100 # Set maximum line width to 100 characters.
-hard_tabs = false # Use spaces for indentation.
-tab_spaces = 4 # 4 spaces per indentation level.
-newline_style = "Unix" # Use Unix-style line endings.
-use_small_heuristics = "Default" # Enable default heuristics for layout decisions.
-
-# Function and method formatting:
-fn_params_layout = "Tall" # Format function arguments on separate lines when needed.
-chain_width = 100 # Allow chains (e.g. method chains) to extend up to 100 characters.
-
-# Struct and literal formatting:
-struct_lit_width = 100 # Maximum width for struct literals.
-struct_variant_width = 100 # Maximum width for enum variants with struct-like syntax.
-
-# Import formatting:
-reorder_imports = true # Automatically reorder imports alphabetically.
+max_width = 120
+edition = "2021"
+newline_style = "Unix"
diff --git a/template/scripts/dev-setup.sh b/template/scripts/dev-setup.sh
new file mode 100755
index 0000000..35b87e1
--- /dev/null
+++ b/template/scripts/dev-setup.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+# Install mise
+if command -v mise >/dev/null 2>&1; then
+ echo "mise is already installed"
+else
+ echo "mise is not installed"
+ if command -v brew >/dev/null 2>&1; then
+ echo "brew is installed"
+ brew install mise
+ else
+ echo "brew is not installed"
+ curl https://mise.run | sh
+ fi
+fi
diff --git "a/template/{{\"go\" if include_go else \"__skip_go__\"}}/Justfile.jinja" "b/template/{{\"go\" if include_go else \"__skip_go__\"}}/Justfile.jinja"
index 0a9a1cf..a100ebb 100644
--- "a/template/{{\"go\" if include_go else \"__skip_go__\"}}/Justfile.jinja"
+++ "b/template/{{\"go\" if include_go else \"__skip_go__\"}}/Justfile.jinja"
@@ -33,7 +33,7 @@ generate-bindings:
# Build the project
build: generate-bindings
#!/usr/bin/env bash
- set -e
+ set -euxo pipefail
eval "$(just _setup-env)"
go build ./...
@@ -41,7 +41,7 @@ build: generate-bindings
# Run tests
test: generate-bindings
#!/usr/bin/env bash
- set -e
+ set -euxo pipefail
eval "$(just _setup-env)"
go test ./...
@@ -49,7 +49,7 @@ test: generate-bindings
# Run linter
lint:
#!/usr/bin/env bash
- set -e
+ set -euxo pipefail
eval "$(just _setup-env)"
golangci-lint run ./...
diff --git "a/template/{{\"go\" if include_go else \"__skip_go__\"}}/go/binding.go.jinja" "b/template/{{\"go\" if include_go else \"__skip_go__\"}}/go/binding.go.jinja"
index 479917e..839c97e 100644
--- "a/template/{{\"go\" if include_go else \"__skip_go__\"}}/go/binding.go.jinja"
+++ "b/template/{{\"go\" if include_go else \"__skip_go__\"}}/go/binding.go.jinja"
@@ -3,7 +3,7 @@ package binding
/*
#cgo CFLAGS: -I${SRCDIR}/..
-#cgo LDFLAGS: -L${SRCDIR}/../../target/debug -l{{ project_slug_underscore}}_go
+#cgo LDFLAGS: -L${SRCDIR}/../../target/debug -l{{ project_slug_underscore }}_go
#include "binding.h"
#include
diff --git "a/template/{{\"go-wasm\" if include_go else \"__skip_go_wasm__\"}}/go/binding.go.jinja" "b/template/{{\"go-wasm\" if include_go else \"__skip_go_wasm__\"}}/go/binding.go.jinja"
index d85da64..909e0cc 100644
--- "a/template/{{\"go-wasm\" if include_go else \"__skip_go_wasm__\"}}/go/binding.go.jinja"
+++ "b/template/{{\"go-wasm\" if include_go else \"__skip_go_wasm__\"}}/go/binding.go.jinja"
@@ -6,6 +6,7 @@ import (
_ "embed"
"errors"
"fmt"
+ "log"
"sync"
"sync/atomic"
"time"
@@ -127,7 +128,12 @@ func Parse(ctx context.Context, input string) (*Expression, error) {
if err != nil {
return nil, fmt.Errorf("failed to instantiate WASM module: %w", err)
}
- defer module.Close(ctx) // Clean up this instance when done
+ defer func() {
+ if closeErr := module.Close(ctx); closeErr != nil {
+ // Log cleanup error - this shouldn't normally happen but good to know if it does
+ log.Printf("warning: failed to close WASM module: %v\n", closeErr)
+ }
+ }()
// Get the needed export functions
allocate := module.ExportedFunction("allocate")
@@ -274,7 +280,12 @@ func GetWasmTimestamp(ctx context.Context) (time.Time, error) {
if err != nil {
return time.Time{}, fmt.Errorf("failed to instantiate WASM module: %w", err)
}
- defer module.Close(ctx)
+ defer func() {
+ if closeErr := module.Close(ctx); closeErr != nil {
+ // Log cleanup error - this shouldn't normally happen but good to know if it does
+ log.Printf("warning: failed to close WASM module: %v\n", closeErr)
+ }
+ }()
// Call the get_timestamp_ms function
getTimestamp := module.ExportedFunction("get_timestamp_ms")