ghnova 0.3.0__py3-none-any.whl
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.
- ghnova/__init__.py +8 -0
- ghnova/__main__.py +8 -0
- ghnova/cli/__init__.py +1 -0
- ghnova/cli/config/__init__.py +1 -0
- ghnova/cli/config/add.py +48 -0
- ghnova/cli/config/delete.py +50 -0
- ghnova/cli/config/list.py +40 -0
- ghnova/cli/config/main.py +27 -0
- ghnova/cli/config/update.py +59 -0
- ghnova/cli/issue/__init__.py +7 -0
- ghnova/cli/issue/create.py +155 -0
- ghnova/cli/issue/get.py +119 -0
- ghnova/cli/issue/list.py +267 -0
- ghnova/cli/issue/lock.py +110 -0
- ghnova/cli/issue/main.py +31 -0
- ghnova/cli/issue/unlock.py +101 -0
- ghnova/cli/issue/update.py +164 -0
- ghnova/cli/main.py +117 -0
- ghnova/cli/repository/__init__.py +1 -0
- ghnova/cli/repository/list.py +201 -0
- ghnova/cli/repository/main.py +21 -0
- ghnova/cli/user/__init__.py +1 -0
- ghnova/cli/user/ctx_info.py +105 -0
- ghnova/cli/user/get.py +98 -0
- ghnova/cli/user/list.py +78 -0
- ghnova/cli/user/main.py +27 -0
- ghnova/cli/user/update.py +164 -0
- ghnova/cli/utils/__init__.py +7 -0
- ghnova/cli/utils/auth.py +67 -0
- ghnova/client/__init__.py +8 -0
- ghnova/client/async_github.py +121 -0
- ghnova/client/base.py +78 -0
- ghnova/client/github.py +107 -0
- ghnova/config/__init__.py +8 -0
- ghnova/config/manager.py +209 -0
- ghnova/config/model.py +58 -0
- ghnova/issue/__init__.py +8 -0
- ghnova/issue/async_issue.py +554 -0
- ghnova/issue/base.py +469 -0
- ghnova/issue/issue.py +584 -0
- ghnova/repository/__init__.py +8 -0
- ghnova/repository/async_repository.py +134 -0
- ghnova/repository/base.py +124 -0
- ghnova/repository/repository.py +134 -0
- ghnova/resource/__init__.py +8 -0
- ghnova/resource/async_resource.py +88 -0
- ghnova/resource/resource.py +88 -0
- ghnova/user/__init__.py +8 -0
- ghnova/user/async_user.py +285 -0
- ghnova/user/base.py +214 -0
- ghnova/user/user.py +285 -0
- ghnova/utils/__init__.py +16 -0
- ghnova/utils/log.py +70 -0
- ghnova/utils/response.py +67 -0
- ghnova/version.py +11 -0
- ghnova-0.3.0.dist-info/METADATA +194 -0
- ghnova-0.3.0.dist-info/RECORD +60 -0
- ghnova-0.3.0.dist-info/WHEEL +4 -0
- ghnova-0.3.0.dist-info/entry_points.txt +2 -0
- ghnova-0.3.0.dist-info/licenses/LICENSE +21 -0
ghnova/cli/issue/list.py
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"""List command for issue CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Annotated, Literal
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def list_command( # noqa: PLR0913
|
|
12
|
+
ctx: typer.Context,
|
|
13
|
+
account_name: Annotated[
|
|
14
|
+
str | None,
|
|
15
|
+
typer.Option(
|
|
16
|
+
"--account-name",
|
|
17
|
+
help="Name of the account to use for authentication.",
|
|
18
|
+
),
|
|
19
|
+
] = None,
|
|
20
|
+
token: Annotated[
|
|
21
|
+
str | None,
|
|
22
|
+
typer.Option(
|
|
23
|
+
"--token",
|
|
24
|
+
help="Token for authentication. If not provided, the token from the specified account will be used.",
|
|
25
|
+
),
|
|
26
|
+
] = None,
|
|
27
|
+
base_url: Annotated[
|
|
28
|
+
str | None,
|
|
29
|
+
typer.Option(
|
|
30
|
+
"--base-url",
|
|
31
|
+
help="Base URL of the GitHub platform. If not provided, the base URL from the specified account will be used.",
|
|
32
|
+
),
|
|
33
|
+
] = None,
|
|
34
|
+
owner: Annotated[
|
|
35
|
+
str | None,
|
|
36
|
+
typer.Option(
|
|
37
|
+
"--owner",
|
|
38
|
+
help="The owner of the repository.",
|
|
39
|
+
),
|
|
40
|
+
] = None,
|
|
41
|
+
organization: Annotated[
|
|
42
|
+
str | None,
|
|
43
|
+
typer.Option(
|
|
44
|
+
"--organization",
|
|
45
|
+
help="The organization name.",
|
|
46
|
+
),
|
|
47
|
+
] = None,
|
|
48
|
+
repository: Annotated[
|
|
49
|
+
str | None,
|
|
50
|
+
typer.Option(
|
|
51
|
+
"--repository",
|
|
52
|
+
help="The name of the repository.",
|
|
53
|
+
),
|
|
54
|
+
] = None,
|
|
55
|
+
filter_by: Annotated[
|
|
56
|
+
Literal["assigned", "created", "mentioned", "subscribed", "all"] | None,
|
|
57
|
+
typer.Option(
|
|
58
|
+
"--filter-by",
|
|
59
|
+
help="Filter issues by: assigned, created, mentioned, subscribed, or all.",
|
|
60
|
+
),
|
|
61
|
+
] = None,
|
|
62
|
+
state: Annotated[
|
|
63
|
+
Literal["open", "closed", "all"] | None,
|
|
64
|
+
typer.Option(
|
|
65
|
+
"--state",
|
|
66
|
+
help="Filter by state: open, closed, or all.",
|
|
67
|
+
),
|
|
68
|
+
] = None,
|
|
69
|
+
labels: Annotated[list[str] | None, typer.Option("--labels", help="Filter by labels.")] = None,
|
|
70
|
+
sort: Annotated[
|
|
71
|
+
Literal["created", "updated", "comments"] | None,
|
|
72
|
+
typer.Option(
|
|
73
|
+
"--sort",
|
|
74
|
+
help="Sort by: created, updated, or comments.",
|
|
75
|
+
),
|
|
76
|
+
] = None,
|
|
77
|
+
direction: Annotated[
|
|
78
|
+
Literal["asc", "desc"] | None,
|
|
79
|
+
typer.Option(
|
|
80
|
+
"--direction",
|
|
81
|
+
help="Sort direction: asc or desc.",
|
|
82
|
+
),
|
|
83
|
+
] = None,
|
|
84
|
+
since: Annotated[
|
|
85
|
+
datetime | None,
|
|
86
|
+
typer.Option(
|
|
87
|
+
"--since",
|
|
88
|
+
help="Only issues updated at or after this time are returned (ISO 8601 format).",
|
|
89
|
+
),
|
|
90
|
+
] = None,
|
|
91
|
+
collab: Annotated[
|
|
92
|
+
bool | None,
|
|
93
|
+
typer.Option(
|
|
94
|
+
"--collab/--no-collab",
|
|
95
|
+
help="Include issues the user is a collaborator on.",
|
|
96
|
+
),
|
|
97
|
+
] = None,
|
|
98
|
+
orgs: Annotated[
|
|
99
|
+
bool | None,
|
|
100
|
+
typer.Option(
|
|
101
|
+
"--orgs/--no-orgs",
|
|
102
|
+
help="Include issues from organizations the user is a member of.",
|
|
103
|
+
),
|
|
104
|
+
] = None,
|
|
105
|
+
owned: Annotated[
|
|
106
|
+
bool | None,
|
|
107
|
+
typer.Option(
|
|
108
|
+
"--owned/--no-owned",
|
|
109
|
+
help="Include issues owned by the authenticated user.",
|
|
110
|
+
),
|
|
111
|
+
] = None,
|
|
112
|
+
pulls: Annotated[
|
|
113
|
+
bool | None,
|
|
114
|
+
typer.Option(
|
|
115
|
+
"--pulls/--no-pulls",
|
|
116
|
+
help="Include pull requests in the results.",
|
|
117
|
+
),
|
|
118
|
+
] = None,
|
|
119
|
+
issue_type: Annotated[
|
|
120
|
+
str | None,
|
|
121
|
+
typer.Option(
|
|
122
|
+
"--issue-type",
|
|
123
|
+
help="Filter by issue type.",
|
|
124
|
+
),
|
|
125
|
+
] = None,
|
|
126
|
+
milestone: Annotated[
|
|
127
|
+
str | None,
|
|
128
|
+
typer.Option(
|
|
129
|
+
"--milestone",
|
|
130
|
+
help="Filter by milestone.",
|
|
131
|
+
),
|
|
132
|
+
] = None,
|
|
133
|
+
assignee: Annotated[
|
|
134
|
+
str | None,
|
|
135
|
+
typer.Option(
|
|
136
|
+
"--assignee",
|
|
137
|
+
help="Filter by assignee.",
|
|
138
|
+
),
|
|
139
|
+
] = None,
|
|
140
|
+
creator: Annotated[
|
|
141
|
+
str | None,
|
|
142
|
+
typer.Option(
|
|
143
|
+
"--creator",
|
|
144
|
+
help="Filter by creator.",
|
|
145
|
+
),
|
|
146
|
+
] = None,
|
|
147
|
+
mentioned: Annotated[
|
|
148
|
+
str | None,
|
|
149
|
+
typer.Option(
|
|
150
|
+
"--mentioned",
|
|
151
|
+
help="Filter by mentioned user.",
|
|
152
|
+
),
|
|
153
|
+
] = None,
|
|
154
|
+
per_page: Annotated[
|
|
155
|
+
int,
|
|
156
|
+
typer.Option(
|
|
157
|
+
"--per-page",
|
|
158
|
+
help="Number of results per page.",
|
|
159
|
+
),
|
|
160
|
+
] = 30,
|
|
161
|
+
page: Annotated[
|
|
162
|
+
int,
|
|
163
|
+
typer.Option(
|
|
164
|
+
"--page",
|
|
165
|
+
help="Page number for pagination.",
|
|
166
|
+
),
|
|
167
|
+
] = 1,
|
|
168
|
+
etag: Annotated[
|
|
169
|
+
str | None,
|
|
170
|
+
typer.Option(
|
|
171
|
+
"--etag",
|
|
172
|
+
help="ETag from a previous request for caching purposes.",
|
|
173
|
+
),
|
|
174
|
+
] = None,
|
|
175
|
+
last_modified: Annotated[
|
|
176
|
+
str | None,
|
|
177
|
+
typer.Option(
|
|
178
|
+
"--last-modified",
|
|
179
|
+
help="Last-Modified header from a previous request for caching purposes.",
|
|
180
|
+
),
|
|
181
|
+
] = None,
|
|
182
|
+
) -> None:
|
|
183
|
+
"""List issues from a repository or organization.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
ctx: Typer context.
|
|
187
|
+
account_name: Name of the account to use for authentication.
|
|
188
|
+
token: Token for authentication.
|
|
189
|
+
base_url: Base URL of the GitHub platform.
|
|
190
|
+
owner: The owner of the repository.
|
|
191
|
+
organization: The organization name.
|
|
192
|
+
repository: The name of the repository.
|
|
193
|
+
filter_by: Filter issues by: assigned, created, mentioned, subscribed, or all.
|
|
194
|
+
state: Filter by state: open, closed, or all.
|
|
195
|
+
labels: Filter by labels.
|
|
196
|
+
sort: Sort by: created, updated, or comments.
|
|
197
|
+
direction: Sort direction: asc or desc.
|
|
198
|
+
since: Only issues updated at or after this time are returned.
|
|
199
|
+
collab: Include issues the user is a collaborator on.
|
|
200
|
+
orgs: Include issues from organizations the user is a member of.
|
|
201
|
+
owned: Include issues owned by the authenticated user.
|
|
202
|
+
pulls: Include pull requests in the results.
|
|
203
|
+
issue_type: Filter by issue type.
|
|
204
|
+
milestone: Filter by milestone.
|
|
205
|
+
assignee: Filter by assignee.
|
|
206
|
+
creator: Filter by creator.
|
|
207
|
+
mentioned: Filter by mentioned user.
|
|
208
|
+
per_page: Number of results per page.
|
|
209
|
+
page: Page number for pagination.
|
|
210
|
+
etag: ETag from a previous request for caching purposes.
|
|
211
|
+
last_modified: Last-Modified header from a previous request for caching purposes.
|
|
212
|
+
|
|
213
|
+
"""
|
|
214
|
+
import json # noqa: PLC0415
|
|
215
|
+
import logging # noqa: PLC0415
|
|
216
|
+
|
|
217
|
+
from ghnova.cli.utils.auth import get_auth_params # noqa: PLC0415
|
|
218
|
+
from ghnova.client.github import GitHub # noqa: PLC0415
|
|
219
|
+
|
|
220
|
+
logger = logging.getLogger("ghnova")
|
|
221
|
+
|
|
222
|
+
token, base_url = get_auth_params(
|
|
223
|
+
config_path=ctx.obj["config_path"],
|
|
224
|
+
account_name=account_name,
|
|
225
|
+
token=token,
|
|
226
|
+
base_url=base_url,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
with GitHub(token=token, base_url=base_url) as client:
|
|
231
|
+
issue_client = client.issue
|
|
232
|
+
data, status_code, etag_value, last_modified_value = issue_client.list_issues(
|
|
233
|
+
owner=owner,
|
|
234
|
+
organization=organization,
|
|
235
|
+
repository=repository,
|
|
236
|
+
filter_by=filter_by,
|
|
237
|
+
state=state,
|
|
238
|
+
labels=labels,
|
|
239
|
+
sort=sort,
|
|
240
|
+
direction=direction,
|
|
241
|
+
since=since,
|
|
242
|
+
collab=collab,
|
|
243
|
+
orgs=orgs,
|
|
244
|
+
owned=owned,
|
|
245
|
+
pulls=pulls,
|
|
246
|
+
issue_type=issue_type,
|
|
247
|
+
milestone=milestone,
|
|
248
|
+
assignee=assignee,
|
|
249
|
+
creator=creator,
|
|
250
|
+
mentioned=mentioned,
|
|
251
|
+
per_page=per_page,
|
|
252
|
+
page=page,
|
|
253
|
+
etag=etag,
|
|
254
|
+
last_modified=last_modified,
|
|
255
|
+
)
|
|
256
|
+
result = {
|
|
257
|
+
"data": data,
|
|
258
|
+
"metadata": {
|
|
259
|
+
"status_code": status_code,
|
|
260
|
+
"etag": etag_value,
|
|
261
|
+
"last_modified": last_modified_value,
|
|
262
|
+
},
|
|
263
|
+
}
|
|
264
|
+
print(json.dumps(result, indent=2, default=str))
|
|
265
|
+
except Exception as e:
|
|
266
|
+
logger.error("Error listing issues: %s", e)
|
|
267
|
+
raise typer.Exit(code=1) from e
|
ghnova/cli/issue/lock.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Lock command for issue CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated, Literal
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def lock_command( # noqa: PLR0913
|
|
11
|
+
ctx: typer.Context,
|
|
12
|
+
owner: Annotated[
|
|
13
|
+
str,
|
|
14
|
+
typer.Option(
|
|
15
|
+
"--owner",
|
|
16
|
+
help="The owner of the repository.",
|
|
17
|
+
),
|
|
18
|
+
],
|
|
19
|
+
repository: Annotated[
|
|
20
|
+
str,
|
|
21
|
+
typer.Option(
|
|
22
|
+
"--repository",
|
|
23
|
+
help="The name of the repository.",
|
|
24
|
+
),
|
|
25
|
+
],
|
|
26
|
+
issue_number: Annotated[
|
|
27
|
+
int,
|
|
28
|
+
typer.Option(
|
|
29
|
+
"--issue-number",
|
|
30
|
+
help="The issue number.",
|
|
31
|
+
),
|
|
32
|
+
],
|
|
33
|
+
account_name: Annotated[
|
|
34
|
+
str | None,
|
|
35
|
+
typer.Option(
|
|
36
|
+
"--account-name",
|
|
37
|
+
help="Name of the account to use for authentication.",
|
|
38
|
+
),
|
|
39
|
+
] = None,
|
|
40
|
+
token: Annotated[
|
|
41
|
+
str | None,
|
|
42
|
+
typer.Option(
|
|
43
|
+
"--token",
|
|
44
|
+
help="Token for authentication. If not provided, the token from the specified account will be used.",
|
|
45
|
+
),
|
|
46
|
+
] = None,
|
|
47
|
+
base_url: Annotated[
|
|
48
|
+
str | None,
|
|
49
|
+
typer.Option(
|
|
50
|
+
"--base-url",
|
|
51
|
+
help="Base URL of the GitHub platform. If not provided, the base URL from the specified account will be used.",
|
|
52
|
+
),
|
|
53
|
+
] = None,
|
|
54
|
+
lock_reason: Annotated[
|
|
55
|
+
Literal["off-topic", "too heated", "resolved", "spam"] | None,
|
|
56
|
+
typer.Option(
|
|
57
|
+
"--lock-reason",
|
|
58
|
+
help="Reason for locking: off-topic, too heated, resolved, or spam.",
|
|
59
|
+
),
|
|
60
|
+
] = None,
|
|
61
|
+
) -> None:
|
|
62
|
+
"""Lock an issue to prevent further comments.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
ctx: Typer context.
|
|
66
|
+
owner: The owner of the repository.
|
|
67
|
+
repository: The name of the repository.
|
|
68
|
+
issue_number: The issue number.
|
|
69
|
+
account_name: Name of the account to use for authentication.
|
|
70
|
+
token: Token for authentication.
|
|
71
|
+
base_url: Base URL of the GitHub platform.
|
|
72
|
+
lock_reason: Reason for locking the issue.
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
import json # noqa: PLC0415
|
|
76
|
+
import logging # noqa: PLC0415
|
|
77
|
+
|
|
78
|
+
from ghnova.cli.utils.auth import get_auth_params # noqa: PLC0415
|
|
79
|
+
from ghnova.client.github import GitHub # noqa: PLC0415
|
|
80
|
+
|
|
81
|
+
logger = logging.getLogger("ghnova")
|
|
82
|
+
|
|
83
|
+
token, base_url = get_auth_params(
|
|
84
|
+
config_path=ctx.obj["config_path"],
|
|
85
|
+
account_name=account_name,
|
|
86
|
+
token=token,
|
|
87
|
+
base_url=base_url,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
with GitHub(token=token, base_url=base_url) as client:
|
|
92
|
+
issue_client = client.issue
|
|
93
|
+
data, status_code, etag_value, last_modified_value = issue_client.lock_issue(
|
|
94
|
+
owner=owner,
|
|
95
|
+
repository=repository,
|
|
96
|
+
issue_number=issue_number,
|
|
97
|
+
lock_reason=lock_reason,
|
|
98
|
+
)
|
|
99
|
+
result = {
|
|
100
|
+
"data": data,
|
|
101
|
+
"metadata": {
|
|
102
|
+
"status_code": status_code,
|
|
103
|
+
"etag": etag_value,
|
|
104
|
+
"last_modified": last_modified_value,
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
print(json.dumps(result, indent=2, default=str))
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.error("Error locking issue: %s", e)
|
|
110
|
+
raise typer.Exit(code=1) from e
|
ghnova/cli/issue/main.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Issue CLI commands for ghnova."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
issue_app = typer.Typer(
|
|
8
|
+
name="issue",
|
|
9
|
+
help="Manage GitHub issues.",
|
|
10
|
+
rich_markup_mode="rich",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def register_commands() -> None:
|
|
15
|
+
"""Register issue subcommands."""
|
|
16
|
+
from ghnova.cli.issue.create import create_command # noqa: PLC0415
|
|
17
|
+
from ghnova.cli.issue.get import get_command # noqa: PLC0415
|
|
18
|
+
from ghnova.cli.issue.list import list_command # noqa: PLC0415
|
|
19
|
+
from ghnova.cli.issue.lock import lock_command # noqa: PLC0415
|
|
20
|
+
from ghnova.cli.issue.unlock import unlock_command # noqa: PLC0415
|
|
21
|
+
from ghnova.cli.issue.update import update_command # noqa: PLC0415
|
|
22
|
+
|
|
23
|
+
issue_app.command(name="create", help="Create a new issue.")(create_command)
|
|
24
|
+
issue_app.command(name="get", help="Get a specific issue.")(get_command)
|
|
25
|
+
issue_app.command(name="list", help="List issues.")(list_command)
|
|
26
|
+
issue_app.command(name="lock", help="Lock an issue.")(lock_command)
|
|
27
|
+
issue_app.command(name="unlock", help="Unlock an issue.")(unlock_command)
|
|
28
|
+
issue_app.command(name="update", help="Update an issue.")(update_command)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
register_commands()
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Unlock command for issue CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def unlock_command( # noqa: PLR0913
|
|
11
|
+
ctx: typer.Context,
|
|
12
|
+
owner: Annotated[
|
|
13
|
+
str,
|
|
14
|
+
typer.Option(
|
|
15
|
+
"--owner",
|
|
16
|
+
help="The owner of the repository.",
|
|
17
|
+
),
|
|
18
|
+
],
|
|
19
|
+
repository: Annotated[
|
|
20
|
+
str,
|
|
21
|
+
typer.Option(
|
|
22
|
+
"--repository",
|
|
23
|
+
help="The name of the repository.",
|
|
24
|
+
),
|
|
25
|
+
],
|
|
26
|
+
issue_number: Annotated[
|
|
27
|
+
int,
|
|
28
|
+
typer.Option(
|
|
29
|
+
"--issue-number",
|
|
30
|
+
help="The issue number.",
|
|
31
|
+
),
|
|
32
|
+
],
|
|
33
|
+
account_name: Annotated[
|
|
34
|
+
str | None,
|
|
35
|
+
typer.Option(
|
|
36
|
+
"--account-name",
|
|
37
|
+
help="Name of the account to use for authentication.",
|
|
38
|
+
),
|
|
39
|
+
] = None,
|
|
40
|
+
token: Annotated[
|
|
41
|
+
str | None,
|
|
42
|
+
typer.Option(
|
|
43
|
+
"--token",
|
|
44
|
+
help="Token for authentication. If not provided, the token from the specified account will be used.",
|
|
45
|
+
),
|
|
46
|
+
] = None,
|
|
47
|
+
base_url: Annotated[
|
|
48
|
+
str | None,
|
|
49
|
+
typer.Option(
|
|
50
|
+
"--base-url",
|
|
51
|
+
help="Base URL of the GitHub platform. If not provided, the base URL from the specified account will be used.",
|
|
52
|
+
),
|
|
53
|
+
] = None,
|
|
54
|
+
) -> None:
|
|
55
|
+
"""Unlock an issue to allow further comments.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
ctx: Typer context.
|
|
59
|
+
owner: The owner of the repository.
|
|
60
|
+
repository: The name of the repository.
|
|
61
|
+
issue_number: The issue number.
|
|
62
|
+
account_name: Name of the account to use for authentication.
|
|
63
|
+
token: Token for authentication.
|
|
64
|
+
base_url: Base URL of the GitHub platform.
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
import json # noqa: PLC0415
|
|
68
|
+
import logging # noqa: PLC0415
|
|
69
|
+
|
|
70
|
+
from ghnova.cli.utils.auth import get_auth_params # noqa: PLC0415
|
|
71
|
+
from ghnova.client.github import GitHub # noqa: PLC0415
|
|
72
|
+
|
|
73
|
+
logger = logging.getLogger("ghnova")
|
|
74
|
+
|
|
75
|
+
token, base_url = get_auth_params(
|
|
76
|
+
config_path=ctx.obj["config_path"],
|
|
77
|
+
account_name=account_name,
|
|
78
|
+
token=token,
|
|
79
|
+
base_url=base_url,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
with GitHub(token=token, base_url=base_url) as client:
|
|
84
|
+
issue_client = client.issue
|
|
85
|
+
data, status_code, etag_value, last_modified_value = issue_client.unlock_issue(
|
|
86
|
+
owner=owner,
|
|
87
|
+
repository=repository,
|
|
88
|
+
issue_number=issue_number,
|
|
89
|
+
)
|
|
90
|
+
result = {
|
|
91
|
+
"data": data,
|
|
92
|
+
"metadata": {
|
|
93
|
+
"status_code": status_code,
|
|
94
|
+
"etag": etag_value,
|
|
95
|
+
"last_modified": last_modified_value,
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
print(json.dumps(result, indent=2, default=str))
|
|
99
|
+
except Exception as e:
|
|
100
|
+
logger.error("Error unlocking issue: %s", e)
|
|
101
|
+
raise typer.Exit(code=1) from e
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""Update command for issue CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated, Literal
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def update_command( # noqa: PLR0913
|
|
11
|
+
ctx: typer.Context,
|
|
12
|
+
owner: Annotated[
|
|
13
|
+
str,
|
|
14
|
+
typer.Option(
|
|
15
|
+
"--owner",
|
|
16
|
+
help="The owner of the repository.",
|
|
17
|
+
),
|
|
18
|
+
],
|
|
19
|
+
repository: Annotated[
|
|
20
|
+
str,
|
|
21
|
+
typer.Option(
|
|
22
|
+
"--repository",
|
|
23
|
+
help="The name of the repository.",
|
|
24
|
+
),
|
|
25
|
+
],
|
|
26
|
+
issue_number: Annotated[
|
|
27
|
+
int,
|
|
28
|
+
typer.Option(
|
|
29
|
+
"--issue-number",
|
|
30
|
+
help="The issue number.",
|
|
31
|
+
),
|
|
32
|
+
],
|
|
33
|
+
account_name: Annotated[
|
|
34
|
+
str | None,
|
|
35
|
+
typer.Option(
|
|
36
|
+
"--account-name",
|
|
37
|
+
help="Name of the account to use for authentication.",
|
|
38
|
+
),
|
|
39
|
+
] = None,
|
|
40
|
+
token: Annotated[
|
|
41
|
+
str | None,
|
|
42
|
+
typer.Option(
|
|
43
|
+
"--token",
|
|
44
|
+
help="Token for authentication. If not provided, the token from the specified account will be used.",
|
|
45
|
+
),
|
|
46
|
+
] = None,
|
|
47
|
+
base_url: Annotated[
|
|
48
|
+
str | None,
|
|
49
|
+
typer.Option(
|
|
50
|
+
"--base-url",
|
|
51
|
+
help="Base URL of the GitHub platform. If not provided, the base URL from the specified account will be used.",
|
|
52
|
+
),
|
|
53
|
+
] = None,
|
|
54
|
+
title: Annotated[
|
|
55
|
+
str | None,
|
|
56
|
+
typer.Option(
|
|
57
|
+
"--title",
|
|
58
|
+
help="The new title of the issue.",
|
|
59
|
+
),
|
|
60
|
+
] = None,
|
|
61
|
+
body: Annotated[
|
|
62
|
+
str | None,
|
|
63
|
+
typer.Option(
|
|
64
|
+
"--body",
|
|
65
|
+
help="The new body of the issue.",
|
|
66
|
+
),
|
|
67
|
+
] = None,
|
|
68
|
+
assignee: Annotated[
|
|
69
|
+
str | None,
|
|
70
|
+
typer.Option(
|
|
71
|
+
"--assignee",
|
|
72
|
+
help="The assignee of the issue.",
|
|
73
|
+
),
|
|
74
|
+
] = None,
|
|
75
|
+
milestone: Annotated[
|
|
76
|
+
str | None,
|
|
77
|
+
typer.Option(
|
|
78
|
+
"--milestone",
|
|
79
|
+
help="The milestone for the issue.",
|
|
80
|
+
),
|
|
81
|
+
] = None,
|
|
82
|
+
labels: Annotated[
|
|
83
|
+
list[str] | None,
|
|
84
|
+
typer.Option(
|
|
85
|
+
"--labels",
|
|
86
|
+
help="A new list of labels to assign to the issue.",
|
|
87
|
+
),
|
|
88
|
+
] = None,
|
|
89
|
+
assignees: Annotated[
|
|
90
|
+
list[str] | None,
|
|
91
|
+
typer.Option(
|
|
92
|
+
"--assignees",
|
|
93
|
+
help="A new list of assignees for the issue.",
|
|
94
|
+
),
|
|
95
|
+
] = None,
|
|
96
|
+
state: Annotated[
|
|
97
|
+
Literal["open", "closed"] | None,
|
|
98
|
+
typer.Option(
|
|
99
|
+
"--state",
|
|
100
|
+
help="The state of the issue (open or closed).",
|
|
101
|
+
),
|
|
102
|
+
] = None,
|
|
103
|
+
) -> None:
|
|
104
|
+
"""Update an existing issue.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
ctx: Typer context.
|
|
108
|
+
owner: The owner of the repository.
|
|
109
|
+
repository: The name of the repository.
|
|
110
|
+
issue_number: The issue number.
|
|
111
|
+
account_name: Name of the account to use for authentication.
|
|
112
|
+
token: Token for authentication.
|
|
113
|
+
base_url: Base URL of the GitHub platform.
|
|
114
|
+
title: The new title of the issue.
|
|
115
|
+
body: The new body of the issue.
|
|
116
|
+
assignee: The assignee of the issue.
|
|
117
|
+
milestone: The milestone for the issue.
|
|
118
|
+
labels: A new list of labels to assign to the issue.
|
|
119
|
+
assignees: A new list of assignees for the issue.
|
|
120
|
+
state: The state of the issue (open or closed).
|
|
121
|
+
|
|
122
|
+
"""
|
|
123
|
+
import json # noqa: PLC0415
|
|
124
|
+
import logging # noqa: PLC0415
|
|
125
|
+
|
|
126
|
+
from ghnova.cli.utils.auth import get_auth_params # noqa: PLC0415
|
|
127
|
+
from ghnova.client.github import GitHub # noqa: PLC0415
|
|
128
|
+
|
|
129
|
+
logger = logging.getLogger("ghnova")
|
|
130
|
+
|
|
131
|
+
token, base_url = get_auth_params(
|
|
132
|
+
config_path=ctx.obj["config_path"],
|
|
133
|
+
account_name=account_name,
|
|
134
|
+
token=token,
|
|
135
|
+
base_url=base_url,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
with GitHub(token=token, base_url=base_url) as client:
|
|
140
|
+
issue_client = client.issue
|
|
141
|
+
data, status_code, etag_value, last_modified_value = issue_client.update_issue(
|
|
142
|
+
owner=owner,
|
|
143
|
+
repository=repository,
|
|
144
|
+
issue_number=issue_number,
|
|
145
|
+
title=title,
|
|
146
|
+
body=body,
|
|
147
|
+
assignee=assignee,
|
|
148
|
+
milestone=milestone,
|
|
149
|
+
labels=labels,
|
|
150
|
+
assignees=assignees,
|
|
151
|
+
state=state,
|
|
152
|
+
)
|
|
153
|
+
result = {
|
|
154
|
+
"data": data,
|
|
155
|
+
"metadata": {
|
|
156
|
+
"status_code": status_code,
|
|
157
|
+
"etag": etag_value,
|
|
158
|
+
"last_modified": last_modified_value,
|
|
159
|
+
},
|
|
160
|
+
}
|
|
161
|
+
print(json.dumps(result, indent=2, default=str))
|
|
162
|
+
except Exception as e:
|
|
163
|
+
logger.error("Error updating issue: %s", e)
|
|
164
|
+
raise typer.Exit(code=1) from e
|