v0.0.1 first commit
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class DependencyManager:
|
||||
def __init__(self, requirements_path: Path) -> None:
|
||||
self.requirements_path = requirements_path
|
||||
|
||||
@staticmethod
|
||||
def _normalize_requirement_name(requirement_line: str) -> str:
|
||||
line = requirement_line.split(";", 1)[0].strip()
|
||||
for sep in ["==", ">=", "<=", "!=", "~=", ">", "<"]:
|
||||
if sep in line:
|
||||
line = line.split(sep, 1)[0].strip()
|
||||
break
|
||||
if "[" in line:
|
||||
line = line.split("[", 1)[0].strip()
|
||||
return line
|
||||
|
||||
def parse_requirements(self) -> list[str]:
|
||||
if not self.requirements_path.exists():
|
||||
return []
|
||||
|
||||
requirements: list[str] = []
|
||||
for raw in self.requirements_path.read_text(encoding="utf-8").splitlines():
|
||||
line = raw.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
requirements.append(line)
|
||||
return requirements
|
||||
|
||||
def _is_installed(self, requirement: str) -> bool:
|
||||
package_name = self._normalize_requirement_name(requirement)
|
||||
if not package_name:
|
||||
return True
|
||||
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-m", "pip", "show", package_name],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
check=False,
|
||||
)
|
||||
return result.returncode == 0
|
||||
|
||||
def install_missing(self) -> list[str]:
|
||||
requirements = self.parse_requirements()
|
||||
missing = [req for req in requirements if not self._is_installed(req)]
|
||||
|
||||
if missing:
|
||||
subprocess.check_call([sys.executable, "-m", "pip", "install", *missing])
|
||||
|
||||
return missing
|
||||
Reference in New Issue
Block a user