python-gitea 0.11.7__tar.gz → 0.12.1__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 (424) hide show
  1. {python_gitea-0.11.7 → python_gitea-0.12.1}/.pre-commit-config.yaml +1 -1
  2. {python_gitea-0.11.7 → python_gitea-0.12.1}/PKG-INFO +1 -1
  3. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/dev/architecture.md +3 -2
  4. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/user-guide/cli.md +45 -0
  5. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/user-guide/python-api.md +2 -2
  6. {python_gitea-0.11.7 → python_gitea-0.12.1}/pyproject.toml +1 -1
  7. python_gitea-0.12.1/src/gitea/cli/issue/label/__init__.py +1 -0
  8. python_gitea-0.12.1/src/gitea/cli/issue/label/add.py +97 -0
  9. python_gitea-0.12.1/src/gitea/cli/issue/label/clear.py +94 -0
  10. python_gitea-0.12.1/src/gitea/cli/issue/label/common.py +267 -0
  11. python_gitea-0.12.1/src/gitea/cli/issue/label/list.py +87 -0
  12. python_gitea-0.12.1/src/gitea/cli/issue/label/main.py +29 -0
  13. python_gitea-0.12.1/src/gitea/cli/issue/label/remove.py +99 -0
  14. python_gitea-0.12.1/src/gitea/cli/issue/label/set.py +98 -0
  15. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/main.py +2 -0
  16. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/issue/async_issue.py +248 -0
  17. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/issue/base.py +57 -0
  18. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/issue/issue.py +242 -0
  19. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/label/async_label.py +57 -0
  20. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/label/base.py +39 -0
  21. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/label/label.py +57 -0
  22. python_gitea-0.12.1/tests/cli/issue/label/__init__.py +1 -0
  23. python_gitea-0.12.1/tests/cli/issue/label/test_cli_issue_label.py +523 -0
  24. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/test_cli_contract.py +12 -0
  25. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/test_cli_main.py +45 -0
  26. python_gitea-0.12.1/tests/issue/test_issue_labels.py +118 -0
  27. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/label/test_label_async_label.py +13 -0
  28. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/label/test_label_base.py +12 -0
  29. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/label/test_label_label.py +12 -0
  30. {python_gitea-0.11.7 → python_gitea-0.12.1}/uv.lock +1 -1
  31. {python_gitea-0.11.7 → python_gitea-0.12.1}/.coderabbit.yaml +0 -0
  32. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  33. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  34. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
  35. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/pull_request_template.md +0 -0
  36. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/ci.yml +0 -0
  37. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/codeql.yml +0 -0
  38. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/documentation.yml +0 -0
  39. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/draft_release.yml +0 -0
  40. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/publish.yml +0 -0
  41. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/publish_testpypi.yml +0 -0
  42. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/release.yml +0 -0
  43. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/scheduled_release.yml +0 -0
  44. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/semantic_pull_request.yml +0 -0
  45. {python_gitea-0.11.7 → python_gitea-0.12.1}/.github/workflows/support_floor_update.yml +0 -0
  46. {python_gitea-0.11.7 → python_gitea-0.12.1}/.gitignore +0 -0
  47. {python_gitea-0.11.7 → python_gitea-0.12.1}/.markdownlint.yaml +0 -0
  48. {python_gitea-0.11.7 → python_gitea-0.12.1}/.prettierrc +0 -0
  49. {python_gitea-0.11.7 → python_gitea-0.12.1}/.pypirc +0 -0
  50. {python_gitea-0.11.7 → python_gitea-0.12.1}/.typos.toml +0 -0
  51. {python_gitea-0.11.7 → python_gitea-0.12.1}/CITATION.cff +0 -0
  52. {python_gitea-0.11.7 → python_gitea-0.12.1}/CODE_OF_CONDUCT.md +0 -0
  53. {python_gitea-0.11.7 → python_gitea-0.12.1}/CONTRIBUTING.md +0 -0
  54. {python_gitea-0.11.7 → python_gitea-0.12.1}/LICENSE +0 -0
  55. {python_gitea-0.11.7 → python_gitea-0.12.1}/README.md +0 -0
  56. {python_gitea-0.11.7 → python_gitea-0.12.1}/SECURITY.md +0 -0
  57. {python_gitea-0.11.7 → python_gitea-0.12.1}/SUPPORT.md +0 -0
  58. {python_gitea-0.11.7 → python_gitea-0.12.1}/cliff.toml +0 -0
  59. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/contributing.md +0 -0
  60. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/dev/troubleshooting.md +0 -0
  61. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/gen_ref_pages.py +0 -0
  62. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/index.md +0 -0
  63. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/javascripts/mathjax.js +0 -0
  64. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/security.md +0 -0
  65. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/style/api.css +0 -0
  66. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/user-guide/configuration.md +0 -0
  67. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/user-guide/installation.md +0 -0
  68. {python_gitea-0.11.7 → python_gitea-0.12.1}/docs/user-guide/quickstart.md +0 -0
  69. {python_gitea-0.11.7 → python_gitea-0.12.1}/mkdocs.yml +0 -0
  70. {python_gitea-0.11.7 → python_gitea-0.12.1}/renovate.json +0 -0
  71. {python_gitea-0.11.7 → python_gitea-0.12.1}/scripts/release_version.py +0 -0
  72. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/__init__.py +0 -0
  73. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/__main__.py +0 -0
  74. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/_lazy.py +0 -0
  75. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/__init__.py +0 -0
  76. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/actions.py +0 -0
  77. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/artifact.py +0 -0
  78. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/async_actions.py +0 -0
  79. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/async_artifact.py +0 -0
  80. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/async_run_management.py +0 -0
  81. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/async_runner.py +0 -0
  82. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/async_secret.py +0 -0
  83. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/async_variable.py +0 -0
  84. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/base.py +0 -0
  85. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/run_management.py +0 -0
  86. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/runner.py +0 -0
  87. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/scope.py +0 -0
  88. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/secret.py +0 -0
  89. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/actions/variable.py +0 -0
  90. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/__init__.py +0 -0
  91. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/__init__.py +0 -0
  92. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/artifact/__init__.py +0 -0
  93. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/artifact/delete.py +0 -0
  94. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/artifact/download.py +0 -0
  95. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/artifact/get.py +0 -0
  96. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/artifact/list.py +0 -0
  97. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/job/__init__.py +0 -0
  98. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/job/get.py +0 -0
  99. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/job/list.py +0 -0
  100. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/job/logs.py +0 -0
  101. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/job/rerun.py +0 -0
  102. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/main.py +0 -0
  103. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/__init__.py +0 -0
  104. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/approve.py +0 -0
  105. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/cancel.py +0 -0
  106. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/delete.py +0 -0
  107. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/force_cancel.py +0 -0
  108. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/get.py +0 -0
  109. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/jobs.py +0 -0
  110. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/list.py +0 -0
  111. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/run/rerun.py +0 -0
  112. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/runner/__init__.py +0 -0
  113. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/runner/delete.py +0 -0
  114. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/runner/get.py +0 -0
  115. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/runner/list.py +0 -0
  116. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/runner/registration_token.py +0 -0
  117. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/runner/state.py +0 -0
  118. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/runner/update.py +0 -0
  119. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/secret/__init__.py +0 -0
  120. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/secret/delete.py +0 -0
  121. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/secret/list.py +0 -0
  122. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/secret/set.py +0 -0
  123. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/variable/__init__.py +0 -0
  124. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/variable/create.py +0 -0
  125. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/variable/delete.py +0 -0
  126. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/variable/get.py +0 -0
  127. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/variable/list.py +0 -0
  128. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/variable/update.py +0 -0
  129. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/workflow/__init__.py +0 -0
  130. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/workflow/dispatch.py +0 -0
  131. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/workflow/get.py +0 -0
  132. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/actions/workflow/list.py +0 -0
  133. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/comment/__init__.py +0 -0
  134. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/comment/add.py +0 -0
  135. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/comment/delete.py +0 -0
  136. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/comment/edit.py +0 -0
  137. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/comment/list.py +0 -0
  138. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/comment/main.py +0 -0
  139. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/config/__init__.py +0 -0
  140. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/config/add.py +0 -0
  141. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/config/delete.py +0 -0
  142. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/config/list.py +0 -0
  143. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/config/main.py +0 -0
  144. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/config/update.py +0 -0
  145. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/__init__.py +0 -0
  146. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/close.py +0 -0
  147. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/create.py +0 -0
  148. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/dependency/__init__.py +0 -0
  149. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/dependency/add.py +0 -0
  150. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/dependency/list.py +0 -0
  151. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/dependency/main.py +0 -0
  152. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/dependency/remove.py +0 -0
  153. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/edit.py +0 -0
  154. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/get.py +0 -0
  155. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/issue/list.py +0 -0
  156. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/label/__init__.py +0 -0
  157. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/label/create.py +0 -0
  158. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/label/delete.py +0 -0
  159. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/label/list.py +0 -0
  160. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/label/main.py +0 -0
  161. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/label/update.py +0 -0
  162. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/main.py +0 -0
  163. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/milestone/__init__.py +0 -0
  164. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/milestone/create.py +0 -0
  165. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/milestone/list.py +0 -0
  166. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/milestone/main.py +0 -0
  167. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/notification/__init__.py +0 -0
  168. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/notification/list.py +0 -0
  169. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/notification/main.py +0 -0
  170. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/notification/read.py +0 -0
  171. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/organization/__init__.py +0 -0
  172. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/organization/list.py +0 -0
  173. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/organization/main.py +0 -0
  174. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/output.py +0 -0
  175. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/__init__.py +0 -0
  176. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/column/__init__.py +0 -0
  177. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/column/create.py +0 -0
  178. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/column/issues.py +0 -0
  179. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/column/list.py +0 -0
  180. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/create.py +0 -0
  181. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/delete.py +0 -0
  182. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/edit.py +0 -0
  183. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/get.py +0 -0
  184. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/issue/__init__.py +0 -0
  185. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/issue/add.py +0 -0
  186. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/issue/move.py +0 -0
  187. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/issue/remove.py +0 -0
  188. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/issues.py +0 -0
  189. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/list.py +0 -0
  190. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/main.py +0 -0
  191. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/project/show.py +0 -0
  192. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/pull_request/__init__.py +0 -0
  193. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/pull_request/list.py +0 -0
  194. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/pull_request/main.py +0 -0
  195. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/repository/__init__.py +0 -0
  196. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/repository/list.py +0 -0
  197. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/repository/main.py +0 -0
  198. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/user/__init__.py +0 -0
  199. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/user/get.py +0 -0
  200. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/user/main.py +0 -0
  201. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/user/update_settings.py +0 -0
  202. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/utils/__init__.py +0 -0
  203. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/utils/api.py +0 -0
  204. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/utils/auth.py +0 -0
  205. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/utils/convert.py +0 -0
  206. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/utils/errors.py +0 -0
  207. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/utils/issue.py +0 -0
  208. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/utils/options.py +0 -0
  209. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/watch/__init__.py +0 -0
  210. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/watch/advance.py +0 -0
  211. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/watch/list.py +0 -0
  212. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/watch/main.py +0 -0
  213. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/cli/watch/scopes.py +0 -0
  214. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/client/__init__.py +0 -0
  215. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/client/async_gitea.py +0 -0
  216. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/client/base.py +0 -0
  217. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/client/gitea.py +0 -0
  218. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/comment/__init__.py +0 -0
  219. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/comment/async_comment.py +0 -0
  220. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/comment/base.py +0 -0
  221. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/comment/comment.py +0 -0
  222. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/config/__init__.py +0 -0
  223. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/config/manager.py +0 -0
  224. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/config/model.py +0 -0
  225. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/issue/__init__.py +0 -0
  226. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/issue/project_column.py +0 -0
  227. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/label/__init__.py +0 -0
  228. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/milestone/__init__.py +0 -0
  229. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/milestone/async_milestone.py +0 -0
  230. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/milestone/base.py +0 -0
  231. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/milestone/milestone.py +0 -0
  232. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/notification/__init__.py +0 -0
  233. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/notification/async_notification.py +0 -0
  234. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/notification/base.py +0 -0
  235. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/notification/notification.py +0 -0
  236. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/organization/__init__.py +0 -0
  237. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/organization/async_organization.py +0 -0
  238. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/organization/base.py +0 -0
  239. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/organization/organization.py +0 -0
  240. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/project/__init__.py +0 -0
  241. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/project/async_project.py +0 -0
  242. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/project/base.py +0 -0
  243. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/project/project.py +0 -0
  244. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/pull_request/__init__.py +0 -0
  245. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/pull_request/async_pull_request.py +0 -0
  246. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/pull_request/base.py +0 -0
  247. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/pull_request/pull_request.py +0 -0
  248. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/repository/__init__.py +0 -0
  249. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/repository/async_repository.py +0 -0
  250. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/repository/base.py +0 -0
  251. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/repository/repository.py +0 -0
  252. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/resource/__init__.py +0 -0
  253. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/resource/async_resource.py +0 -0
  254. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/resource/protocol.py +0 -0
  255. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/resource/resource.py +0 -0
  256. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/user/__init__.py +0 -0
  257. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/user/async_user.py +0 -0
  258. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/user/base.py +0 -0
  259. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/user/user.py +0 -0
  260. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/utils/__init__.py +0 -0
  261. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/utils/fields.py +0 -0
  262. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/utils/log.py +0 -0
  263. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/utils/pagination.py +0 -0
  264. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/utils/response.py +0 -0
  265. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/version.py +0 -0
  266. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/watch/__init__.py +0 -0
  267. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/watch/changes.py +0 -0
  268. {python_gitea-0.11.7 → python_gitea-0.12.1}/src/gitea/watch/state.py +0 -0
  269. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/__init__.py +0 -0
  270. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/actions/__init__.py +0 -0
  271. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/actions/test_actions_base.py +0 -0
  272. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/actions/test_actions_imports.py +0 -0
  273. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/actions/test_actions_requests.py +0 -0
  274. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/actions/test_actions_scope.py +0 -0
  275. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/board.py +0 -0
  276. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/__init__.py +0 -0
  277. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/__init__.py +0 -0
  278. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/invoking.py +0 -0
  279. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_artifact.py +0 -0
  280. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_job_get.py +0 -0
  281. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_job_list.py +0 -0
  282. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_job_logs.py +0 -0
  283. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_main.py +0 -0
  284. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_run_get.py +0 -0
  285. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_run_jobs.py +0 -0
  286. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_run_list.py +0 -0
  287. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_run_management.py +0 -0
  288. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_runner.py +0 -0
  289. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_secret.py +0 -0
  290. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_variable.py +0 -0
  291. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_workflow_dispatch.py +0 -0
  292. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_workflow_get.py +0 -0
  293. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/actions/test_cli_actions_workflow_list.py +0 -0
  294. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/comment/__init__.py +0 -0
  295. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/comment/test_cli_comment_add.py +0 -0
  296. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/comment/test_cli_comment_delete.py +0 -0
  297. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/comment/test_cli_comment_edit.py +0 -0
  298. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/comment/test_cli_comment_list.py +0 -0
  299. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/comment/test_cli_comment_main.py +0 -0
  300. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/config/__init__.py +0 -0
  301. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/config/test_cli_config_add.py +0 -0
  302. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/config/test_cli_config_delete.py +0 -0
  303. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/config/test_cli_config_list.py +0 -0
  304. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/config/test_cli_config_main.py +0 -0
  305. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/config/test_cli_config_update.py +0 -0
  306. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/envelope.py +0 -0
  307. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/__init__.py +0 -0
  308. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/dependency/__init__.py +0 -0
  309. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/dependency/test_cli_issue_dependency.py +0 -0
  310. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/test_cli_issue_close.py +0 -0
  311. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/test_cli_issue_comment.py +0 -0
  312. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/test_cli_issue_create.py +0 -0
  313. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/test_cli_issue_edit.py +0 -0
  314. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/test_cli_issue_get.py +0 -0
  315. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/test_cli_issue_list.py +0 -0
  316. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/issue/test_cli_issue_main.py +0 -0
  317. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/label/__init__.py +0 -0
  318. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/label/test_cli_label_create.py +0 -0
  319. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/label/test_cli_label_delete.py +0 -0
  320. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/label/test_cli_label_list.py +0 -0
  321. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/label/test_cli_label_main.py +0 -0
  322. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/label/test_cli_label_update.py +0 -0
  323. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/milestone/__init__.py +0 -0
  324. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/milestone/test_cli_milestone_create.py +0 -0
  325. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/milestone/test_cli_milestone_list.py +0 -0
  326. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/milestone/test_cli_milestone_main.py +0 -0
  327. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/notification/__init__.py +0 -0
  328. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/notification/test_cli_notification.py +0 -0
  329. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/organization/__init__.py +0 -0
  330. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/organization/test_cli_organization_list.py +0 -0
  331. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/organization/test_cli_organization_main.py +0 -0
  332. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/project/__init__.py +0 -0
  333. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/project/test_cli_project.py +0 -0
  334. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/project/test_cli_project_column_issues.py +0 -0
  335. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/project/test_cli_project_show.py +0 -0
  336. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/pull_request/__init__.py +0 -0
  337. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/pull_request/test_cli_pull_request_list.py +0 -0
  338. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/pull_request/test_cli_pull_request_main.py +0 -0
  339. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/rendering.py +0 -0
  340. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/repository/__init__.py +0 -0
  341. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/repository/test_cli_repository_list.py +0 -0
  342. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/repository/test_cli_repository_main.py +0 -0
  343. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/test_cli_output.py +0 -0
  344. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/tree.py +0 -0
  345. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/user/__init__.py +0 -0
  346. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/user/test_cli_user_get.py +0 -0
  347. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/user/test_cli_user_update_settings.py +0 -0
  348. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/utils/__init__.py +0 -0
  349. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/utils/test_cli_utils_api.py +0 -0
  350. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/utils/test_cli_utils_auth.py +0 -0
  351. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/utils/test_cli_utils_convert.py +0 -0
  352. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/utils/test_cli_utils_errors.py +0 -0
  353. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/utils/test_cli_utils_issue.py +0 -0
  354. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/utils/test_cli_utils_options.py +0 -0
  355. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/watch/__init__.py +0 -0
  356. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/watch/support.py +0 -0
  357. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/watch/test_cli_watch_advance.py +0 -0
  358. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/watch/test_cli_watch_list.py +0 -0
  359. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/cli/watch/test_cli_watch_scopes.py +0 -0
  360. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/client/__init__.py +0 -0
  361. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/client/test_client_async_gitea.py +0 -0
  362. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/client/test_client_base.py +0 -0
  363. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/client/test_client_gitea.py +0 -0
  364. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/comment/__init__.py +0 -0
  365. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/comment/test_comment_async_comment.py +0 -0
  366. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/comment/test_comment_base.py +0 -0
  367. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/comment/test_comment_comment.py +0 -0
  368. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/config/__init__.py +0 -0
  369. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/config/test_config_manager.py +0 -0
  370. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/config/test_config_model.py +0 -0
  371. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/conftest.py +0 -0
  372. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/issue/__init__.py +0 -0
  373. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/issue/test_issue_async_issue.py +0 -0
  374. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/issue/test_issue_async_project_column.py +0 -0
  375. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/issue/test_issue_base.py +0 -0
  376. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/issue/test_issue_dependencies.py +0 -0
  377. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/issue/test_issue_issue.py +0 -0
  378. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/issue/test_issue_project_column.py +0 -0
  379. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/label/__init__.py +0 -0
  380. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/milestone/__init__.py +0 -0
  381. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/milestone/test_milestone_async_milestone.py +0 -0
  382. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/milestone/test_milestone_base.py +0 -0
  383. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/milestone/test_milestone_milestone.py +0 -0
  384. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/notification/__init__.py +0 -0
  385. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/notification/test_notification_base.py +0 -0
  386. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/notification/test_notification_notification.py +0 -0
  387. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/organization/__init__.py +0 -0
  388. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/organization/test_organization_async_organization.py +0 -0
  389. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/organization/test_organization_base.py +0 -0
  390. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/organization/test_organization_organization.py +0 -0
  391. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/project/__init__.py +0 -0
  392. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/project/test_project_base.py +0 -0
  393. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/project/test_project_project.py +0 -0
  394. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/project/test_project_requests.py +0 -0
  395. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/pull_request/__init__.py +0 -0
  396. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/pull_request/test_pull_request_async_pull_request.py +0 -0
  397. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/pull_request/test_pull_request_base.py +0 -0
  398. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/pull_request/test_pull_request_pull_request.py +0 -0
  399. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/repository/__init__.py +0 -0
  400. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/repository/test_repository_async_repository.py +0 -0
  401. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/repository/test_repository_base.py +0 -0
  402. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/repository/test_repository_repository.py +0 -0
  403. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/resource/__init__.py +0 -0
  404. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/resource/test_resource_async_resource.py +0 -0
  405. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/resource/test_resource_resource.py +0 -0
  406. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/smoke_test.py +0 -0
  407. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/test_import.py +0 -0
  408. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/test_lazy_reexports.py +0 -0
  409. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/test_main.py +0 -0
  410. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/test_release_version.py +0 -0
  411. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/test_version.py +0 -0
  412. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/transport.py +0 -0
  413. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/user/__init__.py +0 -0
  414. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/user/test_user_async_user.py +0 -0
  415. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/user/test_user_base.py +0 -0
  416. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/user/test_user_user.py +0 -0
  417. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/utils/__init__.py +0 -0
  418. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/utils/test_utils_fields.py +0 -0
  419. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/utils/test_utils_log.py +0 -0
  420. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/utils/test_utils_pagination.py +0 -0
  421. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/utils/test_utils_response.py +0 -0
  422. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/watch/__init__.py +0 -0
  423. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/watch/test_watch_changes.py +0 -0
  424. {python_gitea-0.11.7 → python_gitea-0.12.1}/tests/watch/test_watch_state.py +0 -0
