Skip to content

Commit 2a331a3

Browse files
committed
lock: add --output
1 parent 605f3b3 commit 2a331a3

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

src/pip/_internal/commands/lock.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
with_cleanup,
1111
)
1212
from pip._internal.cli.status_codes import SUCCESS
13-
from pip._internal.models.pylock import Pylock
13+
from pip._internal.models.pylock import Pylock, is_valid_pylock_file_name
1414
from pip._internal.operations.build.build_tracker import get_build_tracker
1515
from pip._internal.req.req_install import (
1616
check_legacy_setup_py_options,
@@ -45,6 +45,17 @@ class LockCommand(RequirementCommand):
4545
%prog [options] <archive url/path> ..."""
4646

4747
def add_options(self) -> None:
48+
self.cmd_opts.add_option(
49+
cmdoptions.PipOption(
50+
"--output",
51+
"-o",
52+
dest="output_file",
53+
metavar="path",
54+
type="path",
55+
default="pylock.toml",
56+
help="Lock file name (default=pylock.toml). Use - for stdout.",
57+
)
58+
)
4859
self.cmd_opts.add_option(cmdoptions.requirements())
4960
self.cmd_opts.add_option(cmdoptions.constraints())
5061
self.cmd_opts.add_option(cmdoptions.no_deps())
@@ -131,9 +142,22 @@ def run(self, options: Values, args: List[str]) -> int:
131142

132143
requirement_set = resolver.resolve(reqs, check_supported_wheels=True)
133144

134-
pyproject_lock = Pylock.from_install_requirements(
135-
requirement_set.requirements.values(), base_dir=Path.cwd()
136-
)
137-
sys.stdout.write(pyproject_lock.as_toml())
145+
if options.output_file == "-":
146+
base_dir = Path.cwd()
147+
else:
148+
output_file_path = Path(options.output_file)
149+
if not is_valid_pylock_file_name(output_file_path):
150+
logger.warning(
151+
"%s is not a valid lock file name.",
152+
output_file_path,
153+
)
154+
base_dir = output_file_path.parent.absolute()
155+
pylock_toml = Pylock.from_install_requirements(
156+
requirement_set.requirements.values(), base_dir=base_dir
157+
).as_toml()
158+
if options.output_file == "-":
159+
sys.stdout.write(pylock_toml)
160+
else:
161+
output_file_path.write_text(pylock_toml, encoding="utf-8")
138162

139163
return SUCCESS

src/pip/_internal/models/pylock.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import dataclasses
2+
import re
23
from dataclasses import dataclass
34
from pathlib import Path
45
from typing import Any, Dict, Iterable, List, Optional, Tuple
@@ -11,6 +12,12 @@
1112
from pip._internal.req.req_install import InstallRequirement
1213
from pip._internal.utils.urls import url_to_path
1314

15+
PYLOCK_FILE_NAME_RE = re.compile(r"^pylock\.([^.]+)\.toml$")
16+
17+
18+
def is_valid_pylock_file_name(path: Path) -> bool:
19+
return path.name == "pylock.toml" or bool(re.match(PYLOCK_FILE_NAME_RE, path.name))
20+
1421

1522
def _toml_dict_factory(data: List[Tuple[str, Any]]) -> Dict[str, Any]:
1623
return {key.replace("_", "-"): value for key, value in data if value is not None}

0 commit comments

Comments
 (0)