Вопрос или проблема
Итак, я знаю, как получить комментарии и отзывы на Pull Request, а также комментарии к отзывам с помощью GitHub API – это все задокументировано.
Что НЕ задокументировано, так это то, как я могу получить выделение, связанное с комментарием, например:
Я знаю, как получить текст комментария и весь дифф-хунк (используя API комментариев PR), но не имею представления, как получить выделение в дифф-хунке, связанное с комментарием.
Например, для изображения ниже я получаю следующий загрузочный пакет от GitHub Rest Api:
Единственная отдаленно релевантная информация в этом контексте:
"start_line": null,
"original_start_line": null,
"start_side": null,
"line": 41,
"original_line": 41,
"side": "LEFT",
"original_position": 40,
"position": 40,
"subject_type": "line"
Но что это значит? Выделение охватывает строки 38-41, но возвращаемый JSON об этом не сообщает.
Итак, как мы можем это получить?
Страница документации содержит схему ответа: Список комментариев к отзывам на Pull Request (справа от кнопки примера ответа). Схема содержит описание всех полей.
"start_line"
– Первая строка диапазона для многократного комментария.
"original_start_line"
– Первая строка диапазона для многократного комментария.
"start_side"
– Сторона первой строки диапазона для многократного комментария.
"line"
– Строка блоба, к которой относится комментарий. Последняя строка диапазона для многократного комментария.
"original_line"
– Строка блоба, к которой относится комментарий. Последняя строка диапазона для многократного комментария.
"side"
– Сторона диффа, к которой относится комментарий. Сторона последней строки диапазона для многократного комментария.
"original_position"
– Индекс оригинальной строки в диффе, к которому относится комментарий. Это поле закрывается; используйте original_line вместо этого.
"position"
– Индекс строки в диффе, к которому относится комментарий. Это поле закрывается; используйте line вместо этого.
"subject_type"
– Уровень, на который направлен комментарий, может быть строкой диффа или файлом.
Ответ или решение
Да, использование GitHub API для получения текста, выделенного в Diff-ханке (раздел изменения) комментария Pull Request, представляет собой интересную задачу. Несмотря на то, что API предоставляет множество информации о комментариях, таких как текст самого комментария и ассоциированные строки, точное извлечение выделенного текста из hunk-а не так явно документировано. В этом ответе мы рассмотрим, как можно добиться нужного результата.
Основные шаги для извлечения выделенного текста
-
Получение комментариев Pull Request: Первым шагом является использование API для получения комментариев к Pull Request. Вы можете использовать следующий эндпоинт:
GET /repos/{owner}/{repo}/pulls/{pull_number}/comments
Этот запрос вернет список комментариев с информацией о строках, на которых они расположены.
-
Анализ структуры комментария: Каждое комментарий будет иметь несколько полей, среди которых важные для нас:
start_line
: первая строка диапазона для многострочного комментария.line
: последняя строка диапазона для многострочного комментария.side
: сторона (LEFT или RIGHT), к которой относится комментарий.
-
Определение диапазона строк: Важно понимать диапазон строк, к которому относится ваш комментарий. Если
start_line
иline
не равны, вы имеет дело с многострочным комментарием.- Если
start_line
равноnull
, это значит, что комментарий относится к одной строке. - Если оба поля имеют значения, диапазон строки будет от
start_line
доline
.
- Если
-
Получение полного diffs: Чтобы извлечь конкретные строки текста из выбранного встречного hunk-а, вам нужно будет получить полный diff этого Pull Request. Это можно сделать с помощью следующего эндпоинта:
GET /repos/{owner}/{repo}/pulls/{pull_number}/files
Этот запрос вернет список файлов с их изменениями, где можно увидеть полный контекст файла и строки, к которым относится ваш комментарий.
-
Извлечение выделенного текста: Теперь, когда у вас есть полное представление об изменениях в файле, вы можете:
- Найдите нужный файл по имени.
- Используя
start_line
иline
, найдите соответствующий диапазон строк и извлеките текст.
Пример на практике
Допустим, мы имеем комментарий с start_line: 38
и line: 41
. Это означает, что выделенный текст находится в строках 38, 39, 40 и 41. После получения полного diff для файла, вы можете взять эти строки и просмотреть их содержимое.
import requests
# Замените переменные на свои значения
owner = 'владелец'
repo = 'репозиторий'
pull_number = 123
comment_id = 'идентификатор комментария'
# Получение комментария PR
comment_url = f'https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}'
response = requests.get(comment_url)
comment_data = response.json()
# Извлечение информации о строках
start_line = comment_data.get('start_line', 0)
line = comment_data.get('line', 0)
# Получение файлов из PR
files_url = f'https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/files'
files_response = requests.get(files_url)
files_data = files_response.json()
# Поиск нужного файла и извлечение выделенного текста
for file in files_data:
if file['filename'] == 'имя_вашего_файла':
changes = file['patch'].splitlines()
selected_text = changes[start_line-1:line] # start_line-1 поскольку индексы начинаются с 0
print('Выделенный текст:', "\n".join(selected_text))
Заключение
В данном ответе мы рассмотрели, как получать текст, выделенный в Diff-ханке комментария Pull Request с помощью GitHub API. Основной процесс включает получение комментариев, анализ структуры, получение полного diff файла и извлечение нужных строк. Несмотря на то что данный процесс требует нескольких шагов, он полностью реализуем с помощью доступных инструментов API. Оптимизированный подход обеспечит вас всей необходимой информацией для работы с комментариями Pull Request на GitHub.