Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix devenv when package for env is wheel/editable #2820

Merged
merged 1 commit into from Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog/2815.bugfix.rst
@@ -0,0 +1 @@
``devenv`` does not respect the specified path when the package is a wheel file - by :user:`gaborbernat`.
4 changes: 4 additions & 0 deletions src/tox/config/main.py
Expand Up @@ -7,6 +7,7 @@

from tox.config.loader.api import Loader, OverrideMap

from .loader.memory import MemoryLoader
from .loader.section import Section
from .sets import ConfigSet, CoreConfigSet, EnvConfigSet
from .source import Source
Expand Down Expand Up @@ -41,6 +42,7 @@ def __init__(
self._src = config_source
self._key_to_conf_set: dict[tuple[str, str], ConfigSet] = OrderedDict()
self._core_set: CoreConfigSet | None = None
self.memory_seed_loaders: defaultdict[str, list[MemoryLoader]] = defaultdict(list)

def pos_args(self, to_path: Path | None) -> tuple[str, ...] | None:
"""
Expand Down Expand Up @@ -132,6 +134,8 @@ def get_section_config(
except KeyError:
conf_set = of_type(self, section, for_env)
self._key_to_conf_set[key] = conf_set
if for_env is not None:
conf_set.loaders.extend(self.memory_seed_loaders.get(for_env, []))
for loader in self._src.get_loaders(section, base, self._overrides, conf_set):
conf_set.loaders.append(loader)
if loaders is not None:
Expand Down
16 changes: 8 additions & 8 deletions src/tox/session/cmd/devenv.py
Expand Up @@ -17,31 +17,31 @@
def tox_add_option(parser: ToxParser) -> None:
help_msg = "sets up a development environment at ENVDIR based on the tox configuration specified "
our = parser.add_command("devenv", ["d"], help_msg, devenv)
our.add_argument("devenv_path", metavar="path", default=Path("venv").absolute(), nargs="?")
our.add_argument("devenv_path", metavar="path", default=Path("venv"), nargs="?", type=Path)
register_env_select_flags(our, default=CliEnv("py"), multiple=False)
env_run_create_flags(our, mode="devenv")


def devenv(state: State) -> int:
opt = state.conf.options
opt.devenv_path = opt.devenv_path.absolute()
opt.skip_missing_interpreters = False # the target python must exist
opt.no_test = False # do not run the test suite
opt.package_only = False
opt.install_pkg = None # no explicit packages to install
opt.skip_pkg_install = False # always install a package in this case
opt.no_test = True # do not run the test phase
loader = MemoryLoader( # these configuration values are loaded from in-memory always (no file conf)
usedevelop=True, # dev environments must be of type dev
env_dir=opt.devenv_path, # move it in source
)
state.conf.memory_seed_loaders[list(opt.env)[0]].append(loader)

state.envs.ensure_only_run_env_is_active()
envs = list(state.envs.iter())
if len(envs) != 1:
raise HandledError(f"exactly one target environment allowed in devenv mode but found {', '.join(envs)}")
loader = MemoryLoader( # these configuration values are loaded from in-memory always (no file conf)
usedevelop=True, # dev environments must be of type dev
env_dir=Path(opt.devenv_path), # move it in source
)
tox_env = state.envs[envs[0]]
tox_env.conf.loaders.insert(0, loader)
result = run_sequential(state)
if result == 0:
logging.warning(f"created development environment under {tox_env.conf['env_dir']}")
logging.warning(f"created development environment under {opt.devenv_path}")
return result
9 changes: 6 additions & 3 deletions tests/session/cmd/test_devenv.py
Expand Up @@ -6,15 +6,18 @@


def test_devenv_fail_multiple_target(tox_project: ToxProjectCreator) -> None:
outcome = tox_project({"tox.ini": ""}).run("d", "-e", "py39,py38")
outcome = tox_project({"tox.ini": ""}).run("d", "-e", "a,b")
outcome.assert_failed()
msg = "ROOT: HandledError| exactly one target environment allowed in devenv mode but found py39, py38\n"
msg = "ROOT: HandledError| exactly one target environment allowed in devenv mode but found a, b\n"
outcome.assert_out_err(msg, "")


@pytest.mark.integration()
def test_devenv_ok(tox_project: ToxProjectCreator, enable_pip_pypi_access: str | None) -> None: # noqa: U100
content = {"setup.py": "from setuptools import setup\nsetup(name='demo', version='1.0')"}
content = {
"setup.py": "from setuptools import setup\nsetup(name='demo', version='1.0')",
"tox.ini": "[tox]\nenv_list = py\n[testenv]\nusedevelop = True",
}
project = tox_project(content)
outcome = project.run("d", "-e", "py")

Expand Down