Source code for edgetest_pip_tools.plugin
"""Plugin for refreshing a locked requirements file."""
from configparser import ConfigParser
from pathlib import Path
from typing import Any, Dict, List
import click
import pluggy
from edgetest.logger import get_logger
from edgetest.schema import Schema
from edgetest.utils import _run_command
from tomlkit import load
LOG = get_logger(__name__)
hookimpl = pluggy.HookimplMarker("edgetest")
[docs]
@hookimpl
def addoption(schema: Schema):
"""Add configuration options for pip-tools.
Parameters
----------
schema : Schema
The schema class.
"""
schema.add_globaloption(
"pip_tools",
{
"type": "dict",
"schema": {
"extras": {
"type": "list",
"coerce": "listify",
"schema": {"type": "string"},
},
"index_url": {"type": "string"},
},
},
)
[docs]
def get_reqfile(ctx: click.Context) -> Path:
"""Get the requirements file to supply to ``uv``.
Parameters
----------
ctx : click.Context
The context for the CLI call.
Returns
-------
Path
Path to the requirements file.
"""
parser: Any
if Path(ctx.params["config"]).name == "setup.cfg":
# Check for the install_requires
parser = ConfigParser()
parser.read(Path(ctx.params["config"]))
if "options" in parser and parser.get("options", "install_requires"):
reqfile = Path(ctx.params["config"])
else:
reqfile = Path(ctx.params["requirements"])
elif Path(ctx.params["config"]).name == "pyproject.toml":
with open(Path(ctx.params["config"])) as buf:
parser = load(buf)
if "dependencies" in parser["project"]:
reqfile = Path(ctx.params["config"])
else:
reqfile = Path(ctx.params["requirements"])
else:
reqfile = Path(ctx.params["requirements"])
return reqfile
[docs]
@hookimpl(tryfirst=True)
def post_run_hook(testers: List, conf: Dict):
"""Refresh a locked requirements file based on the test output."""
ctx = click.get_current_context()
if not ctx.params["export"]:
LOG.info(
"Skipping ``uv pip compile`` as the requirements have not been updated."
)
elif testers[-1].status:
reqfile = get_reqfile(ctx=ctx)
try:
options = []
if conf.get("pip_tools", {}).get("extras"):
options += [f"--extra={extra}" for extra in conf["pip_tools"]["extras"]]
if conf.get("pip_tools", {}).get("index_url"):
options.append(f"--index-url={conf['pip_tools']['index_url']}")
_run_command(
"uv",
"pip",
"compile",
"-U",
*options,
"--output-file=requirements.txt",
str(reqfile),
)
except RuntimeError:
LOG.info("Unable to update the locked requirements file")
else:
LOG.info("Skipping ``uv`` refresh as the tests didn't pass.")