pygitcode 0.1.5__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {pygitcode-0.1.5/src/pygitcode.egg-info → pygitcode-0.1.6}/PKG-INFO +1 -1
  2. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/__init__.py +1 -1
  3. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/commands/pr.py +52 -19
  4. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/compat/entries.py +1 -0
  5. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/services/pulls.py +5 -0
  6. {pygitcode-0.1.5 → pygitcode-0.1.6/src/pygitcode.egg-info}/PKG-INFO +1 -1
  7. {pygitcode-0.1.5 → pygitcode-0.1.6}/LICENSE +0 -0
  8. {pygitcode-0.1.5 → pygitcode-0.1.6}/README.md +0 -0
  9. {pygitcode-0.1.5 → pygitcode-0.1.6}/pyproject.toml +0 -0
  10. {pygitcode-0.1.5 → pygitcode-0.1.6}/setup.cfg +0 -0
  11. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/adapters/__init__.py +0 -0
  12. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/adapters/base.py +0 -0
  13. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/adapters/capabilities.py +0 -0
  14. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/adapters/issues.py +0 -0
  15. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/adapters/pulls.py +0 -0
  16. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/audit.py +0 -0
  17. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/cli.py +0 -0
  18. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/cli_compat.py +0 -0
  19. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/client.py +0 -0
  20. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/commands/__init__.py +0 -0
  21. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/commands/auth.py +0 -0
  22. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/commands/compat.py +0 -0
  23. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/commands/issue.py +0 -0
  24. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/commands/setup.py +0 -0
  25. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/compat/__init__.py +0 -0
  26. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/compat/_types.py +0 -0
  27. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/compat/registry.py +0 -0
  28. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/config.py +0 -0
  29. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/context.py +0 -0
  30. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/errors.py +0 -0
  31. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/formatters.py +0 -0
  32. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/gh_proxy.py +0 -0
  33. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/helptext.py +0 -0
  34. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/repo.py +0 -0
  35. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/services/__init__.py +0 -0
  36. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/services/issues.py +0 -0
  37. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/services/users.py +0 -0
  38. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/gitcode_cli/utils.py +0 -0
  39. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/pygitcode.egg-info/SOURCES.txt +0 -0
  40. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/pygitcode.egg-info/dependency_links.txt +0 -0
  41. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/pygitcode.egg-info/entry_points.txt +0 -0
  42. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/pygitcode.egg-info/requires.txt +0 -0
  43. {pygitcode-0.1.5 → pygitcode-0.1.6}/src/pygitcode.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygitcode
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: A CLI tool for GitCode (api.gitcode.com), modeled after GitHub CLI.
5
5
  Author-email: codeasier <825770651@qq.com>
6
6
  License-Expression: MIT
@@ -1,3 +1,3 @@
1
1
  __all__ = ["__version__"]
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.1.6"
@@ -155,27 +155,26 @@ def _extract_search_filters(
155
155
 
156
156
 
157
157
  def _advance_diff_line(
158
- raw_line: str, old_line: int, new_line: int, target_line: int, target_side: str, position: int
159
- ) -> tuple[int | None, int, int]:
158
+ raw_line: str, old_line: int, new_line: int, target_line: int, target_side: str
159
+ ) -> tuple[bool, int, int]:
160
160
  prefix = raw_line[:1]
161
161
  if prefix == "-":
162
- return (position if target_side == "LEFT" and old_line == target_line else None), old_line + 1, new_line
162
+ return target_side == "LEFT" and old_line == target_line, old_line + 1, new_line
163
163
  if prefix == "+":
164
- return (position if target_side == "RIGHT" and new_line == target_line else None), old_line, new_line + 1
164
+ return target_side == "RIGHT" and new_line == target_line, old_line, new_line + 1
165
165
  matched = (target_side == "LEFT" and old_line == target_line) or (
166
166
  target_side == "RIGHT" and new_line == target_line
167
167
  )
168
- return (position if matched else None), old_line + 1, new_line + 1
168
+ return matched, old_line + 1, new_line + 1
169
169
 
