python-gitea 0.9.0__tar.gz → 0.10.0__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 (330) hide show
  1. {python_gitea-0.9.0 → python_gitea-0.10.0}/.gitignore +4 -0
  2. {python_gitea-0.9.0 → python_gitea-0.10.0}/CONTRIBUTING.md +74 -0
  3. {python_gitea-0.9.0 → python_gitea-0.10.0}/PKG-INFO +1 -1
  4. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/dev/architecture.md +6 -1
  5. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/user-guide/cli.md +110 -5
  6. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/user-guide/python-api.md +37 -0
  7. {python_gitea-0.9.0 → python_gitea-0.10.0}/mkdocs.yml +5 -0
  8. {python_gitea-0.9.0 → python_gitea-0.10.0}/pyproject.toml +33 -0
  9. python_gitea-0.10.0/src/gitea/cli/issue/close.py +106 -0
  10. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/get.py +11 -22
  11. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/main.py +2 -0
  12. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/main.py +4 -0
  13. python_gitea-0.10.0/src/gitea/cli/organization/__init__.py +1 -0
  14. python_gitea-0.10.0/src/gitea/cli/organization/list.py +88 -0
  15. python_gitea-0.10.0/src/gitea/cli/organization/main.py +21 -0
  16. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/main.py +2 -0
  17. python_gitea-0.10.0/src/gitea/cli/project/show.py +147 -0
  18. python_gitea-0.10.0/src/gitea/cli/repository/__init__.py +1 -0
  19. python_gitea-0.10.0/src/gitea/cli/repository/list.py +115 -0
  20. python_gitea-0.10.0/src/gitea/cli/repository/main.py +21 -0
  21. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/client/async_gitea.py +2 -0
  22. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/client/gitea.py +2 -0
  23. python_gitea-0.10.0/src/gitea/organization/__init__.py +8 -0
  24. python_gitea-0.10.0/src/gitea/organization/async_organization.py +69 -0
  25. python_gitea-0.10.0/src/gitea/organization/base.py +60 -0
  26. python_gitea-0.10.0/src/gitea/organization/organization.py +69 -0
  27. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/project/async_project.py +13 -4
  28. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/project/project.py +13 -4
  29. python_gitea-0.10.0/src/gitea/utils/fields.py +200 -0
  30. python_gitea-0.10.0/src/gitea/utils/pagination.py +323 -0
  31. python_gitea-0.10.0/tests/cli/issue/test_cli_issue_close.py +191 -0
  32. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/test_cli_issue_get.py +21 -22
  33. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/notification/test_cli_notification.py +1 -1
  34. python_gitea-0.10.0/tests/cli/organization/__init__.py +1 -0
  35. python_gitea-0.10.0/tests/cli/organization/test_cli_organization_list.py +144 -0
  36. python_gitea-0.10.0/tests/cli/organization/test_cli_organization_main.py +24 -0
  37. python_gitea-0.10.0/tests/cli/project/test_cli_project_show.py +367 -0
  38. python_gitea-0.10.0/tests/cli/repository/__init__.py +1 -0
  39. python_gitea-0.10.0/tests/cli/repository/test_cli_repository_list.py +267 -0
  40. python_gitea-0.10.0/tests/cli/repository/test_cli_repository_main.py +24 -0
  41. python_gitea-0.10.0/tests/cli/test_cli_contract.py +648 -0
  42. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/test_cli_main.py +13 -44
  43. python_gitea-0.10.0/tests/cli/tree.py +46 -0
  44. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/watch/test_cli_watch_list.py +94 -1
  45. python_gitea-0.10.0/tests/organization/__init__.py +1 -0
  46. python_gitea-0.10.0/tests/organization/test_organization_async_organization.py +120 -0
  47. python_gitea-0.10.0/tests/organization/test_organization_base.py +66 -0
  48. python_gitea-0.10.0/tests/organization/test_organization_organization.py +109 -0
  49. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/project/test_project_project.py +61 -0
  50. python_gitea-0.10.0/tests/project/test_project_requests.py +391 -0
  51. python_gitea-0.10.0/tests/test_version.py +72 -0
  52. python_gitea-0.10.0/tests/transport.py +289 -0
  53. python_gitea-0.10.0/tests/utils/test_utils_fields.py +270 -0
  54. python_gitea-0.10.0/tests/utils/test_utils_pagination.py +542 -0
  55. {python_gitea-0.9.0 → python_gitea-0.10.0}/uv.lock +215 -0
  56. python_gitea-0.9.0/src/gitea/utils/pagination.py +0 -100
  57. python_gitea-0.9.0/tests/cli/transport.py +0 -105
  58. python_gitea-0.9.0/tests/test_version.py +0 -32
  59. python_gitea-0.9.0/tests/utils/test_utils_pagination.py +0 -139
  60. {python_gitea-0.9.0 → python_gitea-0.10.0}/.coderabbit.yaml +0 -0
  61. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  62. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  63. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
  64. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/pull_request_template.md +0 -0
  65. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/ci.yml +0 -0
  66. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/codeql.yml +0 -0
  67. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/documentation.yml +0 -0
  68. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/draft_release.yml +0 -0
  69. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/publish.yml +0 -0
  70. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/publish_testpypi.yml +0 -0
  71. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/release.yml +0 -0
  72. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/scheduled_release.yml +0 -0
  73. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/semantic_pull_request.yml +0 -0
  74. {python_gitea-0.9.0 → python_gitea-0.10.0}/.github/workflows/support_floor_update.yml +0 -0
  75. {python_gitea-0.9.0 → python_gitea-0.10.0}/.markdownlint.yaml +0 -0
  76. {python_gitea-0.9.0 → python_gitea-0.10.0}/.pre-commit-config.yaml +0 -0
  77. {python_gitea-0.9.0 → python_gitea-0.10.0}/.prettierrc +0 -0
  78. {python_gitea-0.9.0 → python_gitea-0.10.0}/.pypirc +0 -0
  79. {python_gitea-0.9.0 → python_gitea-0.10.0}/.typos.toml +0 -0
  80. {python_gitea-0.9.0 → python_gitea-0.10.0}/CITATION.cff +0 -0
  81. {python_gitea-0.9.0 → python_gitea-0.10.0}/CODE_OF_CONDUCT.md +0 -0
  82. {python_gitea-0.9.0 → python_gitea-0.10.0}/LICENSE +0 -0
  83. {python_gitea-0.9.0 → python_gitea-0.10.0}/README.md +0 -0
  84. {python_gitea-0.9.0 → python_gitea-0.10.0}/SECURITY.md +0 -0
  85. {python_gitea-0.9.0 → python_gitea-0.10.0}/SUPPORT.md +0 -0
  86. {python_gitea-0.9.0 → python_gitea-0.10.0}/cliff.toml +0 -0
  87. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/contributing.md +0 -0
  88. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/dev/troubleshooting.md +0 -0
  89. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/gen_ref_pages.py +0 -0
  90. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/index.md +0 -0
  91. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/javascripts/mathjax.js +0 -0
  92. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/security.md +0 -0
  93. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/style/api.css +0 -0
  94. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/user-guide/configuration.md +0 -0
  95. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/user-guide/installation.md +0 -0
  96. {python_gitea-0.9.0 → python_gitea-0.10.0}/docs/user-guide/quickstart.md +0 -0
  97. {python_gitea-0.9.0 → python_gitea-0.10.0}/renovate.json +0 -0
  98. {python_gitea-0.9.0 → python_gitea-0.10.0}/scripts/release_version.py +0 -0
  99. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/__init__.py +0 -0
  100. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/__main__.py +0 -0
  101. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/__init__.py +0 -0
  102. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/comment/__init__.py +0 -0
  103. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/comment/add.py +0 -0
  104. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/comment/delete.py +0 -0
  105. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/comment/edit.py +0 -0
  106. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/comment/list.py +0 -0
  107. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/comment/main.py +0 -0
  108. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/config/__init__.py +0 -0
  109. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/config/add.py +0 -0
  110. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/config/delete.py +0 -0
  111. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/config/list.py +0 -0
  112. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/config/main.py +0 -0
  113. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/config/update.py +0 -0
  114. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/__init__.py +0 -0
  115. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/create.py +0 -0
  116. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/dependency/__init__.py +0 -0
  117. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/dependency/add.py +0 -0
  118. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/dependency/list.py +0 -0
  119. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/dependency/main.py +0 -0
  120. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/dependency/remove.py +0 -0
  121. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/edit.py +0 -0
  122. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/issue/list.py +0 -0
  123. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/label/__init__.py +0 -0
  124. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/label/create.py +0 -0
  125. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/label/delete.py +0 -0
  126. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/label/list.py +0 -0
  127. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/label/main.py +0 -0
  128. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/label/update.py +0 -0
  129. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/milestone/__init__.py +0 -0
  130. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/milestone/create.py +0 -0
  131. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/milestone/list.py +0 -0
  132. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/milestone/main.py +0 -0
  133. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/notification/__init__.py +0 -0
  134. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/notification/list.py +0 -0
  135. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/notification/main.py +0 -0
  136. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/notification/read.py +0 -0
  137. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/output.py +0 -0
  138. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/__init__.py +0 -0
  139. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/column/__init__.py +0 -0
  140. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/column/create.py +0 -0
  141. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/column/issues.py +0 -0
  142. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/column/list.py +0 -0
  143. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/create.py +0 -0
  144. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/delete.py +0 -0
  145. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/edit.py +0 -0
  146. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/get.py +0 -0
  147. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/issue/__init__.py +0 -0
  148. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/issue/add.py +0 -0
  149. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/issue/move.py +0 -0
  150. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/issue/remove.py +0 -0
  151. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/issues.py +0 -0
  152. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/project/list.py +0 -0
  153. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/pull_request/__init__.py +0 -0
  154. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/pull_request/list.py +0 -0
  155. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/pull_request/main.py +0 -0
  156. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/user/__init__.py +0 -0
  157. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/user/get.py +0 -0
  158. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/user/main.py +0 -0
  159. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/user/update_settings.py +0 -0
  160. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/utils/__init__.py +0 -0
  161. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/utils/api.py +0 -0
  162. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/utils/auth.py +0 -0
  163. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/utils/convert.py +0 -0
  164. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/utils/errors.py +0 -0
  165. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/utils/issue.py +0 -0
  166. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/utils/options.py +0 -0
  167. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/watch/__init__.py +0 -0
  168. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/watch/list.py +0 -0
  169. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/cli/watch/main.py +0 -0
  170. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/client/__init__.py +0 -0
  171. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/client/base.py +0 -0
  172. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/comment/__init__.py +0 -0
  173. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/comment/async_comment.py +0 -0
  174. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/comment/base.py +0 -0
  175. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/comment/comment.py +0 -0
  176. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/config/__init__.py +0 -0
  177. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/config/manager.py +0 -0
  178. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/config/model.py +0 -0
  179. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/issue/__init__.py +0 -0
  180. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/issue/async_issue.py +0 -0
  181. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/issue/base.py +0 -0
  182. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/issue/issue.py +0 -0
  183. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/issue/project_column.py +0 -0
  184. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/label/__init__.py +0 -0
  185. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/label/async_label.py +0 -0
  186. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/label/base.py +0 -0
  187. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/label/label.py +0 -0
  188. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/milestone/__init__.py +0 -0
  189. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/milestone/async_milestone.py +0 -0
  190. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/milestone/base.py +0 -0
  191. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/milestone/milestone.py +0 -0
  192. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/notification/__init__.py +0 -0
  193. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/notification/async_notification.py +0 -0
  194. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/notification/base.py +0 -0
  195. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/notification/notification.py +0 -0
  196. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/project/__init__.py +0 -0
  197. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/project/base.py +0 -0
  198. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/pull_request/__init__.py +0 -0
  199. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/pull_request/async_pull_request.py +0 -0
  200. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/pull_request/base.py +0 -0
  201. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/pull_request/pull_request.py +0 -0
  202. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/repository/__init__.py +0 -0
  203. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/repository/async_repository.py +0 -0
  204. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/repository/base.py +0 -0
  205. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/repository/repository.py +0 -0
  206. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/resource/__init__.py +0 -0
  207. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/resource/async_resource.py +0 -0
  208. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/resource/resource.py +0 -0
  209. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/user/__init__.py +0 -0
  210. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/user/async_user.py +0 -0
  211. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/user/base.py +0 -0
  212. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/user/user.py +0 -0
  213. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/utils/__init__.py +0 -0
  214. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/utils/log.py +0 -0
  215. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/utils/response.py +0 -0
  216. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/version.py +0 -0
  217. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/watch/__init__.py +0 -0
  218. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/watch/changes.py +0 -0
  219. {python_gitea-0.9.0 → python_gitea-0.10.0}/src/gitea/watch/state.py +0 -0
  220. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/__init__.py +0 -0
  221. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/board.py +0 -0
  222. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/__init__.py +0 -0
  223. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/comment/__init__.py +0 -0
  224. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/comment/test_cli_comment_add.py +0 -0
  225. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/comment/test_cli_comment_delete.py +0 -0
  226. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/comment/test_cli_comment_edit.py +0 -0
  227. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/comment/test_cli_comment_list.py +0 -0
  228. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/comment/test_cli_comment_main.py +0 -0
  229. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/config/__init__.py +0 -0
  230. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/config/test_cli_config_add.py +0 -0
  231. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/config/test_cli_config_delete.py +0 -0
  232. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/config/test_cli_config_list.py +0 -0
  233. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/config/test_cli_config_main.py +0 -0
  234. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/config/test_cli_config_update.py +0 -0
  235. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/envelope.py +0 -0
  236. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/__init__.py +0 -0
  237. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/dependency/__init__.py +0 -0
  238. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/dependency/test_cli_issue_dependency.py +0 -0
  239. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/test_cli_issue_comment.py +0 -0
  240. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/test_cli_issue_create.py +0 -0
  241. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/test_cli_issue_edit.py +0 -0
  242. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/test_cli_issue_list.py +0 -0
  243. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/issue/test_cli_issue_main.py +0 -0
  244. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/label/__init__.py +0 -0
  245. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/label/test_cli_label_create.py +0 -0
  246. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/label/test_cli_label_delete.py +0 -0
  247. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/label/test_cli_label_list.py +0 -0
  248. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/label/test_cli_label_main.py +0 -0
  249. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/label/test_cli_label_update.py +0 -0
  250. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/milestone/__init__.py +0 -0
  251. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/milestone/test_cli_milestone_create.py +0 -0
  252. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/milestone/test_cli_milestone_list.py +0 -0
  253. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/milestone/test_cli_milestone_main.py +0 -0
  254. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/notification/__init__.py +0 -0
  255. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/project/__init__.py +0 -0
  256. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/project/test_cli_project.py +0 -0
  257. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/project/test_cli_project_column_issues.py +0 -0
  258. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/pull_request/__init__.py +0 -0
  259. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/pull_request/test_cli_pull_request_list.py +0 -0
  260. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/pull_request/test_cli_pull_request_main.py +0 -0
  261. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/rendering.py +0 -0
  262. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/test_cli_output.py +0 -0
  263. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/user/__init__.py +0 -0
  264. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/user/test_cli_user_get.py +0 -0
  265. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/user/test_cli_user_update_settings.py +0 -0
  266. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/utils/__init__.py +0 -0
  267. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/utils/test_cli_utils_api.py +0 -0
  268. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/utils/test_cli_utils_auth.py +0 -0
  269. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/utils/test_cli_utils_convert.py +0 -0
  270. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/utils/test_cli_utils_errors.py +0 -0
  271. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/utils/test_cli_utils_issue.py +0 -0
  272. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/utils/test_cli_utils_options.py +0 -0
  273. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/cli/watch/__init__.py +0 -0
  274. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/client/__init__.py +0 -0
  275. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/client/test_client_async_gitea.py +0 -0
  276. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/client/test_client_base.py +0 -0
  277. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/client/test_client_gitea.py +0 -0
  278. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/comment/__init__.py +0 -0
  279. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/comment/test_comment_async_comment.py +0 -0
  280. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/comment/test_comment_base.py +0 -0
  281. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/comment/test_comment_comment.py +0 -0
  282. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/config/__init__.py +0 -0
  283. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/config/test_config_manager.py +0 -0
  284. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/config/test_config_model.py +0 -0
  285. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/conftest.py +0 -0
  286. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/issue/__init__.py +0 -0
  287. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/issue/test_issue_async_issue.py +0 -0
  288. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/issue/test_issue_async_project_column.py +0 -0
  289. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/issue/test_issue_base.py +0 -0
  290. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/issue/test_issue_dependencies.py +0 -0
  291. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/issue/test_issue_issue.py +0 -0
  292. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/issue/test_issue_project_column.py +0 -0
  293. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/label/__init__.py +0 -0
  294. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/label/test_label_async_label.py +0 -0
  295. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/label/test_label_base.py +0 -0
  296. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/label/test_label_label.py +0 -0
  297. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/milestone/__init__.py +0 -0
  298. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/milestone/test_milestone_async_milestone.py +0 -0
  299. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/milestone/test_milestone_base.py +0 -0
  300. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/milestone/test_milestone_milestone.py +0 -0
  301. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/notification/__init__.py +0 -0
  302. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/notification/test_notification_base.py +0 -0
  303. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/notification/test_notification_notification.py +0 -0
  304. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/project/__init__.py +0 -0
  305. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/project/test_project_base.py +0 -0
  306. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/pull_request/__init__.py +0 -0
  307. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/pull_request/test_pull_request_async_pull_request.py +0 -0
  308. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/pull_request/test_pull_request_base.py +0 -0
  309. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/pull_request/test_pull_request_pull_request.py +0 -0
  310. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/repository/__init__.py +0 -0
  311. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/repository/test_repository_async_repository.py +0 -0
  312. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/repository/test_repository_base.py +0 -0
  313. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/repository/test_repository_repository.py +0 -0
  314. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/resource/__init__.py +0 -0
  315. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/resource/test_resource_async_resource.py +0 -0
  316. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/resource/test_resource_resource.py +0 -0
  317. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/smoke_test.py +0 -0
  318. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/test_import.py +0 -0
  319. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/test_main.py +0 -0
  320. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/test_release_version.py +0 -0
  321. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/user/__init__.py +0 -0
  322. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/user/test_user_async_user.py +0 -0
  323. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/user/test_user_base.py +0 -0
  324. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/user/test_user_user.py +0 -0
  325. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/utils/__init__.py +0 -0
  326. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/utils/test_utils_log.py +0 -0
  327. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/utils/test_utils_response.py +0 -0
  328. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/watch/__init__.py +0 -0
  329. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/watch/test_watch_changes.py +0 -0
  330. {python_gitea-0.9.0 → python_gitea-0.10.0}/tests/watch/test_watch_state.py +0 -0
