python-gitea 0.9.0__tar.gz → 0.10.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 (332) hide show
  1. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/support_floor_update.yml +1 -1
  2. {python_gitea-0.9.0 → python_gitea-0.10.1}/.gitignore +4 -0
  3. {python_gitea-0.9.0 → python_gitea-0.10.1}/.pre-commit-config.yaml +1 -1
  4. {python_gitea-0.9.0 → python_gitea-0.10.1}/CONTRIBUTING.md +74 -0
  5. {python_gitea-0.9.0 → python_gitea-0.10.1}/PKG-INFO +1 -1
  6. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/dev/architecture.md +6 -1
  7. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/user-guide/cli.md +156 -11
  8. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/user-guide/python-api.md +69 -0
  9. {python_gitea-0.9.0 → python_gitea-0.10.1}/mkdocs.yml +5 -0
  10. {python_gitea-0.9.0 → python_gitea-0.10.1}/pyproject.toml +34 -1
  11. python_gitea-0.10.1/src/gitea/cli/issue/close.py +106 -0
  12. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/get.py +11 -22
  13. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/main.py +2 -0
  14. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/main.py +4 -0
  15. python_gitea-0.10.1/src/gitea/cli/organization/__init__.py +1 -0
  16. python_gitea-0.10.1/src/gitea/cli/organization/list.py +88 -0
  17. python_gitea-0.10.1/src/gitea/cli/organization/main.py +21 -0
  18. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/issue/add.py +6 -0
  19. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/issue/move.py +23 -12
  20. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/main.py +14 -2
  21. python_gitea-0.10.1/src/gitea/cli/project/show.py +147 -0
  22. python_gitea-0.10.1/src/gitea/cli/repository/__init__.py +1 -0
  23. python_gitea-0.10.1/src/gitea/cli/repository/list.py +115 -0
  24. python_gitea-0.10.1/src/gitea/cli/repository/main.py +21 -0
  25. python_gitea-0.10.1/src/gitea/cli/utils/issue.py +878 -0
  26. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/client/async_gitea.py +2 -0
  27. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/client/gitea.py +2 -0
  28. python_gitea-0.10.1/src/gitea/issue/__init__.py +25 -0
  29. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/issue/project_column.py +109 -26
  30. python_gitea-0.10.1/src/gitea/organization/__init__.py +8 -0
  31. python_gitea-0.10.1/src/gitea/organization/async_organization.py +69 -0
  32. python_gitea-0.10.1/src/gitea/organization/base.py +60 -0
  33. python_gitea-0.10.1/src/gitea/organization/organization.py +69 -0
  34. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/project/async_project.py +13 -4
  35. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/project/project.py +13 -4
  36. python_gitea-0.10.1/src/gitea/utils/fields.py +200 -0
  37. python_gitea-0.10.1/src/gitea/utils/pagination.py +323 -0
  38. python_gitea-0.10.1/tests/cli/issue/test_cli_issue_close.py +191 -0
  39. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/test_cli_issue_get.py +21 -22
  40. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/notification/test_cli_notification.py +1 -1
  41. python_gitea-0.10.1/tests/cli/organization/__init__.py +1 -0
  42. python_gitea-0.10.1/tests/cli/organization/test_cli_organization_list.py +144 -0
  43. python_gitea-0.10.1/tests/cli/organization/test_cli_organization_main.py +24 -0
  44. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/project/test_cli_project.py +690 -4
  45. python_gitea-0.10.1/tests/cli/project/test_cli_project_show.py +367 -0
  46. python_gitea-0.10.1/tests/cli/repository/__init__.py +1 -0
  47. python_gitea-0.10.1/tests/cli/repository/test_cli_repository_list.py +267 -0
  48. python_gitea-0.10.1/tests/cli/repository/test_cli_repository_main.py +24 -0
  49. python_gitea-0.10.1/tests/cli/test_cli_contract.py +651 -0
  50. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/test_cli_main.py +77 -44
  51. python_gitea-0.10.1/tests/cli/tree.py +46 -0
  52. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/watch/test_cli_watch_list.py +94 -1
  53. python_gitea-0.10.1/tests/organization/__init__.py +1 -0
  54. python_gitea-0.10.1/tests/organization/test_organization_async_organization.py +120 -0
  55. python_gitea-0.10.1/tests/organization/test_organization_base.py +66 -0
  56. python_gitea-0.10.1/tests/organization/test_organization_organization.py +109 -0
  57. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/project/test_project_project.py +61 -0
  58. python_gitea-0.10.1/tests/project/test_project_requests.py +391 -0
  59. python_gitea-0.10.1/tests/test_version.py +72 -0
  60. python_gitea-0.10.1/tests/transport.py +289 -0
  61. python_gitea-0.10.1/tests/utils/test_utils_fields.py +270 -0
  62. python_gitea-0.10.1/tests/utils/test_utils_pagination.py +542 -0
  63. {python_gitea-0.9.0 → python_gitea-0.10.1}/uv.lock +234 -19
  64. python_gitea-0.9.0/src/gitea/cli/utils/issue.py +0 -253
  65. python_gitea-0.9.0/src/gitea/issue/__init__.py +0 -9
  66. python_gitea-0.9.0/src/gitea/utils/pagination.py +0 -100
  67. python_gitea-0.9.0/tests/cli/transport.py +0 -105
  68. python_gitea-0.9.0/tests/test_version.py +0 -32
  69. python_gitea-0.9.0/tests/utils/test_utils_pagination.py +0 -139
  70. {python_gitea-0.9.0 → python_gitea-0.10.1}/.coderabbit.yaml +0 -0
  71. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  72. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  73. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
  74. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/pull_request_template.md +0 -0
  75. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/ci.yml +0 -0
  76. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/codeql.yml +0 -0
  77. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/documentation.yml +0 -0
  78. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/draft_release.yml +0 -0
  79. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/publish.yml +0 -0
  80. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/publish_testpypi.yml +0 -0
  81. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/release.yml +0 -0
  82. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/scheduled_release.yml +0 -0
  83. {python_gitea-0.9.0 → python_gitea-0.10.1}/.github/workflows/semantic_pull_request.yml +0 -0
  84. {python_gitea-0.9.0 → python_gitea-0.10.1}/.markdownlint.yaml +0 -0
  85. {python_gitea-0.9.0 → python_gitea-0.10.1}/.prettierrc +0 -0
  86. {python_gitea-0.9.0 → python_gitea-0.10.1}/.pypirc +0 -0
  87. {python_gitea-0.9.0 → python_gitea-0.10.1}/.typos.toml +0 -0
  88. {python_gitea-0.9.0 → python_gitea-0.10.1}/CITATION.cff +0 -0
  89. {python_gitea-0.9.0 → python_gitea-0.10.1}/CODE_OF_CONDUCT.md +0 -0
  90. {python_gitea-0.9.0 → python_gitea-0.10.1}/LICENSE +0 -0
  91. {python_gitea-0.9.0 → python_gitea-0.10.1}/README.md +0 -0
  92. {python_gitea-0.9.0 → python_gitea-0.10.1}/SECURITY.md +0 -0
  93. {python_gitea-0.9.0 → python_gitea-0.10.1}/SUPPORT.md +0 -0
  94. {python_gitea-0.9.0 → python_gitea-0.10.1}/cliff.toml +0 -0
  95. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/contributing.md +0 -0
  96. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/dev/troubleshooting.md +0 -0
  97. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/gen_ref_pages.py +0 -0
  98. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/index.md +0 -0
  99. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/javascripts/mathjax.js +0 -0
  100. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/security.md +0 -0
  101. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/style/api.css +0 -0
  102. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/user-guide/configuration.md +0 -0
  103. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/user-guide/installation.md +0 -0
  104. {python_gitea-0.9.0 → python_gitea-0.10.1}/docs/user-guide/quickstart.md +0 -0
  105. {python_gitea-0.9.0 → python_gitea-0.10.1}/renovate.json +0 -0
  106. {python_gitea-0.9.0 → python_gitea-0.10.1}/scripts/release_version.py +0 -0
  107. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/__init__.py +0 -0
  108. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/__main__.py +0 -0
  109. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/__init__.py +0 -0
  110. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/comment/__init__.py +0 -0
  111. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/comment/add.py +0 -0
  112. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/comment/delete.py +0 -0
  113. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/comment/edit.py +0 -0
  114. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/comment/list.py +0 -0
  115. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/comment/main.py +0 -0
  116. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/config/__init__.py +0 -0
  117. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/config/add.py +0 -0
  118. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/config/delete.py +0 -0
  119. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/config/list.py +0 -0
  120. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/config/main.py +0 -0
  121. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/config/update.py +0 -0
  122. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/__init__.py +0 -0
  123. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/create.py +0 -0
  124. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/dependency/__init__.py +0 -0
  125. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/dependency/add.py +0 -0
  126. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/dependency/list.py +0 -0
  127. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/dependency/main.py +0 -0
  128. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/dependency/remove.py +0 -0
  129. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/edit.py +0 -0
  130. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/issue/list.py +0 -0
  131. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/label/__init__.py +0 -0
  132. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/label/create.py +0 -0
  133. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/label/delete.py +0 -0
  134. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/label/list.py +0 -0
  135. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/label/main.py +0 -0
  136. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/label/update.py +0 -0
  137. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/milestone/__init__.py +0 -0
  138. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/milestone/create.py +0 -0
  139. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/milestone/list.py +0 -0
  140. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/milestone/main.py +0 -0
  141. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/notification/__init__.py +0 -0
  142. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/notification/list.py +0 -0
  143. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/notification/main.py +0 -0
  144. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/notification/read.py +0 -0
  145. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/output.py +0 -0
  146. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/__init__.py +0 -0
  147. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/column/__init__.py +0 -0
  148. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/column/create.py +0 -0
  149. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/column/issues.py +0 -0
  150. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/column/list.py +0 -0
  151. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/create.py +0 -0
  152. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/delete.py +0 -0
  153. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/edit.py +0 -0
  154. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/get.py +0 -0
  155. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/issue/__init__.py +0 -0
  156. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/issue/remove.py +0 -0
  157. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/issues.py +0 -0
  158. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/project/list.py +0 -0
  159. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/pull_request/__init__.py +0 -0
  160. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/pull_request/list.py +0 -0
  161. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/pull_request/main.py +0 -0
  162. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/user/__init__.py +0 -0
  163. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/user/get.py +0 -0
  164. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/user/main.py +0 -0
  165. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/user/update_settings.py +0 -0
  166. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/utils/__init__.py +0 -0
  167. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/utils/api.py +0 -0
  168. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/utils/auth.py +0 -0
  169. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/utils/convert.py +0 -0
  170. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/utils/errors.py +0 -0
  171. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/utils/options.py +0 -0
  172. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/watch/__init__.py +0 -0
  173. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/watch/list.py +0 -0
  174. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/cli/watch/main.py +0 -0
  175. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/client/__init__.py +0 -0
  176. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/client/base.py +0 -0
  177. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/comment/__init__.py +0 -0
  178. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/comment/async_comment.py +0 -0
  179. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/comment/base.py +0 -0
  180. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/comment/comment.py +0 -0
  181. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/config/__init__.py +0 -0
  182. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/config/manager.py +0 -0
  183. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/config/model.py +0 -0
  184. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/issue/async_issue.py +0 -0
  185. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/issue/base.py +0 -0
  186. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/issue/issue.py +0 -0
  187. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/label/__init__.py +0 -0
  188. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/label/async_label.py +0 -0
  189. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/label/base.py +0 -0
  190. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/label/label.py +0 -0
  191. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/milestone/__init__.py +0 -0
  192. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/milestone/async_milestone.py +0 -0
  193. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/milestone/base.py +0 -0
  194. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/milestone/milestone.py +0 -0
  195. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/notification/__init__.py +0 -0
  196. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/notification/async_notification.py +0 -0
  197. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/notification/base.py +0 -0
  198. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/notification/notification.py +0 -0
  199. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/project/__init__.py +0 -0
  200. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/project/base.py +0 -0
  201. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/pull_request/__init__.py +0 -0
  202. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/pull_request/async_pull_request.py +0 -0
  203. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/pull_request/base.py +0 -0
  204. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/pull_request/pull_request.py +0 -0
  205. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/repository/__init__.py +0 -0
  206. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/repository/async_repository.py +0 -0
  207. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/repository/base.py +0 -0
  208. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/repository/repository.py +0 -0
  209. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/resource/__init__.py +0 -0
  210. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/resource/async_resource.py +0 -0
  211. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/resource/resource.py +0 -0
  212. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/user/__init__.py +0 -0
  213. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/user/async_user.py +0 -0
  214. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/user/base.py +0 -0
  215. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/user/user.py +0 -0
  216. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/utils/__init__.py +0 -0
  217. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/utils/log.py +0 -0
  218. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/utils/response.py +0 -0
  219. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/version.py +0 -0
  220. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/watch/__init__.py +0 -0
  221. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/watch/changes.py +0 -0
  222. {python_gitea-0.9.0 → python_gitea-0.10.1}/src/gitea/watch/state.py +0 -0
  223. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/__init__.py +0 -0
  224. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/board.py +0 -0
  225. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/__init__.py +0 -0
  226. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/comment/__init__.py +0 -0
  227. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/comment/test_cli_comment_add.py +0 -0
  228. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/comment/test_cli_comment_delete.py +0 -0
  229. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/comment/test_cli_comment_edit.py +0 -0
  230. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/comment/test_cli_comment_list.py +0 -0
  231. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/comment/test_cli_comment_main.py +0 -0
  232. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/config/__init__.py +0 -0
  233. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/config/test_cli_config_add.py +0 -0
  234. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/config/test_cli_config_delete.py +0 -0
  235. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/config/test_cli_config_list.py +0 -0
  236. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/config/test_cli_config_main.py +0 -0
  237. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/config/test_cli_config_update.py +0 -0
  238. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/envelope.py +0 -0
  239. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/__init__.py +0 -0
  240. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/dependency/__init__.py +0 -0
  241. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/dependency/test_cli_issue_dependency.py +0 -0
  242. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/test_cli_issue_comment.py +0 -0
  243. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/test_cli_issue_create.py +0 -0
  244. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/test_cli_issue_edit.py +0 -0
  245. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/test_cli_issue_list.py +0 -0
  246. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/issue/test_cli_issue_main.py +0 -0
  247. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/label/__init__.py +0 -0
  248. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/label/test_cli_label_create.py +0 -0
  249. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/label/test_cli_label_delete.py +0 -0
  250. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/label/test_cli_label_list.py +0 -0
  251. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/label/test_cli_label_main.py +0 -0
  252. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/label/test_cli_label_update.py +0 -0
  253. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/milestone/__init__.py +0 -0
  254. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/milestone/test_cli_milestone_create.py +0 -0
  255. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/milestone/test_cli_milestone_list.py +0 -0
  256. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/milestone/test_cli_milestone_main.py +0 -0
  257. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/notification/__init__.py +0 -0
  258. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/project/__init__.py +0 -0
  259. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/project/test_cli_project_column_issues.py +0 -0
  260. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/pull_request/__init__.py +0 -0
  261. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/pull_request/test_cli_pull_request_list.py +0 -0
  262. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/pull_request/test_cli_pull_request_main.py +0 -0
  263. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/rendering.py +0 -0
  264. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/test_cli_output.py +0 -0
  265. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/user/__init__.py +0 -0
  266. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/user/test_cli_user_get.py +0 -0
  267. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/user/test_cli_user_update_settings.py +0 -0
  268. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/utils/__init__.py +0 -0
  269. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/utils/test_cli_utils_api.py +0 -0
  270. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/utils/test_cli_utils_auth.py +0 -0
  271. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/utils/test_cli_utils_convert.py +0 -0
  272. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/utils/test_cli_utils_errors.py +0 -0
  273. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/utils/test_cli_utils_issue.py +0 -0
  274. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/utils/test_cli_utils_options.py +0 -0
  275. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/cli/watch/__init__.py +0 -0
  276. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/client/__init__.py +0 -0
  277. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/client/test_client_async_gitea.py +0 -0
  278. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/client/test_client_base.py +0 -0
  279. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/client/test_client_gitea.py +0 -0
  280. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/comment/__init__.py +0 -0
  281. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/comment/test_comment_async_comment.py +0 -0
  282. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/comment/test_comment_base.py +0 -0
  283. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/comment/test_comment_comment.py +0 -0
  284. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/config/__init__.py +0 -0
  285. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/config/test_config_manager.py +0 -0
  286. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/config/test_config_model.py +0 -0
  287. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/conftest.py +0 -0
  288. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/issue/__init__.py +0 -0
  289. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/issue/test_issue_async_issue.py +0 -0
  290. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/issue/test_issue_async_project_column.py +0 -0
  291. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/issue/test_issue_base.py +0 -0
  292. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/issue/test_issue_dependencies.py +0 -0
  293. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/issue/test_issue_issue.py +0 -0
  294. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/issue/test_issue_project_column.py +0 -0
  295. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/label/__init__.py +0 -0
  296. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/label/test_label_async_label.py +0 -0
  297. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/label/test_label_base.py +0 -0
  298. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/label/test_label_label.py +0 -0
  299. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/milestone/__init__.py +0 -0
  300. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/milestone/test_milestone_async_milestone.py +0 -0
  301. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/milestone/test_milestone_base.py +0 -0
  302. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/milestone/test_milestone_milestone.py +0 -0
  303. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/notification/__init__.py +0 -0
  304. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/notification/test_notification_base.py +0 -0
  305. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/notification/test_notification_notification.py +0 -0
  306. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/project/__init__.py +0 -0
  307. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/project/test_project_base.py +0 -0
  308. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/pull_request/__init__.py +0 -0
  309. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/pull_request/test_pull_request_async_pull_request.py +0 -0
  310. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/pull_request/test_pull_request_base.py +0 -0
  311. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/pull_request/test_pull_request_pull_request.py +0 -0
  312. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/repository/__init__.py +0 -0
  313. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/repository/test_repository_async_repository.py +0 -0
  314. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/repository/test_repository_base.py +0 -0
  315. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/repository/test_repository_repository.py +0 -0
  316. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/resource/__init__.py +0 -0
  317. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/resource/test_resource_async_resource.py +0 -0
  318. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/resource/test_resource_resource.py +0 -0
  319. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/smoke_test.py +0 -0
  320. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/test_import.py +0 -0
  321. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/test_main.py +0 -0
  322. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/test_release_version.py +0 -0
  323. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/user/__init__.py +0 -0
  324. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/user/test_user_async_user.py +0 -0
  325. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/user/test_user_base.py +0 -0
  326. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/user/test_user_user.py +0 -0
  327. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/utils/__init__.py +0 -0
  328. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/utils/test_utils_log.py +0 -0
  329. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/utils/test_utils_response.py +0 -0
  330. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/watch/__init__.py +0 -0
  331. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/watch/test_watch_changes.py +0 -0
  332. {python_gitea-0.9.0 → python_gitea-0.10.1}/tests/watch/test_watch_state.py +0 -0
