# Ivorn development recipes
# Run all CI quality checks locally (matches CrowCI environment)
ci:
#!/usr/bin/env bash
# Translate container path to host path if running inside project-mgmt container
if [ -f /.dockerenv ] && [ "$PWD" != "${PWD#/workspace}" ]; then
HOST_PATH="/home/pcampbell/Projects/ProjectManagement${PWD#/workspace}"
else
HOST_PATH="$(pwd)"
fi
mkdir -p .cache/cargo/registry .cache/cargo/git .cache/target .cache/deno
docker run --rm \
-u "$(id -u):$(id -g)" \
-v "$HOST_PATH:$HOST_PATH" \
-v "$HOST_PATH/.cache/cargo/registry:/cache/cargo/registry" \
-v "$HOST_PATH/.cache/cargo/git:/cache/cargo/git" \
-v "$HOST_PATH/.cache/target:/cache/target" \
-v "$HOST_PATH/.cache/deno:/cache/deno" \
-e CARGO_HOME=/cache/cargo \
-e CARGO_TARGET_DIR=/cache/target \
-e DENO_DIR=/cache/deno \
-e CI=true \
-w "$HOST_PATH" \
git.kemitix.net/kemitix/rust:v5.0.0 \
sh -c "{{ ci_dependencies }} \
echo \"TEST-JS:\" && deno test --allow-read tests/ && \
echo \"FORMAT:\" && cargo +nightly fmt --check && \
echo \"CHECK:\" && cargo +stable check && \
echo \"MACHETE:\" && cargo +stable machete && \
echo \"CLIPPY:\" && cargo +stable clippy --all-targets -- -D warnings && \
echo \"PEDANT:\" && cargo +stable clippy -- -W clippy::pedantic -D warnings && \
echo \"BUILD:\" && cargo +stable build && \
echo \"RUN-TESTS:\" && RUST_LOG=debug cargo +stable nextest run --no-fail-fast"
# Project-specific dependencies
ci_dependencies := ""
# Format code
fmt:
cargo +nightly fmt
# Check for compiler errors/warnings
check:
cargo check
# Run clippy linter
clippy:
cargo clippy --all-targets -- -D warnings
# Run tests
test:
cargo nextest run
# Run tests in sequence
sequ-test:
cargo test
# Run JavaScript tests with Deno
test-js:
$(mise which deno) test --allow-read tests/
# Run all quality checks and fix formatting
fix:
cargo +nightly fmt 2>/dev/null
cargo machete --fix || true
just ci 2>&1 | rg -v 'unstable features are only available in nightly channel'
bisect-bad:
jj bookmark move BAD --to @- --allow-backwards
just bisect-next
bisect-good:
jj bookmark move GOOD --to @-
just bisect-next
bisect-next:
#!/usr/bin/env bash
if jj log -r 'BAD-' --no-graph -T 'commit_id' | grep -q "$(jj log -r 'GOOD' --no-graph -T 'commit_id')"; then
echo "Bisect complete: BAD bookmark's parent is GOOD bookmark"
exit 0
fi
jj new -r 'bisect(GOOD..BAD)'
just bisect-test
bisect-test:
just ci && just bisect-good || just bisect-bad
log-op-position:
@echo ""
@echo "---"
jj op log -n 1
# Run specific test(s) with optional features
# Examples:
# just test-specific v2 # Run all v2 module tests
# just test-specific v2 codegen-v2 # Run v2 tests with codegen-v2 feature
# just test-specific nesting_4_level "" # Run specific test file, no features
test-specific test_name features="":
#!/usr/bin/env bash
timestamp=$(date +%Y-%m-%d-%H-%M-%S)
output_file=".output-${timestamp}-test-{{test_name}}.log"
if [ "{{features}}" = "" ]; then
echo "Running: cargo nextest run --test {{test_name}}"
cargo nextest run --test {{test_name}} &> "${output_file}"
else
echo "Running: cargo nextest run --features {{features}} --test {{test_name}}"
cargo nextest run --features {{features}} --test {{test_name}} &> "${output_file}"
fi
echo "Output saved to: ${output_file}"
# Expand macro for specific test with features
# Examples:
# just expand tree-type-proc-macro dynamic_id_test codegen-v2
# just expand tree-type comprehensive_test
# just expand tree-type-proc-macro dynamic_id_test "codegen-v2,serde"
expand package test_name *features="":
#!/bin/bash
timestamp=$(date +%Y-%m-%d-%H-%M-%S)
output_file=".output-${timestamp}-expand-{{test_name}}.log"
feature_flags=""
if [ "{{features}}" != "" ]; then
feature_flags="--features {{features}}"
fi
echo "Expanding test {{test_name}} with features: {{features}}"
cargo expand -p {{package}} ${feature_flags} --test {{test_name}} &> "${output_file}"
echo "Output saved to: ${output_file}"
echo "Use: head -50 ${output_file} | grep -A 20 -B 5 'struct.*{{test_name}}'"
# Compile expanded macro output to verify it compiles correctly
compile-expanded package test_name *features="":
#!/bin/bash
just expand {{package}} {{test_name}} {{features}}
timestamp=$(date +%Y-%m-%d-%H-%M-%S)
output_file=".output-${timestamp}-compile-{{test_name}}.log"
expanded_file=$(ls -t .output-*-expand-{{test_name}}.log 2>/dev/null | head -1)
echo "Compiling: $expanded_file"
rustc --edition 2024 --crate-type bin --test \
-L target/debug/deps \
--extern tree_type=target/debug/libtree_type.rlib \
"$expanded_file" -o /tmp/test_expanded &> "${output_file}"
echo "Output saved to: ${output_file}"
# Run Ivorn Server locally
run projects="..":
cargo run -- {{projects}}
@serve:
just run ../..
# Build Docker image locally with git hash
docker-build:
docker build --build-arg GIT_HASH=$(git rev-parse --short HEAD) .
# performs a `jj git` command for each remote
_each-remote op:
#!/usr/bin/env bash
REMOTES=$(jj git remote list | sort --random-sort | cut -d\ -f 1)
for remote in $REMOTES
do
echo "--- {{op}} $remote ---"
time jj git {{op}} --remote $remote
echo ""
done
# advance the main bookmark to @-, then push to all remotes
advance-push: advance push
# advance the main bookmark to @-
advance:
jj bookmark advance
# Runs `jj git push` for each remote
push:
@just _each-remote push
# Runs `jj git fetch` for each remote
fetch:
@just _each-remote fetch
# Create and publish a new release
release:
#!/usr/bin/env bash
set -euo pipefail
echo "=== Stack: bump version and update changelog ==="
cairn stack
echo ""
echo "=== Advance dev bookmark ==="
jj bookmark advance
echo ""
echo "=== Push dev to origin ==="
jj git push --remote origin --bookmark dev
echo ""
echo "=== Mark: wait for CI and create release ==="
cairn mark