Skip to content

Commit

Permalink
✨ lock refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
juftin committed Feb 1, 2024
1 parent 00afadd commit a29f845
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 35 deletions.
52 changes: 26 additions & 26 deletions hatch_pip_compile/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@
hatch-pip-compile header operations
"""

from __future__ import annotations

import hashlib
import logging
import pathlib
import re
from dataclasses import dataclass
from textwrap import dedent
from typing import Iterable, List, Optional
from typing import TYPE_CHECKING, Iterable

from hatch.env.virtual import VirtualEnv
from packaging.requirements import Requirement
from packaging.version import Version
from piptools._compat.pip_compat import PipSession, parse_requirements

from hatch_pip_compile.exceptions import LockFileError

if TYPE_CHECKING:
from hatch_pip_compile.plugin import PipCompileEnvironment

logger = logging.getLogger(__name__)


Expand All @@ -26,13 +30,7 @@ class PipCompileLock:
Pip Compile Lock File Operations
"""

lock_file: pathlib.Path
dependencies: List[str]
project_root: pathlib.Path
constraints_file: Optional[pathlib.Path]
env_name: str
project_name: str
virtualenv: Optional[VirtualEnv] = None
environment: PipCompileEnvironment

def process_lock(self, lockfile: pathlib.Path) -> None:
"""
Expand All @@ -45,18 +43,20 @@ def process_lock(self, lockfile: pathlib.Path) -> None:
#
"""
prefix = dedent(raw_prefix).strip()
joined_dependencies = "\n".join([f"# - {dep}" for dep in self.dependencies])
joined_dependencies = "\n".join([f"# - {dep}" for dep in self.environment.dependencies])
lockfile_text = lockfile.read_text()
cleaned_input_file = re.sub(
rf"-r \S*/{self.env_name}\.in",
f"hatch.envs.{self.env_name}",
rf"-r \S*/{self.environment.name}\.in",
f"hatch.envs.{self.environment.name}",
lockfile_text,
)
if self.constraints_file is not None:
lockfile_contents = self.constraints_file.read_bytes()
if self.environment.piptools_constraints_file is not None:
lockfile_contents = self.environment.piptools_constraints_file.read_bytes()
cross_platform_contents = lockfile_contents.replace(b"\r\n", b"\n")
constraint_sha = hashlib.sha256(cross_platform_contents).hexdigest()
constraints_path = self.constraints_file.relative_to(self.project_root).as_posix()
constraints_path = self.environment.piptools_constraints_file.relative_to(
self.environment.root
).as_posix()
constraints_line = f"# [constraints] {constraints_path} (SHA256: {constraint_sha})"
joined_dependencies = "\n".join([constraints_line, "#", joined_dependencies])
cleaned_input_file = re.sub(
Expand All @@ -68,11 +68,11 @@ def process_lock(self, lockfile: pathlib.Path) -> None:
new_text = prefix + "\n\n" + cleaned_input_file
lockfile.write_text(new_text)

def read_header_requirements(self) -> List[Requirement]:
def read_header_requirements(self) -> list[Requirement]:
"""
Read requirements from lock file header
"""
lock_file_text = self.lock_file.read_text()
lock_file_text = self.environment.piptools_lock_file.read_text()
parsed_requirements = []
for line in lock_file_text.splitlines():
if line.startswith("# - "):
Expand All @@ -90,8 +90,8 @@ def current_python_version(self) -> Version:
In the case of running as a hatch plugin, the `virtualenv` will be set,
otherwise it will be None and the Python version will be read differently.
"""
if self.virtualenv is not None:
return Version(self.virtualenv.environment["python_version"])
if self.environment.virtual_env is not None:
return Version(self.environment.virtual_env.environment["python_version"])
else:
msg = "VirtualEnv is not set"
raise NotImplementedError(msg)
Expand All @@ -101,7 +101,7 @@ def lock_file_version(self) -> Version:
"""
Get lock file version
"""
lock_file_text = self.lock_file.read_text()
lock_file_text = self.environment.piptools_lock_file.read_text()
match = re.search(
r"# This file is autogenerated by hatch-pip-compile with Python (.*)", lock_file_text
)
Expand All @@ -110,7 +110,7 @@ def lock_file_version(self) -> Version:
raise LockFileError(msg)
return Version(match.group(1))

def compare_python_versions(self, verbose: Optional[bool] = None) -> bool:
def compare_python_versions(self, verbose: bool | None = None) -> bool:
"""
Compare python versions
Expand Down Expand Up @@ -148,7 +148,7 @@ def compare_constraint_sha(self, sha: str) -> bool:
"""
Compare SHA to the SHA on the lockfile
"""
lock_file_text = self.lock_file.read_text()
lock_file_text = self.environment.piptools_lock_file.read_text()
match = re.search(r"# \[constraints\] \S* \(SHA256: (.*)\)", lock_file_text)
if match is None:
return False
Expand All @@ -158,18 +158,18 @@ def get_file_content_hash(self) -> str:
"""
Get hash of lock file
"""
lockfile_contents = self.lock_file.read_bytes()
lockfile_contents = self.environment.piptools_lock_file.read_bytes()
cross_platform_contents = lockfile_contents.replace(b"\r\n", b"\n")
return hashlib.sha256(cross_platform_contents).hexdigest()

def read_lock_requirements(self) -> List[Requirement]:
def read_lock_requirements(self) -> list[Requirement]:
"""
Read all requirements from lock file
"""
if not self.dependencies:
if not self.environment.dependencies:
return []
install_requirements = parse_requirements(
str(self.lock_file),
str(self.environment.piptools_lock_file),
session=PipSession(),
)
return [ireq.req for ireq in install_requirements] # type: ignore[misc]
10 changes: 1 addition & 9 deletions hatch_pip_compile/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,7 @@ def __init__(self, *args, **kwargs) -> None:
with self.metadata.context.apply_context(self.context):
lock_filename = self.metadata.context.format(lock_filename_config)
self.piptools_lock_file = self.root / lock_filename
self.piptools_lock = PipCompileLock(
lock_file=self.piptools_lock_file,
dependencies=self.dependencies,
virtualenv=self.virtual_env,
constraints_file=self.piptools_constraints_file,
project_root=self.root,
env_name=self.name,
project_name=self.metadata.name,
)
self.piptools_lock = PipCompileLock(environment=self)
install_method = self.config.get("pip-compile-installer", "pip")
self.installer: PluginInstaller
if install_method == "pip":
Expand Down

0 comments on commit a29f845

Please sign in to comment.