Last active
April 9, 2025 00:19
-
-
Save shyazusa/960b21e21170aef261e2fc240f3720bb to your computer and use it in GitHub Desktop.
メインブランチと開発ブランチとGitHubアカウント名を入れると、メインブランチと開発ブランチの差分にある指定GitHubアカウント名のPRを出すヤツ Made by Google Gemini 2.5 Pro (experimental)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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