| #!/usr/bin/env bash | |
| # SPDX-License-Identifier: GPL-2.0-or-later | |
| # Copyright (c) Jarkko Sakkinen 2025 | |
| set -e | |
| SOURCE="git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git" | |
| TEMPLATE_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/linux-pr" | |
| usage() { | |
| echo "Usage: $0 [-n|--dry-run] [-C <linux kernel tree>] [--postfix <postfix>] [--data-dir <data dir>] <template name> <version>" | |
| } | |
| git_kernel() { | |
| git -C "$kernel_tree" "$@" | |
| } | |
| render_template() { | |
| jq \ | |
| --rawfile template "$template" \ | |
| --arg tag "$tag" \ | |
| --arg version "$version" \ | |
| --arg pull_request "$pull_request" \ | |
| --arg sender "$sender" \ | |
| --arg sender_email "$sender_email" \ | |
| --arg timestamp "$timestamp" \ | |
| -rn ' | |
| $template | |
| | gsub("{{sender}}"; $sender) | |
| | gsub("{{sender_email}}"; $sender_email) | |
| | gsub("{{timestamp}}"; $timestamp) | |
| | gsub("{{tag}}"; $tag) | |
| | gsub("{{version}}"; $version) | |
| | sub("{{pull_request}}"; $pull_request) | |
| ' | |
| } | |
| kernel_tree=. | |
| dry_run= | |
| postfix= | |
| data_dir="$TEMPLATE_DIR" | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -n|--dry-run) | |
| dry_run=1 | |
| shift | |
| ;; | |
| -C) | |
| if [[ $# -lt 2 ]]; then | |
| usage >&2 | |
| exit 1 | |
| fi | |
| kernel_tree="$2" | |
| shift 2 | |
| ;; | |
| --postfix) | |
| if [[ $# -lt 2 || -z "$2" ]]; then | |
| usage >&2 | |
| exit 1 | |
| fi | |
| postfix="$2" | |
| shift 2 | |
| ;; | |
| --data-dir) | |
| if [[ $# -lt 2 || -z "$2" ]]; then | |
| usage >&2 | |
| exit 1 | |
| fi | |
| data_dir="$2" | |
| shift 2 | |
| ;; | |
| -h|--help) | |
| usage | |
| exit 0 | |
| ;; | |
| --) | |
| shift | |
| break | |
| ;; | |
| -*) | |
| echo "Unknown option: $1" >&2 | |
| usage >&2 | |
| exit 1 | |
| ;; | |
| *) | |
| break | |
| ;; | |
| esac | |
| done | |
| if [[ -z "$kernel_tree" || $# -ne 2 ]]; then | |
| usage >&2 | |
| exit 1 | |
| fi | |
| if ! git -C "$kernel_tree" rev-parse --show-toplevel >/dev/null 2>&1; then | |
| echo "\"$kernel_tree\" is not a git repository" >&2 | |
| exit 1 | |
| fi | |
| template_name="$1" | |
| version="$2" | |
| if [[ -z "$template_name" || "$template_name" == */* ]]; then | |
| echo "Invalid template name: \"$template_name\"" >&2 | |
| exit 1 | |
| fi | |
| template="$data_dir/$template_name.mbox.in" | |
| if [[ ! -f "$template" || ! -r "$template" ]]; then | |
| echo "Template \"$template_name\" not found or unreadable: $template" >&2 | |
| exit 1 | |
| fi | |
| tag="${template_name}-${version}" | |
| git_tag="${tag}${postfix:+-$postfix}" | |
| tag_ref="refs/tags/$git_tag" | |
| if git_kernel show-ref --verify --quiet "$tag_ref"; then | |
| echo "\"$git_tag\" pre-exists" | |
| exit 1 | |
| fi | |
| if git_kernel ls-remote --exit-code --refs --tags origin "$tag_ref" >/dev/null 2>&1; then | |
| echo "\"origin/$git_tag\" pre-exists" | |
| exit 1 | |
| fi | |
| sender_email="$(git_kernel config user.email)" | |
| sender="$(git_kernel config user.name) <$sender_email>" | |
| timestamp=$(date +"%a %b %e %H:%M:%S %Y") | |
| pull_request='{{pull_request}}' | |
| subject=$(render_template | jq -Rrs ' | |
| split("\n\n")[0] | |
| | split("\n")[] | |
| | select(startswith("Subject: ")) | |
| | ltrimstr("Subject: ") | |
| ') | |
| if [[ -z "$subject" ]] || grep -Eq '\{\{[^}]+\}\}' <<< "$subject"; then | |
| echo "\"$template\" has a missing or unresolved subject" >&2 | |
| exit 1 | |
| fi | |
| if [[ -n "$dry_run" ]]; then | |
| request_ref="HEAD:$tag_ref" | |
| printf "Dry run: using '%s' as request-pull end ref\n" "$request_ref" >&2 | |
| pull_request=$(git_kernel request-pull mainline/master "$SOURCE" "$request_ref" 2>/dev/null) || true | |
| if [[ -z "$pull_request" ]]; then | |
| git_kernel request-pull mainline/master "$SOURCE" "$request_ref" >/dev/null | |
| fi | |
| else | |
| request_ref="$git_tag" | |
| git_kernel tag -s --edit -m "$subject" -m "Signed-off-by: $sender" "$git_tag" | |
| git_kernel push origin "$git_tag" | |
| printf "Waiting for '%s'" "$git_tag" >&2 | |
| while ! git ls-remote --exit-code --refs --tags "$SOURCE" "$tag_ref" >/dev/null 2>&1; do | |
| printf "." >&2 | |
| sleep 1 | |
| done | |
| printf " found\n" >&2 | |
| pull_request=$(git_kernel request-pull mainline/master "$SOURCE" "$request_ref") | |
| fi | |
| output="git-pull-${tag}.mbox" | |
| tmp_output="$(mktemp "${output}.XXXXXX")" | |
| trap 'rm -f "$tmp_output"' EXIT | |
| render_template > "$tmp_output" | |
| if grep -Eq '\{\{[^}]+\}\}' "$tmp_output"; then | |
| echo "\"$template\" contains unresolved placeholders" >&2 | |
| exit 1 | |
| fi | |
| mv "$tmp_output" "$output" | |
| trap - EXIT |