tox-dev / tox

Command line driven CI frontend and development task automation tool.
https://tox.wiki
MIT License
3.65k stars 511 forks source link

variable assingment order inconsistency when using file| in set_env #3335

Open piotr-kubiak opened 3 weeks ago

piotr-kubiak commented 3 weeks ago

When not using file| in set_env, the variables are assigned in order (with the last value replacing any previous one, as in FOO being overwriten with QUX in my example1).

However, this behaviour is not consistent when using file|, when assingment of variables from file always take precedence (see example2, where FOO gets the value BAR from .env, and is not overwriten by subsequent assignment of QUX).

Expected:

tox.ini:

[tox]
env_list = example1,example2

[testenv]
allowlist_externals = bash
commands =
    bash -c 'env | egrep "FOO"'

[testenv:example1]
set_env = 
    FOO=BAZ
    FOO=QUX

[testenv:example2]
set_env = 
    FOO=BAZ
    file|.env
    FOO=QUX

.env:

FOO=BAR

Output:

$ tox -v
4.18.0

$ tox -e example1
FOO=QUX

$ tox -e example2
FOO=BAR
pachewise commented 2 weeks ago

The regular assignments are processed in SetEnv.__init__, while the file assignments happen in use_replacer, which is called during by build(). Would we be OK with loading these at the same time, either in the __init__ or somewhere further down the line? To me, that seems like the easiest way to make sure that order of the assignments is taken into account, and I'm leaning toward putting them all in the __init__, but doing so feels like we'd be making the constructor "bulky".

I also just started looking at this code, so I am not sure if there was a reason that the env files are loaded after. Original PR