qctl 0.5.0

Control in-repo YAML work queues
# CI already runs `mise run verify`. Do not arm hooks on runners.
pre-commit:
  skip:
    - run: test -n "$CI"
  commands:
    format:
      glob: "**/*.rs"
      run: mise run format

commit-msg:
  skip:
    - run: test -n "$CI"
  commands:
    committed:
      run: mise run commit-msg {1}

pre-push:
  skip:
    - run: test -n "$CI"
  commands:
    lockfile:
      run: mise install --locked
    committed:
      # Lint each pushed commit that neither origin/main nor the remote
      # branch already has. Git passes one
      # `<local ref> <local sha> <remote ref> <remote sha>` line per ref on
      # stdin. A branch that merged main carries main's commits, and squash
      # merges land on main without this hook, so either base alone can
      # let those through: a stale origin/main misses what the remote
      # branch merged, and the remote sha misses what a local merge
      # brought. With neither base, the pushed commit is linted alone.
      use_stdin: true
      run: |
        zero=0000000000000000000000000000000000000000
        while read -r _ lsha _ rsha; do
          [ "$lsha" = "$zero" ] && continue
          bases=""
          if git rev-parse -q --verify origin/main >/dev/null; then
            bases="origin/main"
          fi
          if [ "$rsha" != "$zero" ] && git cat-file -e "$rsha^{commit}" 2>/dev/null; then
            bases="$bases $rsha"
          fi
          if [ -n "$bases" ]; then
            commits=$(git rev-list "$lsha" --not $bases)
          else
            commits=$lsha
          fi
          [ -n "$commits" ] || continue
          mise run commits $commits </dev/null || exit 1
        done
    verify:
      # Git exports GIT_DIR and friends to hooks. Tests that probe a scratch
      # directory with `git -C` would find this repository instead.
      run: unset $(git rev-parse --local-env-vars) && mise run verify