Skip to content

Commit

Permalink
Merge pull request #8 from Cadair/tox4
Browse files Browse the repository at this point in the history
  • Loading branch information
astrofrog authored Mar 8, 2023
2 parents bb6375d + c3d00d3 commit abccf00
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 72 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ jobs:
uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@v1
with:
submodules: false
toxdeps: "'tox<4'"
envs: |
- linux: codestyle
- windows: py38-test-cli
Expand Down
25 changes: 23 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = 'setuptools.build_meta'
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"

[project]
name = "tox-pypi-filter"
authors = [
{name = "Thomas Robitaille", email = "thomas.robitaille@gmail.com"},
{name = "Stuart Mumford", email = "stuart@cadair.com"},
]
description = "Implement a --pypi-filter option for tox"
readme = "README.rst"
requires-python = ">=3.8"
license = {text = "BSD-2-Clause"}
dependencies = [
"tox>=4.0.9",
"pypicky>=0.5"
]
dynamic = ["version"]

[project.entry-points."tox"]
pypi-filter = "tox_pypi_filter.plugin"

[tool.setuptools_scm]
29 changes: 0 additions & 29 deletions setup.cfg

This file was deleted.

2 changes: 0 additions & 2 deletions setup.py

This file was deleted.

88 changes: 50 additions & 38 deletions tox_pypi_filter/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@
import urllib.parse
import urllib.request
from textwrap import indent
from typing import Any

from tox.plugin import impl
from tox.tox_env.api import ToxEnv
from tox.config.cli.parser import ToxParser
from tox.config.sets import EnvConfigSet
from tox.session.state import State

import pluggy
from pkg_resources import DistributionNotFound, get_distribution

try:
__version__ = get_distribution(__name__).version
except DistributionNotFound:
pass

hookimpl = pluggy.HookimplMarker("tox")

HELP = ("Specify version constraints for packages which are then applied by "
"setting up a proxy PyPI server. If giving multiple constraints, you "
Expand All @@ -25,24 +30,31 @@
"http://, https://, or ftp://).")


@hookimpl
def tox_addoption(parser):
parser.add_argument('--pypi-filter', dest='pypi_filter', help=HELP)
parser.add_testenv_attribute('pypi_filter', 'string', help=HELP)
@impl
def tox_add_option(parser: ToxParser) -> None:
parser.add_argument('--pypi-filter', action="store", type=str, of_type=str)


SERVER_PROCESS = {}
SERVER_URLS = {}


@impl
def tox_add_env_config(env_conf: EnvConfigSet, state: State) -> None:
env_conf.add_config('pypi_filter', default=None, desc=HELP, of_type=str)


@hookimpl
def tox_testenv_create(venv, action):
# Skip the environment used for creating the tarball
if venv.name == ".package":
@impl
def tox_on_install(tox_env: ToxEnv, arguments: Any, section: str, of_type: str) -> None:
# Do not set the environment variable for the custom index if we are in the .pkg step
if tox_env.name == ".pkg":
return

global SERVER_PROCESS
global SERVER_PROCESS, SERVER_URLS

pypi_filter = venv.envconfig.config.option.pypi_filter or venv.envconfig.pypi_filter
pypi_filter_config = tox_env.conf.load("pypi_filter")
pypi_filter_cli = tox_env.options.pypi_filter
pypi_filter = pypi_filter_cli or pypi_filter_config

if not pypi_filter:
return
Expand All @@ -61,44 +73,44 @@ def tox_testenv_create(venv, action):

# If we get a blank set of requirements then we don't do anything.
with open(reqfile, "r") as fobj:
contents = fobj.read()
contents = fobj.readlines()
contents = list(filter(lambda line: not line.startswith("#"), contents))
if not contents:
return
contents = "\n".join(contents)

# Find available port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 0))
port = sock.getsockname()[1]
sock.close()
# We might have already setup the process for this env at an earlier call of this function.
if tox_env.name not in SERVER_PROCESS:
# Find available port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 0))
port = sock.getsockname()[1]
sock.close()

# Run pypicky
print(f"{venv.name}: Starting tox-pypi-filter server with the following requirements:")
print(indent(contents.strip(), ' '))
# Run pypicky
print(f"{tox_env.name}: Starting tox-pypi-filter server with the following requirements:")
print(indent(contents.strip(), ' '))

SERVER_PROCESS[venv.name] = subprocess.Popen([sys.executable, '-m', 'pypicky',
reqfile, '--port', str(port), '--quiet'])
SERVER_URLS[tox_env.name] = f'http://localhost:{port}'
SERVER_PROCESS[tox_env.name] = subprocess.Popen([sys.executable, '-m', 'pypicky',
reqfile, '--port', str(port), '--quiet'])

# FIXME: properly check that the server has started up
time.sleep(2)

venv.envconfig.config.indexserver['default'].url = f'http://localhost:{port}'
# If PIP_INDEX_URL is configured in config it will conflict
if "PIP_INDEX_URL" in tox_env.conf.load("setenv"):
raise ValueError("Can not use tox-pypi-filter if already setting the PIP_INDEX_URL env var.")

# Add the index url to the env vars just for this install (as oppsed to the global config)
tox_env.environment_variables["PIP_INDEX_URL"] = SERVER_URLS[tox_env.name]


@hookimpl
def tox_runtest_post(venv):
@impl
def tox_env_teardown(tox_env):
global SERVER_PROCESS

proc = SERVER_PROCESS.pop(venv.name, None)
proc = SERVER_PROCESS.pop(tox_env.name, None)
if proc:
print(f"{venv.name}: Shutting down tox-pypi-filter server")
print(f"{tox_env.name}: Shutting down tox-pypi-filter server")
proc.terminate()


@hookimpl
def tox_cleanup(session):
global SERVER_PROCESS

for venv, process in SERVER_PROCESS.items():
print(f"{venv}: Shutting down tox-pypi-filter server.")
process.terminate()
SERVER_PROCESS = {}

0 comments on commit abccf00

Please sign in to comment.