今回のコードでできること
GitHubのPull RequestのURL(Load diffがあってもOK)を今回のコードを実行して張り付けると
動機
- GitHubAPIを使うことでLoad diffを展開した状態のdiffが取れるのでGitHubAPIのレスポンスに対応した整形コードを作成
- URLを指定するだけでdiffを取得したい。前回よりも手順を省略したい
使い方
- Pull Request画面でURL(とにかくowner, repo, PR番号が取れればOK)を取得する
- "GitDiffURLToMd.py"ファイルを作成してエディタでソースコードを張り付ける
- "GitDiffURLToMd.py"をクリックして、指示に従ってURLを指定する
- "diff.md"にテキスト化した結果が入っているので、生成AIへの質問等で活用する
ソースコード(Pythonファイル)
import requests
import re
# GitHub APIからプルリクエストのdiffを取得する
def getDiffRes(url):
# URLからowner, repo, PR番号を抽出
m = re.match(r"https://github.com/([^/]+)/([^/]+)/pull/(\d+)", url)
if not m:
print("無効なURLです")
exit()
owner, repo, pr_number = m.groups()
api_url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}"
headers = {"Accept": "application/vnd.github.v3.diff"}
try:
res = requests.get(api_url, headers=headers)
res.raise_for_status()
return res.text
except requests.exceptions.RequestException as e:
print(f"Error fetching diff: {e}")
exit()
def getCleanedDiffMd(diff_text):
# ファイルごとにdiffを分割
parts = diff_text.split("diff --git ")
formatted = []
for part in parts:
if not part.strip():
continue
lines = part.strip().splitlines()
# diff --git a/xxx b/xxx からファイル名を取得
first_line = lines[0] if lines else ""
# b/以下のパスを抽出(通常は2つ目のファイルパス)
if first_line.startswith("a/") or first_line.startswith("b/"):
# splitすると ['a/filepath', 'b/filepath'] になる
file_paths = first_line.split()
if len(file_paths) == 2:
filename = file_paths[1][2:] # b/ を除去
else:
filename = "unknown_file"
else:
filename = "unknown_file"
# "@@"で始まる行を探す
at_at_index = -1
for i, line in enumerate(lines):
if line.startswith('@@'):
at_at_index = i
break
# "@@"行が見つかった場合、その行から最後までを取得
if at_at_index != -1:
cleaned_diff_lines = lines[at_at_index:]
cleaned_diff = "\n".join(cleaned_diff_lines)
else:
cleaned_diff = "\n".join(lines)
# Markdown形式に整形(ファイル名も追加)
formatted.append(f"## {filename}\n```diff\n{cleaned_diff}\n```")
# 全ての整形済みdiffを結合
md_diff = "\n\n".join(formatted)
return md_diff
def main():
url = input("GitHub Pull Request のURLを入力してください: ").strip()
# URLからdiff取得
diff_text = getDiffRes(url)
# diffを整形
md_diff = getCleanedDiffMd(diff_text)
# Markdownファイルとして保存
output_filename = "diff.md"
try:
with open(output_filename, "w", encoding="utf-8") as f:
f.write(md_diff)
print(f"PR diff has been saved to {output_filename}")
except IOError as e:
print(f"Error saving file: {e}")
# 入力待ち
input("続行するには何かキーを押してください...")
if __name__ == "__main__":
main()