#!/bin/sh
# script/prettier: run prettier over this repo's canonical file set.
#
# Takes exactly one mode argument, --write or --check, and applies the
# same patterns in both modes. script/fmt and script/fmt-check both go
# through here, so the set of files that get formatted and the set that
# get verified cannot drift apart.
#
# Failures are never swallowed: a missing prettier is an error, not a
# silent skip. A formatter that quietly does nothing is worse than one
# that fails loudly.
set -eu

ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"

usage() {
    echo "usage: script/prettier --write|--check" >&2
    exit 2
}

# Only the prettier yarn installed from yarn.lock, never one on PATH: a
# different version formats differently.
PRETTIER="$ROOT/node_modules/.bin/prettier"

main() {
    [ "$#" -eq 1 ] || usage
    case "$1" in
        --write | --check) mode="$1" ;;
        *) usage ;;
    esac

    cd "$ROOT"

    # node_modules keeps the old prettier after package.json moves to a new
    # one, until script/bootstrap runs again, so compare the two. A prettier
    # that runs also means node is on PATH, which reading package.json needs.
    if ! installed="$("$PRETTIER" --version 2>/dev/null)"; then
        echo "prettier: not installed; run script/bootstrap" >&2
        exit 1
    fi
    pinned="$(node -p 'require("./package.json").devDependencies.prettier')"
    if [ "$installed" != "$pinned" ]; then
        echo "prettier: package.json pins $pinned but $installed is" \
            "installed; run script/bootstrap" >&2
        exit 1
    fi

    # Markdown and JSON, repo-wide rather than root-only, so files in
    # subdirectories (docs/, once it exists) are covered too. Exclusions
    # live in .prettierignore; REPO_POLICIES.md is excluded there because
    # it is a verbatim copy of an upstream document.
    #
    # --no-error-on-unmatched-pattern is deliberately NOT used: both
    # patterns always match at least one tracked file (README.md,
    # package.json), so an empty match means the glob broke, and prettier
    # erroring out is exactly what we want rather than a vacuous pass.
    "$PRETTIER" "$mode" "**/*.md"
    "$PRETTIER" "$mode" "**/*.json"
}

main "$@"
