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/__init__.py
ADDED
ghnova/__main__.py
ADDED
ghnova/cli/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Command line interface for ghnova."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Command line interface for configurations."""
|
ghnova/cli/config/add.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Add command for config CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def add_command(
|
|
11
|
+
ctx: typer.Context,
|
|
12
|
+
name: Annotated[
|
|
13
|
+
str,
|
|
14
|
+
typer.Option("--name", help="Name of the account. It does not need to be the same as the GitHub account name."),
|
|
15
|
+
],
|
|
16
|
+
token: Annotated[str, typer.Option("--token", help="Token for authentication.")],
|
|
17
|
+
base_url: Annotated[str, typer.Option("--base-url", help="Base URL of the platform.")] = "https://github.com",
|
|
18
|
+
is_default: Annotated[bool, typer.Option("--default", help="Set as default account.")] = False,
|
|
19
|
+
) -> None:
|
|
20
|
+
"""Add a new account to the configuration.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
ctx: Typer context.
|
|
24
|
+
name: Name of the account. It does not need to be the same as the GutHub account name.
|
|
25
|
+
token: Token for authentication.
|
|
26
|
+
base_url: Base URL of the platform.
|
|
27
|
+
is_default: Set as default account.
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
import logging # noqa: PLC0415
|
|
31
|
+
|
|
32
|
+
from ghnova.config.manager import ConfigManager # noqa: PLC0415
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger("ghnova")
|
|
35
|
+
|
|
36
|
+
config_manager = ConfigManager(filename=ctx.obj["config_path"])
|
|
37
|
+
|
|
38
|
+
logger.info("Configuration path: %s", config_manager.config_path)
|
|
39
|
+
|
|
40
|
+
config_manager.load_config()
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
config_manager.add_account(name=name, token=token, base_url=base_url, is_default=is_default)
|
|
44
|
+
config_manager.save_config()
|
|
45
|
+
logger.info("Account '%s' added successfully.", name)
|
|
46
|
+
except ValueError as e:
|
|
47
|
+
logger.error("Error adding account: %s", e)
|
|
48
|
+
raise typer.Exit(code=1) from e
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Delete command for config CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def delete_command(
|
|
11
|
+
ctx: typer.Context,
|
|
12
|
+
name: Annotated[
|
|
13
|
+
str,
|
|
14
|
+
typer.Option("--name", help="Name of the account. It does not need to be the same as the GitHub account name."),
|
|
15
|
+
],
|
|
16
|
+
force: Annotated[bool, typer.Option("--force", "-f", help="Force deletion without confirmation.")] = False,
|
|
17
|
+
) -> None:
|
|
18
|
+
"""Delete the configuration of an existing account.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
ctx: Typer context.
|
|
22
|
+
name: Name of the account.
|
|
23
|
+
force: Force deletion without confirmation.
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
import logging # noqa: PLC0415
|
|
27
|
+
|
|
28
|
+
from ghnova.config.manager import ConfigManager # noqa: PLC0415
|
|
29
|
+
|
|
30
|
+
if not force:
|
|
31
|
+
confirm = typer.confirm(f"Are you sure you want to delete the account '{name}'?")
|
|
32
|
+
if not confirm:
|
|
33
|
+
typer.echo("Deletion cancelled.")
|
|
34
|
+
raise typer.Exit()
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger("ghnova")
|
|
37
|
+
|
|
38
|
+
config_manager = ConfigManager(filename=ctx.obj["config_path"])
|
|
39
|
+
|
|
40
|
+
logger.info("Configuration path: %s", config_manager.config_path)
|
|
41
|
+
|
|
42
|
+
config_manager.load_config()
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
config_manager.delete_account(name=name)
|
|
46
|
+
config_manager.save_config()
|
|
47
|
+
logger.info("Account '%s' deleted successfully.", name)
|
|
48
|
+
except ValueError as e:
|
|
49
|
+
logger.error("Error deleting account: %s", e)
|
|
50
|
+
raise typer.Exit(code=1) from e
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""List command for config CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def list_command(ctx: typer.Context) -> None:
|
|
9
|
+
"""List all configured accounts.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
ctx: Typer context.
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
import logging # noqa: PLC0415
|
|
16
|
+
|
|
17
|
+
from ghnova.config.manager import ConfigManager # noqa: PLC0415
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger("ghnova")
|
|
20
|
+
|
|
21
|
+
config_manager = ConfigManager(filename=ctx.obj["config_path"])
|
|
22
|
+
|
|
23
|
+
logger.info("Configuration path: %s", config_manager.config_path)
|
|
24
|
+
|
|
25
|
+
config_manager.load_config()
|
|
26
|
+
|
|
27
|
+
accounts = config_manager._config.accounts
|
|
28
|
+
|
|
29
|
+
default_account_name = config_manager._config.default_account
|
|
30
|
+
if not default_account_name:
|
|
31
|
+
typer.echo("Default account: None")
|
|
32
|
+
else:
|
|
33
|
+
typer.echo(f"Default account: {default_account_name}")
|
|
34
|
+
|
|
35
|
+
typer.echo("Configured accounts:")
|
|
36
|
+
|
|
37
|
+
for account in accounts.values():
|
|
38
|
+
typer.echo(f" Name: {account.name}")
|
|
39
|
+
typer.echo(f" Base URL: {account.base_url}")
|
|
40
|
+
typer.echo("")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Configuration CLI commands for ghnova."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
config_app = typer.Typer(
|
|
8
|
+
name="config",
|
|
9
|
+
help="Manage github configuration.",
|
|
10
|
+
rich_markup_mode="rich",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def register_commands() -> None:
|
|
15
|
+
"""Register config subcommands."""
|
|
16
|
+
from ghnova.cli.config.add import add_command # noqa: PLC0415
|
|
17
|
+
from ghnova.cli.config.delete import delete_command # noqa: PLC0415
|
|
18
|
+
from ghnova.cli.config.list import list_command # noqa: PLC0415
|
|
19
|
+
from ghnova.cli.config.update import update_command # noqa: PLC0415
|
|
20
|
+
|
|
21
|
+
config_app.command(name="add")(add_command)
|
|
22
|
+
config_app.command(name="delete")(delete_command)
|
|
23
|
+
config_app.command(name="list")(list_command)
|
|
24
|
+
config_app.command(name="update")(update_command)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
register_commands()
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Update command for config CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def update_command(
|
|
11
|
+
ctx: typer.Context,
|
|
12
|
+
name: Annotated[str, typer.Option("--name", help="Name of the account.")],
|
|
13
|
+
token: Annotated[str | None, typer.Option("--token", help="Token for authentication.")] = None,
|
|
14
|
+
base_url: Annotated[str | None, typer.Option("--base-url", help="Base URL of the GitHub platform.")] = None,
|
|
15
|
+
default: Annotated[bool | None, typer.Option("--default", help="Set as default account.")] = None,
|
|
16
|
+
) -> None:
|
|
17
|
+
"""Update the configuration of an existing platform.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
ctx: Typer context.
|
|
21
|
+
name: Name of the account.
|
|
22
|
+
token: Token for authentication.
|
|
23
|
+
base_url: Base URL of the platform.
|
|
24
|
+
default: Set as default account.
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
import logging # noqa: PLC0415
|
|
28
|
+
|
|
29
|
+
from ghnova.config.manager import ConfigManager # noqa: PLC0415
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger("ghnova")
|
|
32
|
+
|
|
33
|
+
config_manager = ConfigManager(filename=ctx.obj["config_path"])
|
|
34
|
+
|
|
35
|
+
logger.info("Configuration path: %s", config_manager.config_path)
|
|
36
|
+
|
|
37
|
+
config_manager.load_config()
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
config_manager.update_account(name=name, token=token, base_url=base_url, is_default=default)
|
|
41
|
+
config_manager.save_config()
|
|
42
|
+
updated_entries = []
|
|
43
|
+
if token is not None:
|
|
44
|
+
updated_entries.append("token")
|
|
45
|
+
if base_url is not None:
|
|
46
|
+
updated_entries.append("base_url")
|
|
47
|
+
if default is not None:
|
|
48
|
+
updated_entries.append("default_account")
|
|
49
|
+
if updated_entries:
|
|
50
|
+
logger.info(
|
|
51
|
+
"Account '%s' updated successfully. Updated fields: %s",
|
|
52
|
+
name,
|
|
53
|
+
", ".join(updated_entries),
|
|
54
|
+
)
|
|
55
|
+
else:
|
|
56
|
+
logger.info("Account '%s' updated successfully. No fields changed.", name)
|
|
57
|
+
except ValueError as e:
|
|
58
|
+
logger.error("Error updating account: %s", e)
|
|
59
|
+
raise typer.Exit(code=1) from e
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Create command for issue CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def create_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
|
+
title: Annotated[
|
|
27
|
+
str,
|
|
28
|
+
typer.Option(
|
|
29
|
+
"--title",
|
|
30
|
+
help="The title of the issue.",
|
|
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
|
+
body: Annotated[
|
|
55
|
+
str | None,
|
|
56
|
+
typer.Option(
|
|
57
|
+
"--body",
|
|
58
|
+
help="The body of the issue.",
|
|
59
|
+
),
|
|
60
|
+
] = None,
|
|
61
|
+
assignee: Annotated[
|
|
62
|
+
str | None,
|
|
63
|
+
typer.Option(
|
|
64
|
+
"--assignee",
|
|
65
|
+
help="The assignee of the issue.",
|
|
66
|
+
),
|
|
67
|
+
] = None,
|
|
68
|
+
milestone: Annotated[
|
|
69
|
+
str | None,
|
|
70
|
+
typer.Option(
|
|
71
|
+
"--milestone",
|
|
72
|
+
help="The milestone for the issue.",
|
|
73
|
+
),
|
|
74
|
+
] = None,
|
|
75
|
+
labels: Annotated[
|
|
76
|
+
list[str] | None,
|
|
77
|
+
typer.Option(
|
|
78
|
+
"--labels",
|
|
79
|
+
help="A list of labels to assign to the issue.",
|
|
80
|
+
),
|
|
81
|
+
] = None,
|
|
82
|
+
assignees: Annotated[
|
|
83
|
+
list[str] | None,
|
|
84
|
+
typer.Option(
|
|
85
|
+
"--assignees",
|
|
86
|
+
help="A list of assignees to assign to the issue.",
|
|
87
|
+
),
|
|
88
|
+
] = None,
|
|
89
|
+
issue_type: Annotated[
|
|
90
|
+
str | None,
|
|
91
|
+
typer.Option(
|
|
92
|
+
"--issue-type",
|
|
93
|
+
help="The type of the issue (e.g., 'bug', 'feature').",
|
|
94
|
+
),
|
|
95
|
+
] = None,
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Create a new issue in a repository.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
ctx: Typer context.
|
|
101
|
+
owner: The owner of the repository.
|
|
102
|
+
repository: The name of the repository.
|
|
103
|
+
title: The title of the issue.
|
|
104
|
+
account_name: Name of the account to use for authentication.
|
|
105
|
+
token: Token for authentication.
|
|
106
|
+
base_url: Base URL of the GitHub platform.
|
|
107
|
+
body: The body of the issue.
|
|
108
|
+
assignee: The assignee of the issue.
|
|
109
|
+
milestone: The milestone for the issue.
|
|
110
|
+
labels: A list of labels to assign to the issue.
|
|
111
|
+
assignees: A list of assignees to assign to the issue.
|
|
112
|
+
issue_type: The type of the issue.
|
|
113
|
+
|
|
114
|
+
"""
|
|
115
|
+
import json # noqa: PLC0415
|
|
116
|
+
import logging # noqa: PLC0415
|
|
117
|
+
|
|
118
|
+
from ghnova.cli.utils.auth import get_auth_params # noqa: PLC0415
|
|
119
|
+
from ghnova.client.github import GitHub # noqa: PLC0415
|
|
120
|
+
|
|
121
|
+
logger = logging.getLogger("ghnova")
|
|
122
|
+
|
|
123
|
+
token, base_url = get_auth_params(
|
|
124
|
+
config_path=ctx.obj["config_path"],
|
|
125
|
+
account_name=account_name,
|
|
126
|
+
token=token,
|
|
127
|
+
base_url=base_url,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
with GitHub(token=token, base_url=base_url) as client:
|
|
132
|
+
issue_client = client.issue
|
|
133
|
+
data, status_code, etag_value, last_modified_value = issue_client.create_issue(
|
|
134
|
+
owner=owner,
|
|
135
|
+
repository=repository,
|
|
136
|
+
title=title,
|
|
137
|
+
body=body,
|
|
138
|
+
assignee=assignee,
|
|
139
|
+
milestone=milestone,
|
|
140
|
+
labels=labels,
|
|
141
|
+
assignees=assignees,
|
|
142
|
+
issue_type=issue_type,
|
|
143
|
+
)
|
|
144
|
+
result = {
|
|
145
|
+
"data": data,
|
|
146
|
+
"metadata": {
|
|
147
|
+
"status_code": status_code,
|
|
148
|
+
"etag": etag_value,
|
|
149
|
+
"last_modified": last_modified_value,
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
print(json.dumps(result, indent=2, default=str))
|
|
153
|
+
except Exception as e:
|
|
154
|
+
logger.error("Error creating issue: %s", e)
|
|
155
|
+
raise typer.Exit(code=1) from e
|
ghnova/cli/issue/get.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Get command for issue CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_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
|
+
etag: Annotated[
|
|
55
|
+
str | None,
|
|
56
|
+
typer.Option(
|
|
57
|
+
"--etag",
|
|
58
|
+
help="ETag from a previous request for caching purposes.",
|
|
59
|
+
),
|
|
60
|
+
] = None,
|
|
61
|
+
last_modified: Annotated[
|
|
62
|
+
str | None,
|
|
63
|
+
typer.Option(
|
|
64
|
+
"--last-modified",
|
|
65
|
+
help="Last-Modified header from a previous request for caching purposes.",
|
|
66
|
+
),
|
|
67
|
+
] = None,
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Get a specific issue by owner, repository, and issue number.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
ctx: Typer context.
|
|
73
|
+
owner: The owner of the repository.
|
|
74
|
+
repository: The name of the repository.
|
|
75
|
+
issue_number: The issue number.
|
|
76
|
+
account_name: Name of the account to use for authentication.
|
|
77
|
+
token: Token for authentication.
|
|
78
|
+
base_url: Base URL of the GitHub platform.
|
|
79
|
+
etag: ETag from a previous request for caching purposes.
|
|
80
|
+
last_modified: Last-Modified header from a previous request for caching purposes.
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
import json # noqa: PLC0415
|
|
84
|
+
import logging # noqa: PLC0415
|
|
85
|
+
|
|
86
|
+
from ghnova.cli.utils.auth import get_auth_params # noqa: PLC0415
|
|
87
|
+
from ghnova.client.github import GitHub # noqa: PLC0415
|
|
88
|
+
|
|
89
|
+
logger = logging.getLogger("ghnova")
|
|
90
|
+
|
|
91
|
+
token, base_url = get_auth_params(
|
|
92
|
+
config_path=ctx.obj["config_path"],
|
|
93
|
+
account_name=account_name,
|
|
94
|
+
token=token,
|
|
95
|
+
base_url=base_url,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
with GitHub(token=token, base_url=base_url) as client:
|
|
100
|
+
issue_client = client.issue
|
|
101
|
+
data, status_code, etag_value, last_modified_value = issue_client.get_issue(
|
|
102
|
+
owner=owner,
|
|
103
|
+
repository=repository,
|
|
104
|
+
issue_number=issue_number,
|
|
105
|
+
etag=etag,
|
|
106
|
+
last_modified=last_modified,
|
|
107
|
+
)
|
|
108
|
+
result = {
|
|
109
|
+
"data": data,
|
|
110
|
+
"metadata": {
|
|
111
|
+
"status_code": status_code,
|
|
112
|
+
"etag": etag_value,
|
|
113
|
+
"last_modified": last_modified_value,
|
|
114
|
+
},
|
|
115
|
+
}
|
|
116
|
+
print(json.dumps(result, indent=2, default=str))
|
|
117
|
+
except Exception as e:
|
|
118
|
+
logger.error("Error retrieving issue: %s", e)
|
|
119
|
+
raise typer.Exit(code=1) from e
|