@@ -133,3 +133,7 @@ dmypy.json
133
133
 
134
134
  # Node.js
135
135
  node_modules/
136
+
137
+ # mutmut
138
+ /mutants/
139
+ /.mutmut-cache
@@ -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.0
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>`
@@ -298,6 +354,31 @@ instance is down.
298
354
  - Optional: `--full-name`, `--website`, `--location`, `--language`,
299
355
  `--theme`, `--diff-view-style`, `--hide-email`, `--hide-activity`
300
356
 
357
+ ### Org - discover organizations
358
+
359
+ - `gitea-cli org list`
360
+ - Optional: `--username`, `--page`, `--limit`
361
+ - Lists the organizations of the account the token belongs to; `--username`
362
+ lists those of another account instead.
363
+ - Gitea also has a site-wide listing of every organization, which a token
364
+ that is not scoped for it is refused. This command does not read from it,
365
+ so it answers with the organizations of an account and never with the
366
+ instance's.
367
+
368
+ ### Repo - discover repositories
369
+
370
+ - `gitea-cli repo list --owner <owner>`
371
+ - Optional: `--owner-type`, `--page`, `--limit`
372
+ - `--owner-type` is `organization` (the default) or `user`: Gitea serves the
373
+ two at different endpoints - `/orgs/<owner>/repos` and
374
+ `/users/<owner>/repos` - and an owner's name does not say which of the two
375
+ it is.
376
+
377
+ ```bash
378
+ gitea-cli repo list --owner my-org # an organization's repositories
379
+ gitea-cli repo list --owner alice --owner-type user # a user's repositories
380
+ ```
381
+
301
382
  ### Watch - report what changed since the last run
302
383
 
303
384
  Every other command answers a question about the instance now. `watch` answers
@@ -486,6 +567,30 @@ Show every card on a project together with the column it is in:
486
567
  gitea-cli project issues --owner my-org --project-id 1
487
568
  ```
