# Repeat-CLI 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/tmp
    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/tmp:/cache/tmp" \
        -e CARGO_HOME=/cache/cargo \
        -e CARGO_TARGET_DIR=/cache/target \
        -e TMPDIR=/cache/tmp \
        -e CI=true \
        -w "$HOST_PATH" \
        git.kemitix.net/kemitix/rust:v5.4.0 \
        sh -c "{{ ci_dependencies }} \
            echo \"FORMAT:\" && cargo +nightly fmt --all && \
            echo \"MACHETE:\" && cargo +nightly machete && \
            echo \"CLIPPY:\" && cargo +nightly clippy --all-targets -- -D warnings && \
            echo \"PEDANT:\" && cargo +nightly clippy -- -W clippy::pedantic -D warnings && \
            echo \"TESTS:\" && RUST_LOG=debug cargo +nightly nextest run --workspace --no-fail-fast"

# Project-specific dependencies (runs inside Docker before main CI steps)
ci_dependencies := ""

# Publish crates to crates.io
publish:
    #!/usr/bin/env bash
    set -euo pipefail
    
    echo "=== Checking for unexpected uncommitted files ==="
    # Get list of uncommitted files from cargo's perspective
    dirty_files=$(cargo package --list 2>&1 | grep "^crates/" || true)
    
    # Check if any dirty files are outside the allowed directory
    unexpected=""
    while IFS= read -r file; do
        [[ -z "$file" ]] && continue
        unexpected+="  $file"$'\n'
    done <<< "$dirty_files"
    
    if [[ -n "$unexpected" ]]; then
        echo "ERROR: Unexpected uncommitted files detected:"
        echo "$unexpected"
        echo "Only files in crates/server/static/wasm/ may be uncommitted."
        echo "Commit or stash these files before publishing."
        exit 1
    fi
    
    echo "=== Publishing repeat-cli ==="
    cargo publish -p repeat-cli
    
    echo "=== Done! ==="

# 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 all quality checks and fix formatting
fix: fmt
    cargo machete --fix || true
    just ci 2>&1 | rg -v 'unstable features are only available in nightly channel'

# 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}"

# 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
