Skip to content

Commit 66eeb20

Browse files
author
Evans Castonguay
committed
fix: handle GitLab single-line diff notes in /ask_line
1 parent d9d4dc8 commit 66eeb20

File tree

2 files changed

+97
-10
lines changed

2 files changed

+97
-10
lines changed

pr_agent/servers/gitlab_webhook.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -277,17 +277,33 @@ async def inner(data: dict):
277277

278278
def handle_ask_line(body, data):
279279
try:
280-
line_range_ = data['object_attributes']['position']['line_range']
281-
# if line_range_['start']['type'] == 'new':
282-
start_line = line_range_['start']['new_line']
283-
end_line = line_range_['end']['new_line']
284-
# else:
285-
# start_line = line_range_['start']['old_line']
286-
# end_line = line_range_['end']['old_line']
280+
position = data.get('object_attributes', {}).get('position') or {}
281+
line_range_ = position.get('line_range')
282+
283+
if line_range_:
284+
range_type = line_range_.get('start', {}).get('type')
285+
side = 'RIGHT' if range_type == 'new' else 'LEFT'
286+
if range_type == 'new':
287+
start_line = line_range_.get('start', {}).get('new_line')
288+
end_line = line_range_.get('end', {}).get('new_line')
289+
path = position.get('new_path')
290+
else:
291+
start_line = line_range_.get('start', {}).get('old_line')
292+
end_line = line_range_.get('end', {}).get('old_line')
293+
path = position.get('old_path')
294+
else:
295+
start_line = position.get('new_line') or position.get('old_line')
296+
end_line = position.get('new_line') or position.get('old_line')
297+
side = 'RIGHT' if position.get('new_line') is not None else 'LEFT'
298+
path = position.get('new_path') or position.get('old_path')
299+
300+
if start_line is None or end_line is None:
301+
raise ValueError("Missing line numbers in diff position")
302+
if not path:
303+
raise ValueError("Missing file path in diff position")
304+
287305
question = body.replace('/ask', '').strip()
288-
path = data['object_attributes']['position']['new_path']
289-
side = 'RIGHT' # if line_range_['start']['type'] == 'new' else 'LEFT'
290-
comment_id = data['object_attributes']["discussion_id"]
306+
comment_id = data.get('object_attributes', {}).get("discussion_id", "")
291307
get_logger().info("Handling line ")
292308
body = f"/ask_line --line_start={start_line} --line_end={end_line} --side={side} --file_name={path} --comment_id={comment_id} {question}"
293309
except Exception as e:
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import importlib
2+
import os
3+
4+
import pytest
5+
6+
7+
@pytest.fixture(scope="module", autouse=True)
8+
def _set_gitlab_url():
9+
os.environ.setdefault("GITLAB__URL", "https://gitlab.example.com")
10+
yield
11+
12+
13+
def _load_module():
14+
import pr_agent.servers.gitlab_webhook as gitlab_webhook
15+
16+
return importlib.reload(gitlab_webhook)
17+
18+
19+
def _base_payload(position):
20+
return {
21+
"object_attributes": {
22+
"position": position,
23+
"discussion_id": "discussion-1",
24+
}
25+
}
26+
27+
28+
@pytest.mark.parametrize(
29+
"line_range_type,expected_side,start_key,end_key,path_key",
30+
[
31+
("new", "RIGHT", "new_line", "new_line", "new_path"),
32+
("old", "LEFT", "old_line", "old_line", "old_path"),
33+
],
34+
)
35+
def test_handle_ask_line_line_range(line_range_type, expected_side, start_key, end_key, path_key):
36+
module = _load_module()
37+
position = {
38+
"line_range": {
39+
"start": {start_key: 10, "type": line_range_type},
40+
"end": {end_key: 12, "type": line_range_type},
41+
},
42+
"new_path": "src/new.py",
43+
"old_path": "src/old.py",
44+
}
45+
payload = _base_payload(position)
46+
47+
result = module.handle_ask_line("/ask what is this?", payload)
48+
49+
assert f"--line_start=10" in result
50+
assert f"--line_end=12" in result
51+
assert f"--side={expected_side}" in result
52+
assert f"--file_name={position[path_key]}" in result
53+
54+
55+
@pytest.mark.parametrize(
56+
"position,expected_side,expected_path",
57+
[
58+
({"new_line": 5, "new_path": "src/new.py"}, "RIGHT", "src/new.py"),
59+
({"old_line": 7, "old_path": "src/old.py"}, "LEFT", "src/old.py"),
60+
],
61+
)
62+
def test_handle_ask_line_single_line(position, expected_side, expected_path):
63+
module = _load_module()
64+
payload = _base_payload(position)
65+
66+
result = module.handle_ask_line("/ask explain", payload)
67+
68+
assert "--line_start" in result
69+
assert "--line_end" in result
70+
assert f"--side={expected_side}" in result
71+
assert f"--file_name={expected_path}" in result

0 commit comments

Comments
 (0)