@@ -22,7 +22,7 @@ jobs:
22
22
 
23
23
  - name: Apply support policy (spec0, from pyproject tool table)
24
24
  id: policy
25
- uses: isaac-cf-wong/dependency-support-policy-action@7cce60e19b902747b4267c4f8e53820e3f3656ea # v0.2.4
25
+ uses: isaac-cf-wong/dependency-support-policy-action@c00466ca1b1d902260e56e087c072cbb41ac038b # v0.2.5
26
26
  with:
27
27
  mode: update
28
28
 
@@ -133,3 +133,7 @@ dmypy.json
133
133
 
134
134
  # Node.js
135
135
  node_modules/
136
+
137
+ # mutmut
138
+ /mutants/
139
+ /.mutmut-cache
@@ -16,7 +16,7 @@ repos:
16
16
  - id: check-json
17
17
 
18
18
  - repo: https://github.com/astral-sh/ruff-pre-commit
19
- rev: v0.16.3
19
+ rev: v0.16.4
20
20
  hooks:
21
21
  - id: ruff
22
22
  args: [--fix, --config=pyproject.toml]
@@ -81,6 +81,80 @@ submitting a pull request—this guide will help you get started.
81
81
  pytest
82
82
  ```
83
83
 
84
+ Mutation testing runs the suite again for each deliberate alteration of the
85
+ source, and reports the alterations no test noticed:
86
+
87
+ ```shell
88
+ uv run mutmut run # every module
89
+ uv run mutmut run "gitea.cli.*" # one subtree, while iterating
90
+ uv run mutmut results # what survived
91
+ ```
92
+
93
+ A survivor is a change to the code that every test tolerated. Some cannot be
94
+ killed - a rewritten `typing.cast`, or anything in a `register_commands()`
95
+ that runs at import time - so read the diff `uv run mutmut show <mutant>`
96
+ prints before writing a test for one.
97
+
98
+ A filter selects which mutants are _run_, not which are written: every module
99
+ is mutated either way, so a scoped run still reports mutating the whole tree
100
+ and its progress counter reads `46/9042`, where the denominator counts every
101
+ mutant written and the numerator counts the ones the filter selected and
102
+ checked. Take the result of a scoped run from `uv run mutmut results` rather
103
+ than from that counter: it lists every mutant that was not killed, labelling
104
+ each as `survived` or as `not checked`, and naming the module it belongs to,
105
+ so the survivors of a scope are the `survived` entries whose names begin with
106
+ it. A filter matching no mutant stops the run with an error instead of
107
+ quietly widening it, so a scoped run that gets as far as testing is one that
108
+ scoped.
109
+
110
+ That listing names no killed mutant, though, so it cannot say how large the
111
+ scope was or what share of it died. Both are recorded per module, in the
112
+ `.meta` file mutmut writes beside each mutated module, whose
113
+ `exit_code_by_key` maps every mutant to the exit code of the run that checked
114
+ it - `0` survived, `1` killed, `null` never checked. Counting those gives the
115
+ verdict of a scope, and shows the modules outside it untouched. Point it at
116
+ the package directory the scope sits in - every module in the tree has a
117
+ `.meta`, so pointing it at the whole of `src/gitea` prints a line per module:
118
+
119
+ ```shell
120
+ uv run python - <<'PY'
121
+ import collections, json, pathlib
122
+
123
+ status = {0: "survived", 1: "killed", 3: "killed", 5: "no tests", 33: "no tests", None: "not checked"}
124
+ for meta in sorted(pathlib.Path("mutants/src/gitea/project").glob("*.py.meta")):
125
+ codes = json.loads(meta.read_text())["exit_code_by_key"]
126
+ counts = collections.Counter(status.get(c, f"exit {c}") for c in codes.values())
127
+ if counts:
128
+ print(f"{meta.name:24} {dict(counts)}")
129
+ PY
130
+ ```
131
+
132
+ ```text
133
+ async_project.py.meta {'killed': 620, 'survived': 16}
134
+ base.py.meta {'not checked': 215}
135
+ project.py.meta {'killed': 620, 'survived': 16}
136
+ ```
137
+
138
+ That is the output of a run scoped to the two project resource modules: 636
139
+ mutants each, 1,240 of the 1,272 killed, and the 215 of a module outside the
140
+ scope sitting unchecked. Start from `rm -rf mutants` when a run has to stand
141
+ on its own, since the verdicts of one run are otherwise carried into the
142
+ next.
143
+
144
+ To scope what is _written_ as well, and get a counter whose denominator is
145
+ the scope, point `source_paths` at the modules and let `also_copy` carry the
146
+ rest of the package that the tests import. Scoped to the same two modules as
147
+ above, that run reports mutating two files and counts `1272/1272`:
148
+
149
+ ```toml
150
+ [tool.mutmut]
151
+ source_paths = [
152
+ "src/gitea/project/project.py",
153
+ "src/gitea/project/async_project.py",
154
+ ]
155
+ also_copy = ["scripts/", "src/"]
156
+ ```
157
+
84
158
  8. Open a Pull Request
85
159
 
86
160
  Clearly describe the motivation and scope of your change. Link it to the relevant issue if applicable.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: python-gitea
3
- Version: 0.9.0
3
+ Version: 0.10.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
@@ -44,6 +44,7 @@ src/gitea/
44
44
  ├── milestone/ # Milestone resource (sync + async)
45
45
  ├── notification/ # Notification resource (sync + async)
46
46
  ├── project/ # Project resource (sync + async)
47
+ ├── organization/ # Organization resource (sync + async)
47
48
  ├── cli/ # Typer CLI application
48
49
  │ ├── main.py # gitea-cli entry point, command registration
49
50
  │ ├── config/ # config commands
@@ -54,9 +55,12 @@ src/gitea/
54
55
  │ ├── milestone/ # milestone commands
55
56
  │ ├── notification/ # notification commands
56
57
  │ ├── project/ # project, column, and project-issue commands
58
+ │ ├── organization/ # org commands
59
+ │ ├── repository/ # repo commands
57
60
  │ ├── user/ # user commands
58
61
  │ └── utils/ # auth resolution, API helpers, conversions
59
- └── utils/ # Logging, pagination, and response helpers
62
+ └── utils/ # Logging, field names, pagination, and response helpers
63
+ ├── fields.py # Field-name convention and compatibility aliases
60
64
  ├── log.py # Logger setup
61
65
  ├── pagination.py # Paginated-listing walkers
62
66
  └── response.py # Response processing helpers
@@ -85,6 +89,7 @@ with Gitea(token="...", base_url="...") as client:
85
89
  client.milestone # Milestone
86
90
  client.notification # Notification
87
91
  client.project # Project
92
+ client.organization # Organization
88
93
  ```
