Description
Is your feature request related to a problem? Please describe.
This is a similar to but not exactly the same situation as in #3576, where black's current behavior causes the inferred project root directory to be the file system root directory (/
), which makes it difficult to set up exclude paths in black's config file.
In our situation, we also have a multi-language monorepo with multiple pyproject.toml-based Python packages, but we also have a handful of non-package Python scripts spread throughout the repo. These scripts do the kinds of things you'd typically put in bash scripts, except written in Python, and we just directly invoke them instead of building wheels/installing them into a virtualenv. For our project, it does not make sense to place a pyproject.toml file at the root of our repository, since we have a multi-language monorepo.
In addition, we have a custom, in-house-developed build system that I could best describe as something similar to Bazel and Nix, where we care about hermetic builds and run commands within a sandboxed environment that only contains the files have been explicitly exposed to the command's sandbox. Specifically, we do not send the .git/
directory into our sandbox, which means it's invisible to commands that are run within the sandbox, such as black
.
The net result of not having a pyproject.toml at our repository root and not having a visible .git/ directory due to our build system is that black's default behavior is to infer a project root directory of the file system root, /
. This in turn causes the same issue as #712, where the exclude paths in config files have to be absolute.
If my custom build system scenario is a bit too opaque/weird, then let me offer a hypothetical but realistic situation: Anyone with a monorepo that is not using Git or Mercurial as the version control system will also have an inferred project root of /
, since .git/
and .hg/
are the only two version control directories that are detected by find_project_root()
.
Describe the solution you'd like
I would like for the ability to just directly specify the project root directory from the black
command-line interface so that my excludes paths in a config file can be relative to some known path. An example of this usage could be:
$ black --config linter-configs/black.toml --project-root .
# Alternatively, making the caller specify an absolute path is also fine
$ black --config linter-configs/black.toml --project-root $PWD
Describe alternatives you've considered
My current workaround is to not use the excludes
setting in black at all, and instead write a wrapper script to find all the .py
files I want to run black on and pass them individually and explicitly in the black command.
#3576 suggests interpreting the exclude paths relative to the config file itself, which would work for me.
#1826, which suggests having config files include other config files, would possibly work for our pyproject.toml-based projects, but not for the non-project "bash-like" Python scripts in our repo.
#712 (comment) suggestion to return the nearest common ancestor directory rather than the file system root could possibly work, at least as long as we have Python files to format in different branches of the repository root directory. I think it's probably unintuitive to most people that black will default to the file system root when a pyproject.toml, a .git/, or .hg/ isn't found.
Additional context
If this sounds reasonable, I'm happy to take a stab at contributing the feature.
Activity