170
170
 
171
- def _diff_position_for_line(diff_text: str, path: str, line: int, side: str) -> int:
171
+ def _validate_diff_line(diff_text: str, path: str, line: int, side: str) -> None:
172
172
  target_side = side.upper()
173
173
  if target_side not in {"LEFT", "RIGHT"}:
174
174
  raise click.UsageError("--side must be LEFT or RIGHT")
175
175
 
176
176
  old_line = None
177
177
  new_line = None
178
- position = 0
179
178
  in_target_file = False
180
179
  saw_target_file = False
181
180
 
@@ -183,9 +182,9 @@ def _diff_position_for_line(diff_text: str, path: str, line: int, side: str) ->
183
182
  if raw_line.startswith("diff --git "):
184
183
  old_line = None
185
184
  new_line = None
186
- position = 0
187
185
  in_target_file = False
188
186
  continue
187
+ # TODO: Handle Git-quoted paths and deleted files whose +++ header is /dev/null.
189
188
  if raw_line.startswith("+++ b/"):
190
189
  in_target_file = raw_line[6:] == path
191
190
  saw_target_file = saw_target_file or in_target_file
@@ -200,12 +199,9 @@ def _diff_position_for_line(diff_text: str, path: str, line: int, side: str) ->
200
199
  if old_line is None or new_line is None or raw_line.startswith("\\"):
201
200
  continue
202
201
 
203
- position += 1
204
- matched_position, old_line, new_line = _advance_diff_line(
205
- raw_line, old_line, new_line, line, target_side, position
206
- )
207
- if matched_position is not None:
208
- return matched_position
202
+ matched, old_line, new_line = _advance_diff_line(raw_line, old_line, new_line, line, target_side)
203
+ if matched:
204
+ return
209
205
 
210
206
  if not saw_target_file:
211
207
  raise click.ClickException(f"Path '{path}' was not found in the pull request diff.")