89
94
 
90
95
  ## Resource Layer
@@ -65,7 +65,7 @@ command:
65
65
 
66
66
  - API commands report `status_code`.
67
67
  - Commands that page through the API add counts, such as `column_count` and
68
- `issue_count` for `project issues`.
68
+ `issue_count` for `project issues` and `project show`.
69
69
  - `config` commands report `config_path`.
70
70
  - It is `{}` when the command made no call at all.
71
71
 
@@ -81,10 +81,45 @@ failing over an enrichment of it.
81
81
 
82
82
  Tokens are never included in the output of `config` commands in either format.
83
83
 
84
+ ## Field names
85
+
86
+ Every field of `data` is named as the Gitea API names it. Nothing is renamed and
87
+ nothing is dropped on the way out, so a key can be looked up in
88
+ [Gitea's own API reference](https://docs.gitea.com/api/1.24/) rather than in
89
+ this CLI's source, and the same value never arrives under two names depending on
90
+ which command fetched it.
91
+
92
+ A field the API cannot send is added only where it carries something the API has
93
+ no way of saying, and is documented with the command that adds it: `column_id`
94
+ on the project entries of `issue get`, and `issue_count` and `issue_ids` on the
95
+ columns of `project show`, are the ones today. Such a field is never a second
96
+ name for a field already in the payload.
97
+
98
+ Two consequences worth knowing:
99
+
100
+ - A project column is `title`, not `name`:
101
+
102
+ ```console
103
+ $ gitea-cli --output json project column list --owner my-org --project-id 31
104
+ {
105
+ "data": [{ "id": 117, "title": "Working", "default": false, "sorting": 0, ... }],
106
+ "metadata": { "status_code": 200 }
107
+ }
108
+ ```
109
+
110
+ - A field whose name misleads is documented rather than renamed. `comments` on
111
+ an issue is the _number_ of comments; `gitea-cli issue comment list` reads the
112
+ bodies.
113
+
114
+ The Python client follows the same convention and additionally keeps a field
115
+ name callers already wrote readable as an alias - `column["name"]` reads the
116
+ title - which the [Python API guide](python-api.md#field-names) describes. An
117
+ alias is never emitted, so it cannot appear in the JSON above.
118
+
84
119
  ## Option naming
85
120
 
86
- Every resource command addresses its target the same way, so an invocation can
87
- be written without reading `--help` first:
121
+ Every command that addresses something an account owns names its target the same
122
+ way, so an invocation can be written without reading `--help` first:
88
123
 
89
124
  | Option | Meaning |
90
125
  | --------------- | -------------------------------------------------------- |
@@ -123,6 +158,16 @@ are required together because there is no scope for them to fall back to:
123
158
  neither `--owner` nor `--repository` it acts on the authenticated user's
124
159
  notifications, and the two must be passed together or not at all.
125
160
 
161
+ A command whose target is an account rather than something an account owns takes
162
+ no `--owner` at all, and names the account with `--username` instead: `org list`
163
+ lists an account's organizations and `user get` reads an account's profile, both
164
+ answering for the account the token belongs to when `--username` is omitted.
165
+
166
+ `repo list` is the one command where the _kind_ of owner matters: Gitea serves
167
+ an organization's repositories and a user's at different endpoints, so
168
+ `--owner-type` says which of the two `--owner` names. It defaults to
169
+ `organization`.
170
+
126
171
  ### Deprecated option names
127
172
 
128
173
  `--index` has been renamed to `--issue-id`, so that one option name means "which
@@ -169,9 +214,11 @@ endpoint to serve it with, so they answer by naming the option to pass.
169
214
  - Optional: `--state`, `--labels`, `--search-string`, `--created-by`,
170
215
  `--assigned-by`, `--since`, `--before`, `--page`, `--limit`
171
216
  - `gitea-cli issue get --owner <owner> --repository <repo> --issue-id <number>`
172
- - The `comment_count` field is the number of comments on the issue, not the
217
+ - The `comments` field is the number of comments on the issue, not the
173
218
  comments themselves; use `gitea-cli issue comment list` to read the
174
- bodies.
219
+ bodies. The field keeps the API's name, as
220
+ [the field-name convention](#field-names) requires: this command used to
221
+ rename it to `comment_count` and was alone in doing so.
175
222
  - Each entry of `projects` carries a `column_id`: the column the issue's
176
223
  card sits in, or `null` when the issue has no card on that project. Gitea
177
224
  does not report it on the issue itself, so it is resolved from each
@@ -187,6 +234,13 @@ endpoint to serve it with, so they answer by naming the option to pass.
187
234
  - `gitea-cli issue edit --owner <owner> --repository <repo> --issue-id <number>`
188
235
  - Optional: `--title`, `--body`, `--state`, `--assignees`, `--milestone`,
189
236
  `--due-date`
237
+ - `gitea-cli issue close --owner <owner> --repository <repo> --issue-id <number>`
238
+ - Optional: `--comment`
239
+ - Closes the issue, which `issue edit --state closed` also does; this is the
240
+ shorter way to say it and the one that takes a `--comment`.
241
+ - `--comment` posts that body on the issue after it is closed. The issue is
242
+ closed first, so a comment that is refused leaves the issue closed rather
243
+ than the close undone; the result is the closed issue either way.
190
244
  - `gitea-cli issue dependency add --owner <owner> --repository <repo> --issue-id <number>`
191
245
  - Required: `--dependency-owner <owner>`, `--dependency-repository <repo>`,
192
246
  `--dependency-issue-id <number>`
@@ -252,6 +306,8 @@ gitea-cli project list --owner my-org --repository my-repo # that repository's
252
306
  - Optional: `--description`, `--card-type`, `--template-type`
253
307
  - `gitea-cli project list --owner <owner> [--repository <repo>]`
254
308
  - `gitea-cli project get --owner <owner> [--repository <repo>] --project-id <id>`
309
+ - `gitea-cli project show --owner <owner> [--repository <repo>] --project-id <id>`
310
+ - Optional: `--full`
255
311
  - `gitea-cli project edit --owner <owner> [--repository <repo>] --project-id <id>`
256
312
  - Optional: `--title`, `--description`, `--state`, `--card-type`
257
313
  - `gitea-cli project delete --owner <owner> [--repository <repo>] --project-id <id>`
@@ -264,7 +320,11 @@ gitea-cli project list --owner my-org --repository my-repo # that repository's
264
320
  - `gitea-cli project issue add --owner <owner> [--repository <repo>] --project-id <id> --column-id <id> --issue-id <id>`
265
321
  - Optional: `--issue-repository`
266
322
  - `gitea-cli project issue move --owner <owner> [--repository <repo>] --project-id <id> --column-id <id> --issue-id <id>`
267
- - Optional: `--sorting`, `--issue-repository`
323
+ - Optional: `--sorting`, `--issue-repository`, `--add-if-missing`
324
+ - Moves the card the issue already has on the project, and confirms it
325
+ arrived in `--column-id`. An issue with no card there is reported as an
326
+ error naming `project issue add`; `--add-if-missing` has this command put
327
+ it in `--column-id` instead.
268
328
  - `gitea-cli project issue remove --owner <owner> [--repository <repo>] --project-id <id> --column-id <id> --issue-id <id>`
269
329
  - Optional: `--issue-repository`
270
330
 
@@ -282,6 +342,40 @@ for you:
282
342
  ID. `--issue-repository` also overrides `--repository`, for the case of a
283
343
  repository project holding an issue from elsewhere.
284
344
 
345
+ `add` and `move` are not two ways of doing the same thing. `add` puts an issue
346
+ on a board, giving it a card in a column; `move` relocates the card it already
347
+ has there, and an issue with no card has nothing to relocate. Gitea's move
348
+ endpoint does not say so - it moves the row relating the issue to the project,
349
+ of which there is none, and answers with a success and an empty body having
350
+ moved nothing - so the command finds the card first and reports its absence
351
+ itself:
352
+
353
+ ```console
354
+ $ gitea-cli project issue move --owner my-org --project-id 1 --column-id 2 \
355
+ --issue-repository my-repo --issue-id 42
356
+ No column of project 1 holds issue #42 of my-org/my-repo (global ID 1854), so there is
357
+ no card to move. [...] Put the issue on the board with 'gitea-cli project issue add
358
+ --owner my-org --project-id 1 --column-id 2 --issue-id 42 --issue-repository my-repo',
359
+ or pass --add-if-missing to have this command do that when there is no card yet.
360
+ ```
361
+
362
+ `--add-if-missing` makes the one call do either, which is what a script
363
+ advancing cards through columns wants: the card is moved when it exists and
364
+ created in `--column-id` when it does not. `--sorting` is refused on that second
365
+ path rather than dropped, since the endpoint putting a card on a board takes no
366
+ position within the column. A board that cannot be read is reported as such and
367
+ stops the move: a failed lookup is not evidence that the issue has no card.
368
+
369
+ Whichever call is made, `--column-id` is then read back, because the success the
370
+ endpoint answers with has already been shown not to mean the card went anywhere.
371
+ A zero exit status therefore says the card was seen in that column, rather than
372
+ that Gitea accepted a request to put it there - and the three ways that can fail
373
+ are reported apart: the issue has no card at all, the card is not in the column
374
+ it was sent to, or the reading back could not be done and it is unknown which.
375
+ It does not say the card is still there: the calls are separate requests, and
376
+ Gitea has no conditional move to make them one, so a card taken off the board
377
+ after the command read it is outside what any client can report on.
378
+
285
379
  The global ID the command used comes back as `metadata.resolved_issue_id`. A
286
380
  number the repository does not have, and a call the project endpoint refuses,
287
381
  are both reported as errors naming the issue and what to check - never as an
@@ -298,6 +392,31 @@ instance is down.
298
392
  - Optional: `--full-name`, `--website`, `--location`, `--language`,
299
393
  `--theme`, `--diff-view-style`, `--hide-email`, `--hide-activity`
300
394
 
395
+ ### Org - discover organizations
396
+
397
+ - `gitea-cli org list`
398
+ - Optional: `--username`, `--page`, `--limit`
399
+ - Lists the organizations of the account the token belongs to; `--username`
400
+ lists those of another account instead.
401
+ - Gitea also has a site-wide listing of every organization, which a token
402
+ that is not scoped for it is refused. This command does not read from it,
403
+ so it answers with the organizations of an account and never with the
404
+ instance's.
405
+
406
+ ### Repo - discover repositories
407
+
408
+ - `gitea-cli repo list --owner <owner>`
409
+ - Optional: `--owner-type`, `--page`, `--limit`
410
+ - `--owner-type` is `organization` (the default) or `user`: Gitea serves the
411
+ two at different endpoints - `/orgs/<owner>/repos` and
412
+ `/users/<owner>/repos` - and an owner's name does not say which of the two
413
+ it is.
414
+
415
+ ```bash
416
+ gitea-cli repo list --owner my-org # an organization's repositories
417
+ gitea-cli repo list --owner alice --owner-type user # a user's repositories
418
+ ```
419
+
301
420
  ### Watch - report what changed since the last run
302
421
 
303
422
  Every other command answers a question about the instance now. `watch` answers
@@ -446,8 +565,8 @@ gitea-cli issue create \
446
565
  --milestone 3
447
566
  ```
448
567
 
449
- Move an issue into a project column, addressing it by the number shown in the
450
- web UI:
568
+ Put an issue on a project board, in a column of it, addressing the issue by the
569
+ number shown in the web UI:
451
570
 
452
571
  ```bash
453
572
  gitea-cli project issue add \
@@ -458,8 +577,9 @@ gitea-cli project issue add \
458
577
  --issue-id 42
459
578
  ```
460
579
 
461
- Move `my-repo#42` on an organization project, where the repository holding the
462
- issue has to be named separately:
580
+ Move the card of `my-repo#42` on an organization project, where the repository
581
+ holding the issue has to be named separately, and put it on the board if it is
582
+ not there yet:
463
583
 
464
584
  ```bash
465
585
  gitea-cli project issue move \
@@ -467,7 +587,8 @@ gitea-cli project issue move \
467
587
  --project-id 1 \
468
588
  --column-id 2 \
469
589
  --issue-repository my-repo \
470
- --issue-id 42
590
+ --issue-id 42 \
591
+ --add-if-missing
471
592
  ```
472
593
 
473
594
  List the issues sitting in one column of an organization project (omit
@@ -486,6 +607,30 @@ Show every card on a project together with the column it is in:
486
607
  gitea-cli project issues --owner my-org --project-id 1
487
608
  ```
488
609
 
610
+ Read a board's shape in one call - the project, its columns, and how many cards
611
+ sit in each of them. `project get` answers with the project alone, which says
612
+ nothing about where the cards are:
613
+
614
+ ```console
615
+ $ gitea-cli --output json project show --owner my-org --project-id 31
616
+ {
617
+ "data": {
618
+ "project": { "id": 31, "title": "Board", "state": "open", ... },
619
+ "columns": [
620
+ { "id": 117, "title": "Working", ..., "issue_count": 2, "issue_ids": [1873, 1874] }
621
+ ]
622
+ },
623
+ "metadata": { "status_code": 200, "column_count": 1, "issue_count": 2 }
624
+ }
625
+ ```
626
+
627
+ Each column is the columns endpoint's own object with `issue_count` and
628
+ `issue_ids` added to it, and `issue_ids` holds the global issue IDs the project
629
+ endpoints take - `--issue-id` without `--issue-repository`. Add `--full` to have
630
+ each column carry its issues themselves, under `issues`, rather than their IDs
631
+ alone. Every page of columns, and of each column's issues, is walked, so the
632
+ counts describe the whole board.
633
+
489
634
  Report what changed across two repositories and a board since the last run,
490
635
  quietly enough to be worth a `cron` entry:
491
636
 
@@ -90,6 +90,38 @@ Both are best-effort, and `column_id` should be read with that in mind:
90
90
  - The columns of a user-owned (individual) project live under endpoints this
91
91
  library does not wrap, so such a project's `column_id` is always `None`.
92
92
 
93
+ That last point is about the enrichment and not about the walk itself.
94
+ `find_card_column_id` is the walk on its own — one project, one issue, the
95
+ column holding its card or `None` when no column of the board lists it — and it
96
+ raises what the lookup raised rather than logging it, for a caller that has to
97
+ tell "no card" apart from "could not be read":
98
+
99
+ ```python
100
+ from gitea.client.gitea import Gitea
101
+ from gitea.issue import find_card_column_id
102
+
103
+ with Gitea(token="TOKEN", base_url="https://gitea.example.com") as client:
104
+ column_id = find_card_column_id(
105
+ client=client,
106
+ owner="my-org",
107
+ repository=None, # the organization's own project; a repository's names it
108
+ project_id=1,
109
+ issue_id=1854, # the global ID, which is what the columns list their issues by
110
+ )
111
+ print("not on the board" if column_id is None else column_id)
112
+ ```
113
+
114
+ `find_async_card_column_id` is its `await`-based twin. Asking this before moving
115
+ a card is what `gitea-cli project issue move` does: Gitea's move endpoint moves
116
+ the row relating an issue to a project, and for an issue that is not on the
117
+ project there is none to move, so the call comes back a success having done
118
+ nothing.
119
+
120
+ `column_holds_card` is the same question about a single named column, at the
121
+ cost of that column's listing rather than the board's — which is what the walk
122
+ above asks per column, and what the same command asks again after the move to
123
+ confirm the card arrived. `async_column_holds_card` is its `await`-based twin.
124
+
93
125
  ## Asynchronous Client
94
126
 
95
127
  The `AsyncGitea` client has the same structure but `await`-based, and it uses
@@ -126,12 +158,49 @@ is simpler and sufficient.
126
158
  | `client.milestone` | Milestones |
127
159
  | `client.notification` | Notifications |
128
160
  | `client.project` | Projects, columns, and project issues |
161
+ | `client.organization` | Organizations |
129
162
 
130
163
  Each resource is implemented in a synchronous class (e.g. `gitea.issue.Issue`)
131
164
  and an async class (e.g. `gitea.issue.AsyncIssue`); some modules re-export them
132
165
  from the package `__init__` (e.g. `from gitea.issue import Issue`). See the
133
166
  [API Reference](../reference/index.md) for the full method list and signatures.
134
167
 
168
+ ## Field Names
169
+
170
+ A payload returned by a client method is the JSON the Gitea API sent, keyed as
171
+ the API keys it. Nothing is renamed and nothing is dropped, in the client
172
+ dictionaries and in [the CLI's JSON envelope](cli.md#field-names) alike, so a
173
+ key is looked up in Gitea's API reference and not in this library's source.
174
+
175
+ A project column is therefore `title`:
176
+
177
+ ```python
178
+ columns, _ = client.project.list_project_columns(owner="my-org", repository=None, project_id=31)
179
+ print(columns[0]["title"]) # 'Working'
180
+ ```
181
+
182
+ `name` reads it too. It is an alias, not a second key: reading a payload by it
183
+ works, and enumerating or serializing the payload sees `title` alone, so nothing
184
+ downstream can come to depend on a name the API does not use.
185
+
186
+ ```python
187
+ column = columns[0]
188
+ column["name"] # 'Working' - reads the title
189
+ column.get("name") # 'Working'
190
+ "name" in column # True
191
+ list(column) # ['id', 'title', 'default', 'sorting', ...] - no 'name'
192
+ json.dumps(column) # {"id": 117, "title": "Working", ...} - no 'name'
193
+ ```
194
+
195
+ Only reading is widened. `column["name"] = x` writes a field called `name`, as
196
+ it would on any dictionary, rather than changing the title through a name Gitea
197
+ does not use.
198
+
199
+ `gitea.utils.fields` holds the convention itself, the record types declaring the
200
+ aliases of a resource, and the bar an alias has to clear to be added: a name
201
+ callers have written, not a name that reads well. Today there is one, `name` on
202
+ a project column.
203
+
135
204
  ## Detecting What Changed
136
205
 
137
206
  `gitea.watch` is not a resource: it holds the change detection that
@@ -132,6 +132,11 @@ nav:
132
132
  - Overview: reference/gitea/project/index.md
133
133
  - Project: reference/gitea/project/project.md
134
134
  - Async Project: reference/gitea/project/async_project.md
135
+ - Organization:
136
+ - Overview: reference/gitea/organization/index.md
137
+ - Organization: reference/gitea/organization/organization.md
138
+ - Async Organization:
139
+ reference/gitea/organization/async_organization.md
135
140
  - User:
136
141
  - Overview: reference/gitea/user/index.md
137
142
  - User: reference/gitea/user/user.md
@@ -30,7 +30,12 @@ dependencies = [
30
30
  [dependency-groups]
31
31
  dev = [
32
32
  "ruff>=0.16.3",
33
- "prek>=0.4.13",
33
+ # The mutation runner, in the environment `uv run` resolves, so that
34
+ # `uv run mutmut run` reaches the same interpreter as `uv run pytest` and finds
35
+ # the pytest plugins the suite's own options need. Run from a tool environment
36
+ # of its own it cannot read `--cov`, and the run dies at collection.
37
+ "mutmut>=3.7.0",
38
+ "prek>=0.4.14",
34
39
  "pytest-github-actions-annotate-failures>=0.4.2",
35
40
  "pytest-cov>=7.1.0",
36
41
  "pytest-mock>=3.15.1",
@@ -75,6 +80,34 @@ source = "vcs"
75
80
  [tool.hatch.build.targets.wheel]
76
81
  packages = ["src/gitea"]
77
82
 
83
+ [tool.mutmut]
84
+ # The suite imports from `scripts/` (see `pythonpath` under
85
+ # `[tool.pytest.ini_options]`), so the copy of the tree that mutmut runs it from
86
+ # needs that directory as well - without it every mutant is reported as killed by
87
+ # a collection error in `tests/test_release_version.py`.
88
+ source_paths = ["src/gitea/"]
89
+ also_copy = ["scripts/"]
90
+ # mutmut runs the suite against a rewritten copy of each module, in which every
91
+ # mutated function is replaced by a table of its variants. A test reading a module
92
+ # rather than calling it therefore reads the instrumentation rather than the code,
93
+ # and fails for every mutant - a red baseline, which reports every mutant as
94
+ # killed. Two do: one asserts on the *text* of a module, the other enumerates the
95
+ # methods of a class, which the variants are bound to as members of. Both are
96
+ # deselected here, and are run by `pytest` as usual.
97
+ pytest_add_cli_args = [
98
+ "--deselect",
99
+ "tests/utils/test_utils_pagination.py::TestEndOfListing::test_the_walkers_decide_nothing_of_their_own",
100
+ "--deselect",
101
+ "tests/project/test_project_requests.py::test_every_project_method_is_declared",
102
+ ]
103
+ # A mutant is judged to hang when its tests exceed `timeout_multiplier` times what
104
+ # they took clean, plus this constant. Most tests here take a millisecond or two,
105
+ # so the default constant of one second leaves a budget an unmutated run can miss
106
+ # on a loaded machine - and a mutant reported as a timeout has no verdict at all:
107
+ # it is not known to be caught, and it is not reported as surviving either. Ten
108
+ # seconds is still far below anything a real hang would finish in.
109
+ timeout_constant = 10.0
110
+
78
111
  [tool.coverage.run]
79
112
  branch = true
80
113
 
@@ -0,0 +1,106 @@
1
+ """Close issues command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from gitea.cli.utils.options import DEPRECATED_INDEX_HELP, ISSUE_ID_HELP, REPOSITORY_REQUIRED_HELP
10
+
11
+
12
+ def close_command(
13
+ ctx: typer.Context,
14
+ owner: Annotated[str, typer.Option("--owner", help="Owner of the repository.")],
15
+ repository: Annotated[str | None, typer.Option("--repository", help=REPOSITORY_REQUIRED_HELP)] = None,
16
+ issue_id: Annotated[int | None, typer.Option("--issue-id", help=ISSUE_ID_HELP)] = None,
17
+ index: Annotated[int | None, typer.Option("--index", help=DEPRECATED_INDEX_HELP, hidden=True)] = None,
18
+ comment: Annotated[
19
+ str | None,
20
+ typer.Option("--comment", help="Body of a comment to post on the issue as it is closed."),
21
+ ] = None,
22
+ account_name: Annotated[
23
+ str | None,
24
+ typer.Option(
25
+ "--account-name",
26
+ help="Name of the account to use for authentication.",
27
+ ),
28
+ ] = None,
29
+ token: Annotated[
30
+ str | None,
31
+ typer.Option(
32
+ "--token",
33
+ help="Token for authentication. If not provided, the token from the specified account will be used.",
34
+ ),
35
+ ] = None,
36
+ base_url: Annotated[
37
+ str | None,
38
+ typer.Option(
39
+ "--base-url",
40
+ help="Base URL of the Gitea platform. If not provided, the base URL from the specified account will be used.",
41
+ ),
42
+ ] = None,
43
+ ) -> None:
44
+ """Close an issue in a repository.
45
+
46
+ Args:
47
+ ctx: The Typer context.
48
+ owner: The owner of the repository.
49
+ repository: The name of the repository, which this command requires.
50
+ issue_id: The issue number shown in the web UI.
51
+ index: The deprecated name of `issue_id`.
52
+ comment: The body of a comment to post on the issue as it is closed. No
53
+ comment is posted when it is omitted.
54
+ account_name: Name of the account to use for authentication.
55
+ token: Token for authentication. If not provided, the token from the specified account will be used.
56
+ base_url: Base URL of the Gitea platform. If not provided, the base URL from the specified account will be used.
57
+
58
+ """
59
+ from typing import Any # noqa: PLC0415
60
+
61
+ from gitea.cli.utils.api import execute_api_command # noqa: PLC0415
62
+ from gitea.cli.utils.auth import get_auth_params # noqa: PLC0415
63
+ from gitea.cli.utils.options import require_repository, resolve_issue_id # noqa: PLC0415
64
+ from gitea.client.gitea import Gitea # noqa: PLC0415
65
+
66
+ token, base_url = get_auth_params(
67
+ config_path=ctx.obj.get("config_path"),
68
+ account_name=account_name,
69
+ token=token,
70
+ base_url=base_url,
71
+ )
72
+
73
+ def api_call() -> tuple[dict[str, Any] | list[dict[str, Any]], dict[str, Any]]:
74
+ """Close the issue, and comment on it when a comment was given.
75
+
76
+ The issue is closed before the comment is posted, so a comment that
77
+ cannot be posted leaves the issue closed rather than leaving the close
78
+ undone. The result is the closed issue: the comment is what the command
79
+ does on the way past, not what it was asked for.
80
+
81
+ Returns:
82
+ A tuple containing the issue data and metadata.
83
+
84
+ """
85
+ target_repository = require_repository(repository, command="gitea-cli issue close")
86
+ target_issue = resolve_issue_id(issue_id=issue_id, index=index, command="gitea-cli issue close")
87
+
88
+ with Gitea(token=token, base_url=base_url) as client:
89
+ closed = client.issue.edit_issue(
90
+ owner=owner,
91
+ repository=target_repository,
92
+ index=target_issue,
93
+ state="closed",
94
+ )
95
+
96
+ if comment is not None:
97
+ client.comment.create_comment(
98
+ owner=owner,
99
+ repository=target_repository,
100
+ index=target_issue,
101
+ body=comment,
102
+ )
103
+
104
+ return closed
105
+
106
+ execute_api_command(api_call=api_call, base_url=base_url, command_name="gitea-cli issue close")