I present a feature request, inspired by an environment where I wish to install both Python packages and node packages, similar to the request in StackOverflow 37187753.
I propose that instead of having a single command for the install step, tox could expose install_commands, which would be more congruous with the commands syntax. It could still accept {opts} and {packages} substitutions such that one (or more) of the commands could honor those options.
I suspect install_command was originally meant as a way to provide a bridge for other Python installers, but if the concept could be generalized to provide more functionality for install, much like CI environments do in their install steps. Then, if one wanted to add a node environment to their environment, they could do something like this:
install_commands =
pip install {opts} {packages}
nodeenv --python-virtualenv --prebuilt
Fixing this would probably address #765 and #786.
tox 3.4 introduced commands_pre and commands_post. Maybe the install_command option should be kept as is, but instead install_commands_pre and install_commands_post should be added?
That could work too, but does feel a little artificially constrained... that you can only have multiple install steps in pre or post, and that the sole install command must stand alone and special. -0
So maybe they shall all accept multiple values.
one way or another - things get rough when you have multiple requirement files/index servers. my case: some of the requirements are on one devpi server, some are on different one. So my tox.ini looks simillar to below:
[tox]
indexserver =
default = https://some.devpi.server/
the_other_one= https://some.other.devpi.server/
[testenv]
deps = -I
--no-cache-dir
-r{toxinidir}/requirements_one.txt
:the_other_one:-r{toxinidir}/requirements_other.txt
install_command = {toxinidir}/my_custom_script.sh
and the my_custom_script.sh looks like this:
#!/bin/bash
set -e
pip install "$@"
some-fancy-command-that-depends-on-the-requirements_other-file
this results in the my_custom_script.sh being invoked twice - once for each of the requirements file. And in such a form it of course fails, as after installing requirements from the "requirements-one" file the second command fails.
(TLDR: ) so to sum up - any custom actions that depend on already installed packages (but not instaling packages themselves) should be executed in a separate step - thats why it would be nice to have this install_commands_post feature :)
I'm piggybacking off of the issue, as I'm in favor of enhancing the install_commands to allow for lists of commands, but would furthermore like make {opts} and {packages} required only if dependencies are specified.
My use case is when tox works with tools like Poetry. At the moment, Poetry recommends configuring tox as follows.
[tox]
isolated_build = true
envlist = py{36,37}-unit
[testenv]
whitelist_externals = poetry
commands =
poetry install -v
poetry run pytest tests
The poetry install command therefore runs each and every time tox runs, which is unnecessary.
To that end, I would have liked to configure tox with something along the lines of the config below.
[tox]
isolated_build = true
envlist = py{36,37}-unit
[testenv]
whitelist_externals = poetry
install_commands = poetry install -v
commands =
poetry run pytest tests
Unfortunately, this raises a tox.exception.ConfigError telling me that 'install_command' must contain '{packages}' substitution.
For the record, if I add {packages} to the command (just to see), despite tox informing me that Poetry is being installed (output below), the command then raises a ModuleNotFoundError: No module named 'poetry'.
$ tox
.package create: /Users/magus/Development/url-check/.tox/.package
.package installdeps: poetry>=0.12
ERROR: invocation failed (exit code 1), logfile: /Users/magus/Development/url-check/.tox/.package/log/.package-2.log
ERROR: actionid: .package
msg: get-build-requires
cmdargs: "/Users/magus/Development/url-check/.tox/.package/bin/python -c 'import poetry.masonry.api\nimport json\n\nbackend = poetry.masonry.api\nfor_build_requires = backend.get_requires_for_build_sdist(None)\nprint(json.dumps(for_build_requires))'"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'poetry'
@jambonrose I had an idea similar to yours, but I think that I eventually managed to get it to work. I am using a fake deps, here:
[tox]
isolated_build = true
envlist = flake8, py36, py37
skipsdist=True
skip_install=True
[testenv:flake8]
basepython = python3.7
install_command = poetry {packages} -v
whitelist_externals = poetry
commands =
poetry run flake8 package
deps =
install
I also had to create an empty setup.py file just to stop tox from complaining with Could not find setup.py for directory messages
Most helpful comment
I'm piggybacking off of the issue, as I'm in favor of enhancing the
install_commandsto allow for lists of commands, but would furthermore like make{opts}and{packages}required only if dependencies are specified.My use case is when tox works with tools like Poetry. At the moment, Poetry recommends configuring tox as follows.
The
poetry installcommand therefore runs each and every timetoxruns, which is unnecessary.To that end, I would have liked to configure tox with something along the lines of the config below.
Unfortunately, this raises a
tox.exception.ConfigErrortelling me that'install_command' must contain '{packages}' substitution.For the record, if I add
{packages}to the command (just to see), despitetoxinforming me that Poetry is being installed (output below), the command then raises aModuleNotFoundError: No module named 'poetry'.