@@ -52,7 +52,7 @@ repos:
52
52
  - id: actionlint
53
53
 
54
54
  - repo: https://github.com/astral-sh/uv-pre-commit
55
- rev: 0.12.19
55
+ rev: 0.12.21
56
56
  hooks:
57
57
  # Update the uv lockfile
58
58
  - id: uv-lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: python-gitea
3
- Version: 0.11.7
3
+ Version: 0.12.1
4
4
  Summary: A Python package for interacting with the Gitea API, offering a simple interface to access repositories, users, organizations, issues, and more for automation and data management.
5
5
  Project-URL: Documentation, https://isaac-cf-wong.github.io/python-gitea
6
6
  Project-URL: Source, https://github.com/isaac-cf-wong/python-gitea
@@ -58,7 +58,7 @@ src/gitea/
58
58
  │ ├── main.py # gitea-cli entry point, command registration
59
59
  │ ├── config/ # config commands
60
60
  │ ├── actions/ # actions workflow, run, job, artifact, secret, variable, runner commands
61
- │ ├── issue/ # issue + issue dependency commands
61
+ │ ├── issue/ # issue, issue dependency + issue label commands
62
62
  │ ├── pull_request/ # pull-request commands
63
63
  │ ├── comment/ # comment commands
64
64
  │ ├── label/ # label commands
