Skip to content

Commit

Permalink
lock: add --output-file
Browse files Browse the repository at this point in the history
  • Loading branch information
sbidoul committed Feb 9, 2025
1 parent e9255e8 commit f77d21c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
35 changes: 30 additions & 5 deletions src/pip/_internal/commands/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
with_cleanup,
)
from pip._internal.cli.status_codes import SUCCESS
from pip._internal.models.pylock import Pylock
from pip._internal.models.pylock import Pylock, is_valid_pylock_file_name
from pip._internal.operations.build.build_tracker import get_build_tracker
from pip._internal.req.req_install import (
check_legacy_setup_py_options,
Expand Down Expand Up @@ -45,6 +45,18 @@ class LockCommand(RequirementCommand):
%prog [options] <archive url/path> ..."""

def add_options(self) -> None:
self.cmd_opts.add_option(
cmdoptions.PipOption(
"--output-file",
"--output",
"-o",
dest="output_file",
metavar="path",
type="path",
default="pylock.toml",
help="Lock file name (default=pylock.toml). Use - for stdout.",
)
)
self.cmd_opts.add_option(cmdoptions.requirements())
self.cmd_opts.add_option(cmdoptions.constraints())
self.cmd_opts.add_option(cmdoptions.no_deps())
Expand Down Expand Up @@ -131,9 +143,22 @@ def run(self, options: Values, args: List[str]) -> int:

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

pyproject_lock = Pylock.from_install_requirements(
requirement_set.requirements.values(), base_dir=Path.cwd()
)
sys.stdout.write(pyproject_lock.as_toml())
if options.output_file == "-":
base_dir = Path.cwd()
else:
output_file_path = Path(options.output_file)
if not is_valid_pylock_file_name(output_file_path):
logger.warning(
"%s is not a valid lock file name.",
output_file_path,
)
base_dir = output_file_path.parent.absolute()
pylock_toml = Pylock.from_install_requirements(
requirement_set.requirements.values(), base_dir=base_dir
).as_toml()
if options.output_file == "-":
sys.stdout.write(pylock_toml)
else:
output_file_path.write_text(pylock_toml, encoding="utf-8")

return SUCCESS
7 changes: 7 additions & 0 deletions src/pip/_internal/models/pylock.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import dataclasses
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Dict, Iterable, List, Optional, Tuple
Expand All @@ -11,6 +12,12 @@
from pip._internal.req.req_install import InstallRequirement
from pip._internal.utils.urls import url_to_path

PYLOCK_FILE_NAME_RE = re.compile(r"^pylock\.([^.]+)\.toml$")


def is_valid_pylock_file_name(path: Path) -> bool:
return path.name == "pylock.toml" or bool(re.match(PYLOCK_FILE_NAME_RE, path.name))


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

0 comments on commit f77d21c

Please sign in to comment.