488
569
 
570
+ Read a board's shape in one call - the project, its columns, and how many cards
571
+ sit in each of them. `project get` answers with the project alone, which says
572
+ nothing about where the cards are:
573
+
574
+ ```console
575
+ $ gitea-cli --output json project show --owner my-org --project-id 31
576
+ {
577
+ "data": {
578
+ "project": { "id": 31, "title": "Board", "state": "open", ... },
579
+ "columns": [
580
+ { "id": 117, "title": "Working", ..., "issue_count": 2, "issue_ids": [1873, 1874] }
581
+ ]
582
+ },
583
+ "metadata": { "status_code": 200, "column_count": 1, "issue_count": 2 }
584
+ }
585
+ ```
586
+
587
+ Each column is the columns endpoint's own object with `issue_count` and
588
+ `issue_ids` added to it, and `issue_ids` holds the global issue IDs the project
589
+ endpoints take - `--issue-id` without `--issue-repository`. Add `--full` to have
590
+ each column carry its issues themselves, under `issues`, rather than their IDs
591
+ alone. Every page of columns, and of each column's issues, is walked, so the
592
+ counts describe the whole board.
593
+
489
594
  Report what changed across two repositories and a board since the last run,
490
595
  quietly enough to be worth a `cron` entry:
491
596
 
