pydoit / doit

CLI task management & automation tool
http://pydoit.org
MIT License
1.84k stars 175 forks source link

Problems with interaction between config files and --seek-file/--file #452

Open levic opened 1 year ago

levic commented 1 year ago

(macOS, python3.11, doit 0.36.0)

Use case I'd like to be able to invoke doit from anywhere in a project tree.

For brevity, when I write --seek-file/--file I'm also including the environment variables DOIT_SEEK_FILE/DOIT_FILE

Example:

(Related: #222)

Problem/Bug: Despite specifying --seek-file/--file config files will only be loaded from the current directory, and not every config option can be specified in a dodo.py DOIT_CONFIG

Details

[1a] Config files are initially checked in DoitMain.__init__() using the current directory. This takes place before --seek-file/--file have any effect. This means that only config files in the current directory work.

[1b] If there are multiple pyproject.toml files in your directory tree then you can get different behaviour depending on where you invoke doit.

An example: You cd into a virtualenv to examine an installed package's code. This package has its own pyproject.toml with doit configuration. When you run doit the that package's directory then its doit config will be used -- even though you have specified --file.

While this is an expected risk if using --seek-file, as a developer this is surprising and unexpected behaviour for --file. I would expect that specifying --file would mean only my configuration is used.

[2] We need the ability to specify a config file because not all options work with DOIT_CONFIG

Consider cwdPath:

One way to work around this is to wrap every task with a decorator that inserts a new action to change the current directory, but that would have to be done to every task.

A better way of handling it would be to create a custom loader. We could subclass DodoTaskLoader and override load_doit_config() to change the current directory if cwdPath is set in DOIT_CONFIG. The problem is that a custom Loader can only be specified through the config file because plugins are loaded before DOIT_CONFIG is read.

Since the loader is responsible for loading DOIT_CONFIG we have a circular dependency.

Possible Solutions

Option 1:

Add a new --config-file/DOIT_CONFIG_FILE option & environment variable.

Option 2:

If --seek-file/--file is specified, the config file will always be assumed to be in the same directory as dodo.py

If @schettino72 is happy with Option 2 then I'm willing to take a look at implementing it.

It's not as simple a change as I initially thought because the config file loading takes place before the command line argument parsing (and the results are used to set the command line argument defaults). To preserve this behaviour would mean refactoring to load the config file options twice -- once before the command line arguments are parsed and once afterwards.

Fund with Polar

rix0rrr commented 9 months ago

I'm running into this at well.

Wouldn't it be sufficient/nicer to search upwards for the dodo.py file, from the current directory?

schettino72 commented 9 months ago

I think that config files (pyrpoject.toml or doit.cfg) should always be on the same path as dodo.py.

Would that solve the problem? That should be easy to fix...