-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathcommand.py
More file actions
142 lines (121 loc) · 4.71 KB
/
command.py
File metadata and controls
142 lines (121 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from __future__ import annotations
from pathlib import Path
from typing import TYPE_CHECKING
from cleo.helpers import option
from packaging.utils import NormalizedName
from packaging.utils import canonicalize_name
from poetry.console.commands.group_command import GroupCommand
from poetry.core.packages.dependency_group import MAIN_GROUP
from poetry_plugin_export.exporter import Exporter
if TYPE_CHECKING:
from collections.abc import Iterable
class ExportCommand(GroupCommand):
name = "export"
description = "Exports the lock file to alternative formats."
options = [ # noqa: RUF012
option(
"format",
"f",
"Format to export to. Currently, only constraints.txt and"
" requirements.txt are supported.",
flag=False,
default=Exporter.FORMAT_REQUIREMENTS_TXT,
),
option("output", "o", "The name of the output file.", flag=False),
option("without-hashes", None, "Exclude hashes from the exported file."),
option(
"without-urls",
None,
"Exclude source repository urls from the exported file.",
),
option(
"dev",
None,
"Include development dependencies. (<warning>Deprecated</warning>)",
),
*GroupCommand._group_dependency_options(),
option(
"extras",
"E",
"Extra sets of dependencies to include.",
flag=False,
multiple=True,
),
option("all-extras", None, "Include all sets of extra dependencies."),
option("with-credentials", None, "Include credentials for extra indices."),
option(
"exclude",
None,
"The names of dependencies to exclude along with nested dependencies when"
" exporting.",
flag=False,
multiple=True,
),
]
@property
def non_optional_groups(self) -> set[str]:
# method only required for poetry <= 1.2.0-beta.2.dev0
return {MAIN_GROUP}
@property
def default_groups(self) -> set[str]:
return {MAIN_GROUP}
def handle(self) -> int:
fmt = self.option("format")
if not Exporter.is_format_supported(fmt):
raise ValueError(f"Invalid export format: {fmt}")
output = self.option("output")
locker = self.poetry.locker
if not locker.is_locked():
self.line_error("<comment>The lock file does not exist. Locking.</comment>")
options = []
if self.io.is_debug():
options.append(("-vvv", None))
elif self.io.is_very_verbose():
options.append(("-vv", None))
elif self.io.is_verbose():
options.append(("-v", None))
self.call("lock", " ".join(options)) # type: ignore[arg-type]
if not locker.is_fresh():
self.line_error(
"<warning>"
"Warning: poetry.lock is not consistent with pyproject.toml. "
"You may be getting improper dependencies. "
"Run `poetry lock [--no-update]` to fix it."
"</warning>"
)
# Checking extras
if self.option("extras") and self.option("all-extras"):
self.line_error(
"<error>You cannot specify explicit"
" `<fg=yellow;options=bold>--extras</>` while exporting"
" using `<fg=yellow;options=bold>--all-extras</>`.</error>"
)
return 1
extras: Iterable[NormalizedName]
if self.option("all-extras"):
extras = self.poetry.package.extras.keys()
else:
extras = {
canonicalize_name(extra)
for extra_opt in self.option("extras")
for extra in extra_opt.split()
}
invalid_extras = extras - self.poetry.package.extras.keys()
if invalid_extras:
raise ValueError(
f"Extra [{', '.join(sorted(invalid_extras))}] is not specified."
)
excludes = {
canonicalize_name(exclude)
for exclude_opt in self.option("exclude")
for exclude in exclude_opt.split()
}
exporter = Exporter(self.poetry, self.io)
exporter.only_groups(list(self.activated_groups))
exporter.with_extras(list(extras))
exporter.with_hashes(not self.option("without-hashes"))
exporter.with_credentials(self.option("with-credentials"))
exporter.with_urls(not self.option("without-urls"))
exporter.with_excludes(list(excludes))
exporter.export(fmt, Path.cwd(), output or self.io)
return 0