mirror of
https://github.com/smittix/intercept.git
synced 2026-05-18 13:54:49 -07:00
Merge pull request #97 from JonanOribe/fix-libs
Add optionals group to pyproject.toml and sync tests
This commit is contained in:
@@ -52,6 +52,15 @@ dev = [
|
|||||||
"types-flask>=1.1.0",
|
"types-flask>=1.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
optionals = [
|
||||||
|
"scipy>=1.10.0",
|
||||||
|
"qrcode[pil]>=7.4",
|
||||||
|
"numpy>=1.24.0",
|
||||||
|
"meshtastic>=2.0.0",
|
||||||
|
"psycopg2-binary>=2.9.9",
|
||||||
|
"scapy>=2.4.5",
|
||||||
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
intercept = "intercept:main"
|
intercept = "intercept:main"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import importlib.metadata
|
import importlib.metadata
|
||||||
import tomllib # Standard in Python 3.11+
|
import tomllib
|
||||||
|
import re
|
||||||
|
|
||||||
def get_root_path():
|
def get_root_path():
|
||||||
return Path(__file__).parent.parent
|
return Path(__file__).parent.parent
|
||||||
@@ -18,20 +19,22 @@ def parse_txt_requirements(file_path):
|
|||||||
with open(file_path, "r") as f:
|
with open(file_path, "r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
# Ignore empty lines, comments, and recursive/local flags
|
|
||||||
if not line or line.startswith(("#", "-e", "git+", "-r")):
|
if not line or line.startswith(("#", "-e", "git+", "-r")):
|
||||||
continue
|
continue
|
||||||
packages.add(_clean_string(line))
|
packages.add(_clean_string(line))
|
||||||
return packages
|
return packages
|
||||||
|
|
||||||
def parse_toml_section(data, section_type="main"):
|
def parse_toml_section(data, section_type="main"):
|
||||||
"""Extracts full requirement strings from pyproject.toml."""
|
"""Extracts full requirement strings from pyproject.toml including optional sections."""
|
||||||
packages = set()
|
packages = set()
|
||||||
|
project = data.get("project", {})
|
||||||
|
|
||||||
if section_type == "main":
|
if section_type == "main":
|
||||||
deps = data.get("project", {}).get("dependencies", [])
|
deps = project.get("dependencies", [])
|
||||||
else:
|
elif section_type == "optional":
|
||||||
# Check optional-dependencies or dependency-groups
|
deps = project.get("optional-dependencies", {}).get("optionals", [])
|
||||||
deps = data.get("project", {}).get("optional-dependencies", {}).get("dev", [])
|
elif section_type == "dev":
|
||||||
|
deps = project.get("optional-dependencies", {}).get("dev", [])
|
||||||
if not deps:
|
if not deps:
|
||||||
deps = data.get("dependency-groups", {}).get("dev", [])
|
deps = data.get("dependency-groups", {}).get("dev", [])
|
||||||
|
|
||||||
@@ -48,9 +51,10 @@ def test_dependency_files_integrity():
|
|||||||
with open(toml_path, "rb") as f:
|
with open(toml_path, "rb") as f:
|
||||||
toml_data = tomllib.load(f)
|
toml_data = tomllib.load(f)
|
||||||
|
|
||||||
# Validate Production Sync
|
# Validate Production Sync (Main + Optionals)
|
||||||
txt_main = parse_txt_requirements(root / "requirements.txt")
|
txt_main = parse_txt_requirements(root / "requirements.txt")
|
||||||
toml_main = parse_toml_section(toml_data, "main")
|
toml_main = parse_toml_section(toml_data, "main") | parse_toml_section(toml_data, "optional")
|
||||||
|
|
||||||
assert txt_main == toml_main, (
|
assert txt_main == toml_main, (
|
||||||
f"Production version mismatch!\n"
|
f"Production version mismatch!\n"
|
||||||
f"Only in TXT: {txt_main - toml_main}\n"
|
f"Only in TXT: {txt_main - toml_main}\n"
|
||||||
@@ -72,7 +76,11 @@ def test_environment_vs_toml():
|
|||||||
with open(root / "pyproject.toml", "rb") as f:
|
with open(root / "pyproject.toml", "rb") as f:
|
||||||
data = tomllib.load(f)
|
data = tomllib.load(f)
|
||||||
|
|
||||||
all_declared = parse_toml_section(data, "main") | parse_toml_section(data, "dev")
|
all_declared = (
|
||||||
|
parse_toml_section(data, "main") |
|
||||||
|
parse_toml_section(data, "optional") |
|
||||||
|
parse_toml_section(data, "dev")
|
||||||
|
)
|
||||||
_verify_installation(all_declared, "TOML")
|
_verify_installation(all_declared, "TOML")
|
||||||
|
|
||||||
def test_environment_vs_requirements():
|
def test_environment_vs_requirements():
|
||||||
@@ -89,21 +97,21 @@ def _verify_installation(package_set, source_name):
|
|||||||
missing_or_wrong = []
|
missing_or_wrong = []
|
||||||
|
|
||||||
for req in package_set:
|
for req in package_set:
|
||||||
# Split name from version to check installation status
|
# Split name from version
|
||||||
# handles ==, >=, ~=, <=, > , <
|
|
||||||
import re
|
|
||||||
parts = re.split(r'==|>=|~=|<=|>|<', req)
|
parts = re.split(r'==|>=|~=|<=|>|<', req)
|
||||||
name = parts[0].strip()
|
raw_name = parts[0].strip()
|
||||||
|
|
||||||
|
# CLEAN EXTRAS: "qrcode[pil]" -> "qrcode"
|
||||||
|
clean_name = re.sub(r'\[.*\]', '', raw_name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
installed_ver = importlib.metadata.version(name)
|
installed_ver = importlib.metadata.version(clean_name)
|
||||||
# If the config uses exact versioning '==', we can do a strict check
|
|
||||||
if "==" in req:
|
if "==" in req:
|
||||||
expected_ver = req.split("==")[1].strip()
|
expected_ver = req.split("==")[1].strip()
|
||||||
if installed_ver != expected_ver:
|
if installed_ver != expected_ver:
|
||||||
missing_or_wrong.append(f"{name} (Installed: {installed_ver}, Expected: {expected_ver})")
|
missing_or_wrong.append(f"{clean_name} (Installed: {installed_ver}, Expected: {expected_ver})")
|
||||||
except importlib.metadata.PackageNotFoundError:
|
except importlib.metadata.PackageNotFoundError:
|
||||||
missing_or_wrong.append(f"{name} (Not installed)")
|
missing_or_wrong.append(f"{clean_name} (Not installed)")
|
||||||
|
|
||||||
if missing_or_wrong:
|
if missing_or_wrong:
|
||||||
pytest.fail(f"Environment out of sync with {source_name}:\n" + "\n".join(missing_or_wrong))
|
pytest.fail(f"Environment out of sync with {source_name}:\n" + "\n".join(missing_or_wrong))
|
||||||
|
|||||||
Reference in New Issue
Block a user