@@ -220,7 +216,9 @@ def _resolve_comment_position_from_line(
220
216
  if path is None:
221
217
  raise click.UsageError("--path is required when using --line")
222
218
  diff_text = service.diff(owner, repo, number)
223
- return _diff_position_for_line(diff_text, path, line, side)
219
+ _validate_diff_line(diff_text, path, line, side)
220
+ # GitCode position is an absolute file line, not an ordinal within the diff.
221
+ return line
224
222
 
225
223
 
226
224
  @click.group("pr", cls=GCSectionGroup, help="Work with GitCode pull requests.")
@@ -298,10 +296,19 @@ def pr_merge(
298
296
  @click.option("--edit-last", is_flag=True)
299
297
  @click.option("-e", "--editor", is_flag=True)
300
298
  @click.option("-w", "--web", is_flag=True, help="Open the pull request in the web browser.")
299
+ @click.option(
300
+ "--discussion-id",
301
+ help="Reply to an existing discussion (gc extension). Find discussion_id with pr view --json comments.",
302
+ )
301
303
  @click.option("--path")
302
- @click.option("--position", type=int)
303
- @click.option("--line", type=int)
304
- @click.option("--side", default="RIGHT", show_default=True)
304
+ @click.option("--position", type=int, help="Pass an absolute file line number directly to GitCode.")
305
+ @click.option("--line", type=int, help="Absolute file line number; validated against the pull request diff.")
306
+ @click.option(
307
+ "--side",
308
+ default="RIGHT",
309
+ show_default=True,
310
+ help="Side used only to validate --line: LEFT or RIGHT. GitCode receives no side; LEFT anchoring is best-effort.",
311
+ )
305
312
  @click.option("--commit-id")
306
313
  @click.option("--commit", "commit_id")
307
314
  @click.option("--yes", is_flag=True)
@@ -317,6 +324,7 @@ def pr_comment(
317
324
  edit_last: bool,
318
325
  editor: bool,
319
326
  web: bool,
327
+ discussion_id: str | None,
320
328
  path: str | None,
321
329
  position: int | None,
322
330
  line: int | None,
@@ -332,6 +340,23 @@ def pr_comment(
332
340
  _pending_gh_compat("pr comment --edit-last")
333
341
  if yes:
334
342
  _pending_gh_compat("pr comment --yes")
343
+ if discussion_id is not None:
344
+ discussion_id = discussion_id.strip()
345
+ if not discussion_id:
346
+ raise click.UsageError("--discussion-id must not be empty")
347
+ if discussion_id in {".", ".."} or any(char in discussion_id for char in "/\\?#%"):
348
+ raise click.UsageError("--discussion-id must be a single path segment without URL-reserved characters")
349
+ if (
350
+ path is not None
351
+ or position is not None
352
+ or line is not None
353
+ or ctx.get_parameter_source("side") != click.core.ParameterSource.DEFAULT
354
+ or commit_id is not None
355
+ or web
356
+ ):
357
+ raise click.UsageError(
358
+ "--discussion-id cannot be used with --path, --position, --line, --side, --commit-id/--commit, or --web"
359
+ )
335
360
  if commit_id:
336
361
  raise click.ClickException("GitCode PR comments do not support selecting a commit for line comments.")
337
362
  if line is not None and position is not None:
@@ -348,7 +373,15 @@ def pr_comment(
348
373
  return
349
374
  body = get_body_from_options(body=body, body_file=body_file, editor=editor)
350
375
  body = prompt_if_missing(body, "Body")
351
- resolved_position = position or _resolve_comment_position_from_line(service, owner, repo, number, path, line, side)
376
+ if discussion_id is not None:
377
+ item = service.reply(owner, repo, number, discussion_id, body=body) or {}
378
+ safe_echo(str(item.get("noteId") or "Reply posted."))
379
+ return
380
+ resolved_position = (
381
+ position
382
+ if position is not None
383
+ else _resolve_comment_position_from_line(service, owner, repo, number, path, line, side)
384
+ )
352
385
  item = service.comment(owner, repo, number, body=body, path=path, position=resolved_position)
353
386
  safe_echo(str(item["id"]))
354
387
 
@@ -341,6 +341,7 @@ ENTRIES: list[CompatEntry] = [
341
341
  _e("pr comment", "-e/--editor", CompatStatus.IMPLEMENTED),
342
342
  _e("pr comment", "-w/--web", CompatStatus.IMPLEMENTED),
343
343
  _e("pr comment", "--path", CompatStatus.IMPLEMENTED, "gc extension; not in gh", gc_extension=True),
344
+ _e("pr comment", "--discussion-id", CompatStatus.IMPLEMENTED, "gc extension; not in gh", gc_extension=True),
344
345
  _e("pr comment", "--position", CompatStatus.IMPLEMENTED, "gc extension; not in gh", gc_extension=True),
345
346
  _e("pr comment", "--line", CompatStatus.IMPLEMENTED, "gc extension; not in gh", gc_extension=True),
346
347
  _e("pr comment", "--side", CompatStatus.IMPLEMENTED, "gc extension; not in gh", gc_extension=True),
@@ -70,6 +70,11 @@ class PullRequestService:
70
70
  filtered_payload = {k: v for k, v in payload.items() if v is not None}
71
71
  return self.client.post(f"/repos/{owner}/{repo}/pulls/{number}/review", json=filtered_payload)
72
72
 
73
+ def reply(self, owner: str, repo: str, number: int, discussion_id: str, body: str) -> Any | None:
74
+ return self.client.post(
75
+ f"/repos/{owner}/{repo}/pulls/{number}/discussions/{discussion_id}/comments", json={"body": body}
76
+ )
77
+
73
78
  def list_comments(self, owner: str, repo: str, number: int) -> Any | None:
74
79
  return self._paginate(f"/repos/{owner}/{repo}/pulls/{number}/comments")
75
80
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygitcode
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: A CLI tool for GitCode (api.gitcode.com), modeled after GitHub CLI.
5
5
  Author-email: codeasier <825770651@qq.com>
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes
File without changes