@@ -150,7 +150,8 @@ absence of any module-level import cycle anywhere in `gitea`.
150
150
 
151
151
  The CLI is a single Typer application registered in `cli/main.py`. Each resource
152
152
  has a command group (e.g. `gitea-cli issue`, `gitea-cli project`), and nested
153
- groups exist where the domain nests (e.g. `project column`, `issue dependency`).
153
+ groups exist where the domain nests (e.g. `project column`, `issue dependency`,
154
+ `issue label`).
154
155
 
155
156
  CLI commands reuse the client through thin helper functions in `cli/utils/`
156
157
  (`auth.py` resolves authentication, `api.py` and `convert.py` handle requests
@@ -478,6 +478,41 @@ otherwise look like.
478
478
  - `gitea-cli issue dependency remove --owner <owner> --repository <repo> --issue-id <number>`
479
479
  - Required: `--dependency-owner <owner>`, `--dependency-repository <repo>`,
480
480
  `--dependency-issue-id <number>`
481
+ - `gitea-cli issue label list --owner <owner> --repository <repo> --issue-id <number>`
482
+ - `gitea-cli issue label add --owner <owner> --repository <repo> --issue-id <number> --label <name-or-id>`
483
+ - Adds the labels and keeps the ones the issue already has.
484
+ - `gitea-cli issue label remove --owner <owner> --repository <repo> --issue-id <number> --label <name-or-id>`
485
+ - A label the issue does not carry is left alone: the command still
486
+ succeeds, logs a warning, and names the label's ID in `not_on_issue` in
487
+ the issue's metadata.
488
+ - `gitea-cli issue label set --owner <owner> --repository <repo> --issue-id <number> --label <name-or-id>`
489
+ - Replaces every label of the issue with the given ones.
490
+ - `gitea-cli issue label clear --owner <owner> --repository <repo> --issue-id <number>`
491
+ - Removes every label from the issue.
492
+
493
+ The `issue label` commands act on the labels an issue carries; the
494
+ [`label` commands](#label---manage-labels) manage the labels a repository
495
+ defines. In all of them:
496
+
497
+ - `--label` is repeated once per label, and takes a label's name or its numeric
498
+ ID. A name is resolved to its ID through the repository's labels before
499
+ anything is written, so it works on a Gitea that only accepts IDs. Names are
500
+ matched exactly, case included. A name that matches no label, or more than
501
+ one, fails the command and no issue is changed. A value made only of digits is
502
+ taken as an ID, which is how a label defined on the organization rather than
503
+ the repository is named. An ID is checked as well: one that is neither a label
504
+ of the repository nor of the organization owning it fails the command in the
505
+ same way, before anything is written. Label IDs belong to the repository or
506
+ organization that defines them, so an ID read from another repository names a
507
+ different label, or none; prefer the name, which means the same label wherever
508
+ it is defined.
509
+ - `--issue-id` can be repeated to act on several issues in one run. With one
510
+ issue, `data` is the list of labels the issue is left with. With several,
511
+ `data` holds one entry per issue, in the order given:
512
+ `{"issue_id": <number>, "labels": [...]}`, plus `not_on_issue` for `remove`.
513
+ The issues are changed one after another; if one fails, the command stops,
514
+ prints nothing on stdout, and its error names the issues that were already
515
+ changed.
481
516
 
482
517
  ### Pull Request - manage pull requests
483
518
 
@@ -886,6 +921,16 @@ gitea-cli issue create \
886
921
  --milestone 3
887
922
  ```
888
923
 
924
+ Add a label to several existing issues, keeping the labels they already have:
925
+
926
+ ```bash
927
+ gitea-cli issue label add \
928
+ --owner my-org \
929
+ --repository my-repo \
930
+ --issue-id 12 --issue-id 13 --issue-id 14 \
931
+ --label "needs review"
932
+ ```
933
+
889
934
  Start a workflow, then follow the run it started:
890
935
 
891
936
  ```bash
@@ -155,12 +155,12 @@ is simpler and sufficient.
155
155
  | Client attribute | Gitea domain |
156
156
  | --------------------- | ---------------------------------------------------------------------- |
157
157
  | `client.actions` | Actions: workflows, runs, jobs, artifacts, secrets, variables, runners |
158
- | `client.issue` | Issues and issue dependencies |
158
+ | `client.issue` | Issues, issue dependencies and issue labels |
159
159
  | `client.pull_request` | Pull requests |
160
160
  | `client.repository` | Repositories |
161
161
  | `client.user` | Users and user settings |
162
162
  | `client.comment` | Issue comments |
163
- | `client.label` | Issue labels |
163
+ | `client.label` | The labels a repository defines |
164
164
  | `client.milestone` | Milestones |
165
165
  | `client.notification` | Notifications |
166
166
  | `client.project` | Projects, columns, and project issues |
@@ -38,7 +38,7 @@ dev = [
38
38
  "prek>=0.5.3",
39
39
  "pytest-github-actions-annotate-failures>=0.4.2",
40
40
  "pytest-cov>=7.1.0",
41
- "pytest-mock>=3.15.1",
41
+ "pytest-mock>=3.16.0",
42
42
  "pytest>=9.1.1",
43
43
  "pytest-asyncio>=1.4.0",
44
44
  ]
@@ -0,0 +1 @@
1
+ """CLI commands for managing the labels of issues."""
@@ -0,0 +1,97 @@
1
+ """Add issue labels command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from gitea.cli.issue.label.common import ISSUE_IDS_HELP, LABEL_HELP
10
+ from gitea.cli.utils.options import REPOSITORY_REQUIRED_HELP
11
+
12
+
13
+ def add_command(
14
+ ctx: typer.Context,
15
+ owner: Annotated[str, typer.Option("--owner", help="Owner of the repository.")],
16
+ repository: Annotated[str | None, typer.Option("--repository", help=REPOSITORY_REQUIRED_HELP)] = None,
17
+ issue_ids: Annotated[list[int] | None, typer.Option("--issue-id", help=ISSUE_IDS_HELP)] = None,
18
+ labels: Annotated[list[str] | None, typer.Option("--label", help=LABEL_HELP)] = None,
19
+ account_name: Annotated[
20
+ str | None,
21
+ typer.Option(
22
+ "--account-name",
23
+ help="Name of the account to use for authentication.",
24
+ ),
25
+ ] = None,
26
+ token: Annotated[
27
+ str | None,
28
+ typer.Option(
29
+ "--token",
30
+ help="Token for authentication. If not provided, the token from the specified account will be used.",
31
+ ),
32
+ ] = None,
33
+ base_url: Annotated[
34
+ str | None,
35
+ typer.Option(
36
+ "--base-url",
37
+ help="Base URL of the Gitea platform. If not provided, the base URL from the specified account will be used.",
38
+ ),
39
+ ] = None,
40
+ ) -> None:
41
+ """Add labels to one or more issues, keeping the labels they already have.
42
+
43
+ Args:
44
+ ctx: The Typer context.
45
+ owner: The owner of the repository.
46
+ repository: The name of the repository, which this command requires.
47
+ issue_ids: The issue numbers shown in the web UI.
48
+ labels: The labels, each a name or a numeric ID.
49
+ account_name: Name of the account to use for authentication.
50
+ token: Token for authentication.
51
+ base_url: Base URL of the Gitea platform.
52
+
53
+ """
54
+ from typing import Any # noqa: PLC0415
55
+
56
+ from gitea.cli.issue.label.common import ( # noqa: PLC0415
57
+ for_each_issue,
58
+ require_issue_ids,
59
+ require_labels,
60
+ resolve_label_ids,
61
+ )
62
+ from gitea.cli.utils.api import execute_api_command # noqa: PLC0415
63
+ from gitea.cli.utils.auth import get_auth_params # noqa: PLC0415
64
+ from gitea.cli.utils.options import require_repository # noqa: PLC0415
65
+ from gitea.client.gitea import Gitea # noqa: PLC0415
66
+
67
+ command = "gitea-cli issue label add"
68
+ token, base_url = get_auth_params(
69
+ config_path=ctx.obj.get("config_path"),
70
+ account_name=account_name,
71
+ token=token,
72
+ base_url=base_url,
73
+ )
74
+
75
+ def api_call() -> tuple[dict[str, Any] | list[dict[str, Any]], dict[str, Any]]:
76
+ """Add the labels to each issue.
77
+
78
+ Returns:
79
+ A tuple containing the issue's resulting labels, or one entry per issue, and metadata.
80
+
81
+ """
82
+ target_repository = require_repository(repository, command=command)
83
+ targets = require_issue_ids(issue_ids, command=command)
84
+ requested = require_labels(labels, command=command)
85
+
86
+ with Gitea(token=token, base_url=base_url) as client:
87
+ label_ids = resolve_label_ids(client, owner, target_repository, requested, command=command)
88
+ # POST appends to the issue's labels; PUT would replace them.
89
+ return for_each_issue(
90
+ targets,
91
+ lambda issue_id: client.issue.add_issue_labels(
92
+ owner=owner, repository=target_repository, index=issue_id, labels=list(label_ids)
93
+ ),
94
+ command=command,
95
+ )
96
+
97
+ execute_api_command(api_call=api_call, base_url=base_url, command_name=command)
@@ -0,0 +1,94 @@
1
+ """Clear issue labels command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from gitea.cli.issue.label.common import ISSUE_IDS_HELP
10
+ from gitea.cli.utils.options import REPOSITORY_REQUIRED_HELP
11
+
12
+
13
+ def clear_command(
14
+ ctx: typer.Context,
15
+ owner: Annotated[str, typer.Option("--owner", help="Owner of the repository.")],
16
+ repository: Annotated[str | None, typer.Option("--repository", help=REPOSITORY_REQUIRED_HELP)] = None,
17
+ issue_ids: Annotated[list[int] | None, typer.Option("--issue-id", help=ISSUE_IDS_HELP)] = None,
18
+ account_name: Annotated[
19
+ str | None,
20
+ typer.Option(
21
+ "--account-name",
22
+ help="Name of the account to use for authentication.",
23
+ ),
24
+ ] = None,
25
+ token: Annotated[
26
+ str | None,
27
+ typer.Option(
28
+ "--token",
29
+ help="Token for authentication. If not provided, the token from the specified account will be used.",
30
+ ),
31
+ ] = None,
32
+ base_url: Annotated[
33
+ str | None,
34
+ typer.Option(
35
+ "--base-url",
36
+ help="Base URL of the Gitea platform. If not provided, the base URL from the specified account will be used.",
37
+ ),
38
+ ] = None,
39
+ ) -> None:
40
+ """Remove every label from one or more issues.
41
+
42
+ Args:
43
+ ctx: The Typer context.
44
+ owner: The owner of the repository.
45
+ repository: The name of the repository, which this command requires.
46
+ issue_ids: The issue numbers shown in the web UI.
47
+ account_name: Name of the account to use for authentication.
48
+ token: Token for authentication.
49
+ base_url: Base URL of the Gitea platform.
50
+
51
+ """
52
+ from typing import Any # noqa: PLC0415
53
+
54
+ from gitea.cli.issue.label.common import for_each_issue, require_issue_ids # noqa: PLC0415
55
+ from gitea.cli.utils.api import execute_api_command # noqa: PLC0415
56
+ from gitea.cli.utils.auth import get_auth_params # noqa: PLC0415
57
+ from gitea.cli.utils.options import require_repository # noqa: PLC0415
58
+ from gitea.client.gitea import Gitea # noqa: PLC0415
59
+
60
+ command = "gitea-cli issue label clear"
61
+ token, base_url = get_auth_params(
62
+ config_path=ctx.obj.get("config_path"),
63
+ account_name=account_name,
64
+ token=token,
65
+ base_url=base_url,
66
+ )
67
+
68
+ def api_call() -> tuple[dict[str, Any] | list[dict[str, Any]], dict[str, Any]]:
69
+ """Remove every label from each issue.
70
+
71
+ Returns:
72
+ A tuple containing the issue's resulting labels, or one entry per issue, and metadata.
73
+
74
+ """
75
+ target_repository = require_repository(repository, command=command)
76
+ targets = require_issue_ids(issue_ids, command=command)
77
+
78
+ def clear(issue_id: int) -> tuple[list[dict[str, Any]], dict[str, Any]]:
79
+ """Remove every label from one issue, and read back what it is left with.
80
+
81
+ Args:
82
+ issue_id: The issue to clear.
83
+
84
+ Returns:
85
+ A tuple containing the issue's resulting labels and metadata.
86
+
87
+ """
88
+ client.issue.clear_issue_labels(owner=owner, repository=target_repository, index=issue_id)
89
+ return client.issue.list_issue_labels(owner=owner, repository=target_repository, index=issue_id)
90
+
91
+ with Gitea(token=token, base_url=base_url) as client:
92
+ return for_each_issue(targets, clear, command=command)
93
+
94
+ execute_api_command(api_call=api_call, base_url=base_url, command_name=command)
@@ -0,0 +1,267 @@
1
+ """What the `issue label` commands share: reading labels and issues, and reporting per issue.
2
+
3
+ A label is named on the command line by its name or by its numeric ID. Names are
4
+ resolved to IDs here, through the repository's label listing, rather than sent to
5
+ the API as they are: only a recent Gitea accepts names in an issue's label list,
6
+ and one that does not rejects the whole request. Resolving first also means an
7
+ unknown name is an error before anything is written, rather than a label silently
8
+ not applied, and before the first of several issues has been changed.
9
+
10
+ A value made only of ASCII digits is taken to be an ID. An ID is checked too,
11
+ against the repository's labels and then, for one not among them, against the
12
+ labels of the organization owning the repository, which the repository's listing
13
+ does not include. An ID found in neither is an error before anything is written:
14
+ Gitea drops an ID it cannot apply without saying so, so an ID copied from another
15
+ repository would otherwise be a silent no-op for `add`, and for `set` would leave
16
+ the issue with no labels at all.
17
+
18
+ Every command takes one `--issue-id` or several. With one, `data` is that issue's
19
+ labels, as `gitea-cli issue label list` emits them. With several, `data` holds one
20
+ entry per issue, `{"issue_id": ..., "labels": [...]}`, in the order the issues were
21
+ given, so that which issue was left with which labels can be read back. The shape
22
+ follows from how the command was invoked, never from what the API answered.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import logging
28
+ import re
29
+ from collections.abc import Callable
30
+ from typing import TYPE_CHECKING, Any
31
+
32
+ from requests import HTTPError
33
+
34
+ from gitea.cli.utils.errors import CommandError
35
+ from gitea.utils.pagination import PAGE_SIZE, collect_all_pages
36
+
37
+ if TYPE_CHECKING:
38
+ from gitea.client.gitea import Gitea
39
+
40
+ logger = logging.getLogger("gitea")
41
+
42
+ ISSUE_IDS_HELP = "Issue number shown in the web UI. Repeat the option to act on several issues."
43
+ LABEL_HELP = "Label name or numeric ID. Repeat the option for several labels."
44
+
45
+ _NUMERIC_ID = re.compile(r"[0-9]+")
46
+ _NOT_FOUND = 404
47
+
48
+
49
+ def require_issue_ids(issue_ids: list[int] | None, *, command: str) -> list[int]:
50
+ """Read the issues a command acts on.
51
+
52
+ Args:
53
+ issue_ids: The values passed as --issue-id, or None when it was omitted.
54
+ command: The command being run, named as the user invoked it.
55
+
56
+ Returns:
57
+ The issue numbers, in the order given, each once.
58
+
59
+ Raises:
60
+ CommandError: If no issue was given.
61
+
62
+ """
63
+ if not issue_ids:
64
+ raise CommandError(f"'{command}' needs an issue: pass --issue-id NUMBER, once per issue.")
65
+ return list(dict.fromkeys(issue_ids))
66
+
67
+
68
+ def require_labels(labels: list[str] | None, *, command: str, hint: str = "") -> list[str]:
69
+ """Read the labels a command acts on.
70
+
71
+ Args:
72
+ labels: The values passed as --label, or None when it was omitted.
73
+ command: The command being run, named as the user invoked it.
74
+ hint: A sentence appended to the error, pointing at a command that needs no label.
75
+
76
+ Returns:
77
+ The labels, as they were given.
78
+
79
+ Raises:
80
+ CommandError: If no label was given.
81
+
82
+ """
83
+ if not labels:
84
+ message = f"'{command}' needs a label: pass --label NAME_OR_ID, once per label."
85
+ raise CommandError(f"{message} {hint}" if hint else message)
86
+ return labels
87
+
88
+
89
+ def _organization_label_ids(client: Gitea, owner: str) -> set[int]:
90
+ """Read the IDs of the labels defined on the organization owning a repository.
91
+
92
+ Args:
93
+ client: The client to list the labels with.
94
+ owner: The owner of the repository.
95
+
96
+ Returns:
97
+ The IDs, or none when the owner is a user rather than an organization,
98
+ which Gitea answers with a 404.
99
+
100
+ Raises:
101
+ HTTPError: If the listing failed for any other reason.
102
+
103
+ """
104
+ try:
105
+ defined, _ = collect_all_pages(
106
+ lambda page: client.label.list_organization_labels(organization=owner, page=page, limit=PAGE_SIZE)
107
+ )
108
+ except HTTPError as e:
109
+ response = getattr(e, "response", None)
110
+ if response is None or response.status_code != _NOT_FOUND:
111
+ raise
112
+ return set()
113
+ return {label["id"] for label in defined}
114
+
115
+
116
+ def resolve_label_ids(client: Gitea, owner: str, repository: str, labels: list[str], *, command: str) -> list[int]:
117
+ """Resolve the labels given on the command line to their IDs, and check that each exists.
118
+
119
+ The repository's labels are listed once for all of them. The organization's
120
+ are listed only when an ID is not among the repository's.
121
+
122
+ Args:
123
+ client: The client to list the labels with.
124
+ owner: The owner of the repository.
125
+ repository: The name of the repository.
126
+ labels: The labels, each a name or a numeric ID.
127
+ command: The command being run, named as the user invoked it.
128
+
129
+ Returns:
130
+ The label IDs, in the order given, each once.
131
+
132
+ Raises:
133
+ CommandError: If a name matches no label of the repository, or more than
134
+ one, or an ID is neither a label of the repository nor of the
135
+ organization owning it.
136
+
137
+ """
138
+ defined, _ = collect_all_pages(
139
+ lambda page: client.label.list_labels(owner=owner, repository=repository, page=page, limit=PAGE_SIZE)
140
+ )
141
+ by_name: dict[str, list[int]] = {}
142
+ for label in defined:
143
+ by_name.setdefault(label["name"], []).append(label["id"])
144
+
145
+ names = [label for label in labels if not _NUMERIC_ID.fullmatch(label)]
146
+ unknown = [name for name in names if name not in by_name]
147
+ if unknown:
148
+ raise CommandError(
149
+ f"'{command}': no label named {', '.join(repr(name) for name in unknown)} in {owner}/{repository}. "
150
+ f"Names are matched exactly, case included; 'gitea-cli label list' shows the repository's labels. "
151
+ f"A label defined on the organization is not looked up by name: pass its numeric ID."
152
+ )
153
+ ambiguous = [name for name in names if len(by_name[name]) > 1]
154
+ if ambiguous:
155
+ raise CommandError(
156
+ f"'{command}': more than one label is named {', '.join(repr(name) for name in ambiguous)} "
157
+ f"in {owner}/{repository}. Pass the numeric ID of the one you mean."
158
+ )
159
+
160
+ repository_ids = {label["id"] for label in defined}
161
+ ids = [int(label) for label in labels if _NUMERIC_ID.fullmatch(label)]
162
+ elsewhere = [label_id for label_id in dict.fromkeys(ids) if label_id not in repository_ids]
163
+ if elsewhere:
164
+ organization_ids = _organization_label_ids(client, owner)
165
+ missing = [label_id for label_id in elsewhere if label_id not in organization_ids]
166
+ if missing:
167
+ raise CommandError(
168
+ f"'{command}': no label with ID {', '.join(str(label_id) for label_id in missing)} "
169
+ f"in {owner}/{repository} or on its owner {owner}. "
170
+ f"A label's ID belongs to the repository or organization defining it, so an ID read from "
171
+ f"another repository names a different label there, or none; nothing was changed. "
172
+ f"Pass the label's name instead; 'gitea-cli label list' shows the repository's labels."
173
+ )
174
+
175
+ resolved = [int(label) if _NUMERIC_ID.fullmatch(label) else by_name[label][0] for label in labels]
176
+ return list(dict.fromkeys(resolved))
177
+
178
+
179
+ def for_each_issue(
180
+ issue_ids: list[int],
181
+ action: Callable[[int], tuple[list[dict[str, Any]], dict[str, Any]]],
182
+ *,
183
+ command: str,
184
+ ) -> tuple[list[dict[str, Any]], dict[str, Any]]:
185
+ """Run a command on each issue in turn and shape what it reports.
186
+
187
+ The issues are acted on one after another, so a failure part-way leaves the
188
+ ones before it changed. The error then names them, since the command prints
189
+ nothing on stdout when it fails and the caller could not tell otherwise.
190
+
191
+ Args:
192
+ issue_ids: The issues to act on.
193
+ action: Callable acting on one issue and returning its resulting labels
194
+ and the metadata of the last response. Extra keys in the metadata
195
+ beyond `status_code` are reported with that issue.
196
+ command: The command being run, named as the user invoked it.
197
+
198
+ Returns:
199
+ A tuple containing the data and the metadata of the envelope: for one
200
+ issue, its labels and its metadata; for several, one entry per issue.
201
+
202
+ Raises:
203
+ CommandError: If acting on an issue after the first failed. A failure
204
+ on the first issue is raised as it was, since nothing else changed.
205
+
206
+ """
207
+ entries: list[dict[str, Any]] = []
208
+ metadata: dict[str, Any] = {}
209
+ for issue_id in issue_ids:
210
+ try:
211
+ labels, metadata = action(issue_id)
212
+ except Exception as e:
213
+ if not entries:
214
+ raise
215
+ done = ", ".join(str(entry["issue_id"]) for entry in entries)
216
+ raise CommandError(
217
+ f"'{command}' failed on issue {issue_id}: {e}. "
218
+ f"Issues {done} were already done, and issue {issue_id} may be partly done; "
219
+ f"the rest were not attempted."
220
+ ) from e
221
+ extra = {key: value for key, value in metadata.items() if key != "status_code"}
222
+ entries.append({"issue_id": issue_id, "labels": labels, **extra})
223
+
224
+ if len(entries) == 1:
225
+ return entries[0]["labels"], metadata
226
+ return entries, {"status_code": metadata["status_code"]}
227
+
228
+
229
+ def remove_carried_labels(
230
+ client: Gitea, owner: str, repository: str, issue_id: int, label_ids: list[int]
231
+ ) -> tuple[list[dict[str, Any]], dict[str, Any]]:
232
+ """Remove from one issue those of the labels it carries, and read back what it is left with.
233
+
234
+ A label the issue does not carry is not an error: removing it would leave the
235
+ issue as it is either way, and a command run over several issues meets that
236
+ routinely. It is not silent either: it is logged, and named in the metadata
237
+ as `not_on_issue`, so a caller can tell a removal from a label that was never
238
+ there.
239
+
240
+ Args:
241
+ client: The client to act with.
242
+ owner: The owner of the repository.
243
+ repository: The name of the repository.
244
+ issue_id: The issue to remove the labels from.
245
+ label_ids: The IDs of the labels to remove.
246
+
247
+ Returns:
248
+ A tuple containing the issue's resulting labels, and metadata naming the
249
+ IDs of the requested labels it did not carry.
250
+
251
+ """
252
+ current, _ = client.issue.list_issue_labels(owner=owner, repository=repository, index=issue_id)
253
+ carried = {label["id"] for label in current}
254
+ absent = [label_id for label_id in label_ids if label_id not in carried]
255
+ if absent:
256
+ logger.warning(
257
+ "Issue %s does not carry label %s; left as it is.",
258
+ issue_id,
259
+ ", ".join(str(label_id) for label_id in absent),
260
+ )
261
+
262
+ for label_id in label_ids:
263
+ if label_id in carried:
264
+ client.issue.remove_issue_label(owner=owner, repository=repository, index=issue_id, label=label_id)
265
+
266
+ remaining, metadata = client.issue.list_issue_labels(owner=owner, repository=repository, index=issue_id)
267
+ return remaining, {**metadata, "not_on_issue": absent}
@@ -0,0 +1,87 @@
1
+ """List issue labels command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from gitea.cli.issue.label.common import ISSUE_IDS_HELP
10
+ from gitea.cli.utils.options import REPOSITORY_REQUIRED_HELP
11
+
12
+
13
+ def list_command(
14
+ ctx: typer.Context,
15
+ owner: Annotated[str, typer.Option("--owner", help="Owner of the repository.")],
16
+ repository: Annotated[str | None, typer.Option("--repository", help=REPOSITORY_REQUIRED_HELP)] = None,
17
+ issue_ids: Annotated[list[int] | None, typer.Option("--issue-id", help=ISSUE_IDS_HELP)] = None,
18
+ account_name: Annotated[
19
+ str | None,
20
+ typer.Option(
21
+ "--account-name",
22
+ help="Name of the account to use for authentication.",
23
+ ),
24
+ ] = None,
25
+ token: Annotated[
26
+ str | None,
27
+ typer.Option(
28
+ "--token",
29
+ help="Token for authentication. If not provided, the token from the specified account will be used.",
30
+ ),
31
+ ] = None,
32
+ base_url: Annotated[
33
+ str | None,
34
+ typer.Option(
35
+ "--base-url",
36
+ help="Base URL of the Gitea platform. If not provided, the base URL from the specified account will be used.",
37
+ ),
38
+ ] = None,
39
+ ) -> None:
40
+ """List the labels of one or more issues.
41
+
42
+ Args:
43
+ ctx: The Typer context.
44
+ owner: The owner of the repository.
45
+ repository: The name of the repository, which this command requires.
46
+ issue_ids: The issue numbers shown in the web UI.
47
+ account_name: Name of the account to use for authentication.
48
+ token: Token for authentication.
49
+ base_url: Base URL of the Gitea platform.
50
+
51
+ """
52
+ from typing import Any # noqa: PLC0415
53
+
54
+ from gitea.cli.issue.label.common import for_each_issue, require_issue_ids # noqa: PLC0415
55
+ from gitea.cli.utils.api import execute_api_command # noqa: PLC0415
56
+ from gitea.cli.utils.auth import get_auth_params # noqa: PLC0415
57
+ from gitea.cli.utils.options import require_repository # noqa: PLC0415
58
+ from gitea.client.gitea import Gitea # noqa: PLC0415
59
+
60
+ command = "gitea-cli issue label list"
61
+ token, base_url = get_auth_params(
62
+ config_path=ctx.obj.get("config_path"),
63
+ account_name=account_name,
64
+ token=token,
65
+ base_url=base_url,
66
+ )
67
+
68
+ def api_call() -> tuple[dict[str, Any] | list[dict[str, Any]], dict[str, Any]]:
69
+ """List the labels of each issue.
70
+
71
+ Returns:
72
+ A tuple containing the issue's resulting labels, or one entry per issue, and metadata.
73
+
74
+ """
75
+ target_repository = require_repository(repository, command=command)
76
+ targets = require_issue_ids(issue_ids, command=command)
77
+
78
+ with Gitea(token=token, base_url=base_url) as client:
79
+ return for_each_issue(
80
+ targets,
81
+ lambda issue_id: client.issue.list_issue_labels(
82
+ owner=owner, repository=target_repository, index=issue_id
83
+ ),
84
+ command=command,
85
+ )
86
+
87
+ execute_api_command(api_call=api_call, base_url=base_url, command_name=command)