@@ -126,12 +126,49 @@ is simpler and sufficient.
126
126
  | `client.milestone` | Milestones |
127
127
  | `client.notification` | Notifications |
128
128
  | `client.project` | Projects, columns, and project issues |
129
+ | `client.organization` | Organizations |
129
130
 
130
131
  Each resource is implemented in a synchronous class (e.g. `gitea.issue.Issue`)
131
132
  and an async class (e.g. `gitea.issue.AsyncIssue`); some modules re-export them
132
133
  from the package `__init__` (e.g. `from gitea.issue import Issue`). See the
133
134
  [API Reference](../reference/index.md) for the full method list and signatures.
134
135
 
136
+ ## Field Names
137
+
138
+ A payload returned by a client method is the JSON the Gitea API sent, keyed as
139
+ the API keys it. Nothing is renamed and nothing is dropped, in the client
140
+ dictionaries and in [the CLI's JSON envelope](cli.md#field-names) alike, so a
141
+ key is looked up in Gitea's API reference and not in this library's source.
142
+
143
+ A project column is therefore `title`:
144
+
145
+ ```python
146
+ columns, _ = client.project.list_project_columns(owner="my-org", repository=None, project_id=31)
147
+ print(columns[0]["title"]) # 'Working'
148
+ ```
149
+
150
+ `name` reads it too. It is an alias, not a second key: reading a payload by it
151
+ works, and enumerating or serializing the payload sees `title` alone, so nothing
152
+ downstream can come to depend on a name the API does not use.
153
+
154
+ ```python
155
+ column = columns[0]
156
+ column["name"] # 'Working' - reads the title
157
+ column.get("name") # 'Working'
158
+ "name" in column # True
159
+ list(column) # ['id', 'title', 'default', 'sorting', ...] - no 'name'
160
+ json.dumps(column) # {"id": 117, "title": "Working", ...} - no 'name'
161
+ ```
162
+
163
+ Only reading is widened. `column["name"] = x` writes a field called `name`, as
164
+ it would on any dictionary, rather than changing the title through a name Gitea
165
+ does not use.
166
+
167
+ `gitea.utils.fields` holds the convention itself, the record types declaring the
168
+ aliases of a resource, and the bar an alias has to clear to be added: a name
169
+ callers have written, not a name that reads well. Today there is one, `name` on
170
+ a project column.
171
+
135
172
  ## Detecting What Changed
136
173
 
137
174
  `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,6 +30,11 @@ dependencies = [
30
30
  [dependency-groups]
31
31
  dev = [
32
32
  "ruff>=0.16.3",
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",
33
38
  "prek>=0.4.13",
34
39
  "pytest-github-actions-annotate-failures>=0.4.2",
35
40
  "pytest-cov>=7.1.0",
@@ -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")
@@ -1,4 +1,13 @@
1
- """Get issues command."""
1
+ """Get issues command.
2
+
3
+ The issue is emitted with the field names the API sends, as `gitea.utils.fields`
4
+ requires. `comments` is one worth knowing about: it is the *number* of comments
5
+ on the issue and not their bodies, which `gitea-cli issue comment list` is for.
6
+ An earlier version of this command renamed it to `comment_count` to say so, and
7
+ was the only command emitting an issue that did - the same count arrived under
8
+ two names depending on which command fetched the issue, which was the worse
9
+ surprise of the two.
10
+ """
2
11
 
3
12
  from __future__ import annotations
4
13
 
@@ -9,26 +18,6 @@ import typer
9
18
  from gitea.cli.utils.options import DEPRECATED_INDEX_HELP, ISSUE_ID_HELP, REPOSITORY_REQUIRED_HELP
10
19
 
11
20
 
12
- def rename_comment_count(issue: dict[str, Any]) -> dict[str, Any]:
13
- """Rename the ``comments`` field of an issue to ``comment_count``.
14
-
15
- The Gitea API returns ``comments`` as an integer count rather than the list of
16
- comments, which misleads consumers expecting comment bodies. The value is kept
17
- as-is; only the name is made unambiguous. Use ``gitea-cli issue comment list``
18
- (or ``gitea-cli comment list``) to retrieve the comments themselves.
19
-
20
- Args:
21
- issue: The issue data returned by the API.
22
-
23
- Returns:
24
- The issue data with ``comments`` renamed to ``comment_count``.
25
-
26
- """
27
- if "comments" not in issue:
28
- return issue
29
- return {("comment_count" if key == "comments" else key): value for key, value in issue.items()}
30
-
31
-
32
21
  def get_command(
33
22
  ctx: typer.Context,
34
23
  owner: Annotated[str, typer.Option("--owner", help="Owner of the repository.")],
@@ -104,6 +93,6 @@ def get_command(
104
93
  index=target_issue,
105
94
  )
106
95
  data = resolve_project_column_ids(client=client, owner=owner, repository=target_repository, issue=data)
107
- return rename_comment_count(data), metadata
96
+ return data, metadata
108
97
 
109
98
  execute_api_command(api_call=api_call, base_url=base_url, command_name="gitea-cli issue get")
@@ -14,12 +14,14 @@ issue_app = typer.Typer(
14
14
  def register_commands() -> None:
15
15
  """Register issue-related commands to the issue_app."""
16
16
  from gitea.cli.comment.main import comment_app # noqa: PLC0415
17
+ from gitea.cli.issue.close import close_command # noqa: PLC0415
17
18
  from gitea.cli.issue.create import create_command # noqa: PLC0415
18
19
  from gitea.cli.issue.dependency.main import dependency_app # noqa: PLC0415
19
20
  from gitea.cli.issue.edit import edit_command # noqa: PLC0415
20
21
  from gitea.cli.issue.get import get_command # noqa: PLC0415
21
22
  from gitea.cli.issue.list import list_command # noqa: PLC0415
22
23
 
24
+ issue_app.command("close", help="Close an issue.")(close_command)
23
25
  issue_app.command("create", help="Create an issue.")(create_command)
24
26
  issue_app.command("edit", help="Edit an issue.")(edit_command)
25
27
  issue_app.command("get", help="Get an issue.")(get_command)
@@ -147,8 +147,10 @@ def register_commands() -> None:
147
147
  from gitea.cli.label.main import label_app # noqa: PLC0415
148
148
  from gitea.cli.milestone.main import milestone_app # noqa: PLC0415
149
149
  from gitea.cli.notification.main import notification_app # noqa: PLC0415
150
+ from gitea.cli.organization.main import organization_app # noqa: PLC0415
150
151
  from gitea.cli.project.main import project_app # noqa: PLC0415
151
152
  from gitea.cli.pull_request.main import pull_request_app # noqa: PLC0415
153
+ from gitea.cli.repository.main import repository_app # noqa: PLC0415
152
154
  from gitea.cli.user.main import user_app # noqa: PLC0415
153
155
  from gitea.cli.watch.main import watch_app # noqa: PLC0415
154
156
 
@@ -161,6 +163,8 @@ def register_commands() -> None:
161
163
  app.add_typer(milestone_app, name="milestone", help="Commands for managing milestones.")
162
164
  app.add_typer(notification_app, name="notification", help="Commands for managing notifications.")
163
165
  app.add_typer(project_app, name="project", help="Commands for managing projects.")
166
+ app.add_typer(organization_app, name="org", help="Commands for managing organizations.")
167
+ app.add_typer(repository_app, name="repo", help="Commands for managing repositories.")
164
168
  app.add_typer(watch_app, name="watch", help="Commands for watching issues for changes.")
165
169
 
166
170
 
@@ -0,0 +1 @@
1
+ """Command line interface for organizations."""