graphql-engine/scripts/hpack.sh
Samir Talwar 07328fd9fc server: Automate generation and verification of Cabal files from hpack.
We currently use `hpack` to generate the Cabal files from _package.yaml_
files for the two small libraries in _server/lib_. While this is more
convenient, we also check the Cabal files into the repository to avoid
needing an extra step upon pulling changes.

In order to ensure that the Cabal files do not get out of sync with the
hpack files, this introduces a few improvements:

1.  Makefile targets to automatically generate the Cabal files without
    needing to know the correct incantation. These targets are a
    dependency of all build targets, so you can simply run
    `make build-all` and it will work.
2.  An extra comment at the top of all generated Cabal files that
    explains how to regenerate it.
3.  A `lint-hpack` Makefile target that verifies that the Cabal files
    are up-to-date.
4.  A CI job that runs `make lint-hpack`, to stop inconsistencies
    getting merged into trunk.

Most of these changes are ported from #4794.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5217
GitOrigin-RevId: d3dfbe19ec00528368d357b6d0215a7ba4062f68
2022-07-29 16:22:12 +00:00

52 lines
1.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# This runs `hpack`, but generates a custom header that instructs the reader not to edit the file.
# It instead tells them to edit package.yaml and run a specific `make` command.
set -e
set -u
set -o pipefail
root_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")/.." &> /dev/null && pwd 2> /dev/null)"
function usage {
echo >&2 'Usage:'
echo >&2 " ${BASH_SOURCE[0]} [--check] TARGET"
echo >&2
# shellcheck disable=SC2016
echo >&2 '--check: Do not write the file; instead verify that it is up-to-date.'
echo >&2 'TARGET: The Cabal file to be generated from package.yaml in the same directory.'
exit 2
}
# Prefix the target file with a custom header.
function modify {
# Write the Cabal version information first; it must be before any comments.
awk "{ print }; NR == 2 { print \"-- This file is generated using hpack.\n-- Do not modify it directly. Instead, edit package.yaml and then run:\n-- make ${target}\n\" }"
}
if [[ "$1" == '--check' ]]; then
check=true
shift
else
check=false
fi
if [[ $# -ne 1 ]]; then
usage
fi
# The target must be relative to the root of the project for the `make` command to be meaningful.
target="$(realpath --relative-to="$root_dir" "$1")"
source="$(dirname "$target")"
if $check; then
output="$(mktemp -t "$(basename "$target").XXXXX")"
trap 'rm -f "$output"' EXIT
hpack "$source" - | modify > "$output"
# `git diff` will return a non-zero exit status if the files are different.
git diff --no-index "$target" "$output"
else
hpack "$source" - | modify > "$target"
fi