Skip to content

Instantly share code, notes, and snippets.

@shyazusa
Last active April 9, 2025 00:19
Show Gist options
  • Save shyazusa/960b21e21170aef261e2fc240f3720bb to your computer and use it in GitHub Desktop.
Save shyazusa/960b21e21170aef261e2fc240f3720bb to your computer and use it in GitHub Desktop.
メインブランチと開発ブランチとGitHubアカウント名を入れると、メインブランチと開発ブランチの差分にある指定GitHubアカウント名のPRを出すヤツ Made by Google Gemini 2.5 Pro (experimental)
#!/bin/bash
# --- デフォルト値 ---
MAIN_BRANCH=""
DEV_BRANCH=""
AUTHOR=""
# --- ヘルプメッセージ表示関数 ---
usage() {
echo "使用方法: $0 --main-branch <ブランチ名> --dev-branch <ブランチ名> --author <GitHubユーザー名>"
echo ""
echo "説明:"
echo " カレントディレクトリのGitリポジトリにおいて、指定された2つのブランチ間の差分に含まれる"
echo " コミットに関連し、かつ指定されたユーザーが作成したPull Requestを検索します。"
echo " 比較はリモート追跡ブランチ (origin/...) を基準に行います。"
echo ""
echo "オプション:"
echo " -m, --main-branch <ブランチ名> 比較元のメインブランチ名 (例: dev/beta) [必須]"
echo " -d, --dev-branch <ブランチ名> 比較先の開発ブランチ名 (例: release/online-moy) [必須]"
echo " -a, --author <ユーザー名> 検索対象のPR作成者GitHubアカウント名 (例: shyazusa) [必須]"
echo " -h, --help このヘルプメッセージを表示"
echo ""
echo "前提条件:"
echo " - git, gh (GitHub CLI), jq コマンドがインストールされていること。"
echo " - gh auth login でGitHubにログイン済みであること。"
echo " - スクリプトを実行するディレクトリがGitリポジトリのルートであること。"
echo " - (推奨) gnu-getopt がインストールされていること (brew install gnu-getopt)。"
exit 1
}
# --- getopt のパスを探す ---
GETOPT_PATH=""
# brewでインストールされたgnu-getoptのパスを優先的に探す
# brew --prefix コマンドが存在するか確認
if command -v brew &> /dev/null; then
GNU_GETOPT_PREFIX=$(brew --prefix gnu-getopt 2>/dev/null)
if [ -n "$GNU_GETOPT_PREFIX" ] && [ -x "$GNU_GETOPT_PREFIX/bin/getopt" ]; then
GETOPT_PATH="$GNU_GETOPT_PREFIX/bin/getopt"
echo "情報: brew --prefix を使用してgetoptを見つけました: $GETOPT_PATH" >&2
fi
fi
# もしまだ見つからなければ、PATHからgnu-getoptを探す
if [ -z "$GETOPT_PATH" ] && command -v gnu-getopt &> /dev/null; then
GETOPT_PATH=$(command -v gnu-getopt)
echo "情報: PATHからgnu-getoptを使用します: $GETOPT_PATH" >&2
fi
# それでも見つからなければ、PATHからgetoptを探す
if [ -z "$GETOPT_PATH" ] && command -v getopt &> /dev/null; then
GETOPT_PATH_TEMP=$(command -v getopt)
# それがGNU版かテストする
if "$GETOPT_PATH_TEMP" --test > /dev/null 2>&1; then
if [[ $? -eq 4 ]]; then # GNU getopt は --test で終了コード 4 を返す
GETOPT_PATH=$GETOPT_PATH_TEMP
echo "情報: PATHからGNU版と思われるgetoptを使用します: $GETOPT_PATH" >&2
else
echo "警告: PATHで見つかったgetoptはGNU版ではない可能性があります。スクリプトが正しく動作しないかもしれません: $GETOPT_PATH_TEMP" >&2
# ここでエラーにするか、そのまま使うか選択できます
# exit 1 # エラーにする場合
# GETOPT_PATH=$GETOPT_PATH_TEMP # そのまま使う場合
fi
else
echo "警告: PATHで見つかったgetoptのバージョンを確認できませんでした: $GETOPT_PATH_TEMP" >&2
# GETOPT_PATH=$GETOPT_PATH_TEMP # そのまま使う場合
fi
fi
# 最終的にgetoptが見つからなかった場合
if [ -z "$GETOPT_PATH" ]; then
echo "エラー: GNU getoptコマンドが見つかりません。" >&2
echo "1. 'brew install gnu-getopt' を実行してください。" >&2
echo "2. 'brew info gnu-getopt' の指示に従ってPATHを設定し、シェルを再起動するか 'source ~/.zshrc' を実行してください。" >&2
echo "3. 上記を実行しても解決しない場合、スクリプト内のgetoptパス検出ロジックに問題がある可能性があります。" >&2
exit 1
fi
# --- コマンドラインオプションの解析 ---
# ここで $GETOPT_PATH を使用する
# -o: 短いオプション, --long: 長いオプション, ':' は値が必要
TEMP=$("$GETOPT_PATH" -o m:d:a:h --long main-branch:,dev-branch:,author:,help -n "$0" -- "$@")
if [ $? != 0 ]; then echo "オプション解析エラー。 --help を確認してください。" >&2; exit 1; fi
eval set -- "$TEMP"
unset TEMP
while true; do
case "$1" in
-m|--main-branch)
MAIN_BRANCH="$2"
shift 2
;;
-d|--dev-branch)
DEV_BRANCH="$2"
shift 2
;;
-a|--author)
AUTHOR="$2"
shift 2
;;
-h|--help)
usage
;;
--)
shift
break
;;
*)
echo "内部エラー!" >&2
exit 1
;;
esac
done
# --- 必須オプションのチェック ---
if [ -z "$MAIN_BRANCH" ] || [ -z "$DEV_BRANCH" ] || [ -z "$AUTHOR" ]; then
echo "エラー: --main-branch, --dev-branch, --author は必須オプションです。" >&2
usage
fi
# --- 前提コマンドのチェック ---
if ! command -v git &> /dev/null; then
echo "エラー: git コマンドが見つかりません。" >&2
exit 1
fi
if ! command -v gh &> /dev/null; then
echo "エラー: gh (GitHub CLI) コマンドが見つかりません。インストールして gh auth login を実行してください。" >&2
exit 1
fi
if ! command -v jq &> /dev/null; then
echo "エラー: jq コマンドが見つかりません。brew install jq などでインストールしてください。" >&2
exit 1
fi
# --- カレントディレクトリがGitリポジトリかチェック ---
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo "エラー: カレントディレクトリ ($(pwd)) はGitリポジトリではありません。" >&2
echo "対象リポジトリのルートディレクトリでスクリプトを実行してください。" >&2
exit 1
fi
# --- カレントディレクトリ情報 ---
CURRENT_DIR=$(pwd)
REPO_NAME=$(basename "$CURRENT_DIR")
# --- PR検索関数 ---
find_prs() {
local repo_name=$1
local main_branch=$2
local dev_branch=$3
local target_user=$4
echo "--- リポジトリ: $repo_name (カレントディレクトリ) ---"
echo "比較ブランチ: origin/$main_branch .. origin/$dev_branch"
echo "検索ユーザー: $target_user"
echo ""
# ローカルのリモート追跡ブランチを最新化 (推奨)
echo "リモートブランチ情報を更新中 (git fetch origin)..."
if ! git fetch origin --quiet; then # --quiet を追加して成功時の出力を抑制
echo "警告: git fetch origin に失敗しました。リモート接続を確認してください。処理を続行します..." >&2
# 続行を試みる
else
echo "リモートブランチ情報を更新しました。"
fi
echo ""
# リモート追跡ブランチが存在するか確認
if ! git rev-parse --verify "origin/$main_branch" > /dev/null 2>&1; then
echo "エラー: リモート追跡ブランチ 'origin/$main_branch' が見つかりません。" >&2
echo "'git branch -r' で存在を確認し、必要であれば 'git fetch origin' を実行してください。" >&2
exit 1
fi
if ! git rev-parse --verify "origin/$dev_branch" > /dev/null 2>&1; then
echo "エラー: リモート追跡ブランチ 'origin/$dev_branch' が見つかりません。" >&2
echo "'git branch -r' で存在を確認し、必要であれば 'git fetch origin' を実行してください。" >&2
exit 1
fi
echo "指定されたブランチ間の差分に含まれる $target_user 作成のPRを検索中..."
# git logで差分のあるコミットを取得し、コミットメッセージからPR番号を抽出
local pr_numbers
pr_numbers=$(git log "origin/$main_branch..origin/$dev_branch" --pretty=format:"%s %b" | grep -Eo '\(#([0-9]+)\)|Merge pull request #([0-9]+)' | grep -Eo '[0-9]+' | sort -u)
if [ -z "$pr_numbers" ]; then
echo "関連する可能性のあるPR番号がコミットログから見つかりませんでした。"
return 0
fi
echo "関連する可能性のあるPR番号 (重複除去済み):"
echo "$pr_numbers"
echo ""
echo "$target_user が作成したPR:"
local found_count=0
for pr_num in $pr_numbers; do
local pr_info
# ghコマンドでPR情報を取得 (--json に url を追加)
pr_info=$(gh pr view "$pr_num" --json author,number,title,url --jq '. | select(.author.login=="'$target_user'") | "- (#\(.number)) \(.title)\n \u001b[34m\(.url)\u001b[0m"' 2>/dev/null)
# ↑ jqの出力フォーマットを変更し、URLを次の行に青色で表示 (ターミナルが色表示対応の場合)
# 単純に同じ行に表示する場合は: | "- (#\(.number)) \(.title) - \(.url)"'
if [ $? -eq 0 ] && [ -n "$pr_info" ]; then
echo -e "$pr_info" # -e オプションでエスケープシーケンス(\n や \u001b)を解釈させる
found_count=$((found_count + 1))
fi
done
if [ "$found_count" -eq 0 ]; then
echo "$target_user が作成したPRは見つかりませんでした。"
fi
return 0
}
# --- メイン処理 ---
echo "カレントディレクトリのGitリポジトリでPRを検索します..."
echo "=================================================="
echo ""
find_prs "$REPO_NAME" "$MAIN_BRANCH" "$DEV_BRANCH" "$AUTHOR"
echo ""
echo "=================================================="
echo "検索完了。"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment