RFC CLI Tool Proposal

## Introduction
Other OSS projects such as `scipy` and `numpy` have made use of development CLI tools such as `runtests.py` and `dev.py` to provide a collected and singular entry point into development tasks for contributors. I find these tools very helpful personally, and think they add a large amount of value, especially for onboarding new contributors. Recently Pandas has also begun discussion and implementation of their own development CLI tool. @noatamir has made a great writeup on some of the benefits and justifications for such a tool (see: https://github.com/pandas-dev/pandas/issues/47700). I highly recommend taking the time to read their writeup. 

Some of the benefits of such a tool include:
1. Increased discoverability of tools, decreasing time spent jumping around documentation. This is especially helpful for those who may not read every single word of documentation (such is my bad habit 😅).
2. Consistency for CI and development. We can establish a 1-1 between CI checks and `dev.py` commands, e.g. `dev.py lint` which could then impose both `black` and `isort` (cf. https://github.com/scikit-learn/scikit-learn/issues/22853)
3. Ease of installation. Users could install whatever dependencies are necessary depending on what workflow they want enabled. A call to `dev.py doc build` could check for the presence of the necessary dependencies and install if needed (or optionally prompt).
4. Reduced barrier to entry. Quite frankly, having to run various commands for tasks, anywhere from linting to building C sources, can be overwhelming, especially to new developers.

Recently `scipy` explored a new solution for developing a unified development CLI tool (cf. https://github.com/scipy/scipy/issues/15489) based on [`do.it`](https://pydoit.org/). Pandas is also exploring a `do.it` based [solution](https://github.com/pandas-dev/pandas/issues/47700). There's been good feedback on this framework and I would propose the same.

## Encompassed Actions
Some actions which would be wrapped by such a development CLI include:
- Dependency installation (could be per-workflow)
- Testing
- Linting
- Extension building
- Documentation building
- Pre-commit installation

## Considerations
As with all things, the question is whether the benefits outweigh the maintenance cost. While projects like scipy with many complex workflows benefit the most from such a tool, personally I think anything to decrease the barrier to entry for scikit-learn development is worth considering.

If we do opt to build such a tool, we can make use of the work already done in scipy as well as the recently released separate [`dev.py` package](https://github.com/scientific-python/dev.py). Either way, the largest modification we'd need to make is alter the `build` command to use `setuptools` instead of `meson`, though that shouldn't be too problematic.

COMMENT:
I think I'm joining Adrin in the "grumpy person" camp. I'm not a fan of "hiding" what the actual commands are inside tools. It almost doesn't matter what they are, but "old" things like `Makefiles` might be the least tricky ones because they mostly contain shell commands.

When I come to a new project (or return to one) I want to quickly see what I need to do to setup the dependencies, build the project, run the tests, etc. So the number one problem I have is quickly finding this information. And a lot of projects aren't great for this. Some of the worst are the ones that mention "Read CONTRIBUTING.md" in their README, and then in `CONTRIBUTING.md` they link to the docs, where there then is a four screen long wall of text. Lots of clicks, lots of media breaks, lots of risk that I'll just send the PR without doing anything and wait to see what the CI robots say.

So I think improving the "time to discovery" is important. Above all else. Once that time is small, then I think using "vanilla" commands is better than custom stuff. If the docs say "Setup the development dependencies with `pip install foo biz buz bar`" that is great for me. I can either copy&paste or adjust it "on the fly" because I happen to love using `mamba` and conda envs. The copy&paste works for newcomers and "translate on the fly" works for "old-timers" who want to tweak things. If the instruction says `python dev.py run-tests` then I have to go and find out what the actual command is you are running, then extract that, then do what I really wanted to do (run a subset of the tests, which is the most common test thing I do).

So overall I think improving discoverability is important. For me this is a documentation task. And it should include things like "how to bump CI deps", maybe in a section for maintainers. It also means that you need to keep the complexity low enough that you can explain it in one or two sentences.

Adding a layer on top to deal with the problem that "it is too difficult to explain" is IMHO trying to treat a patient by reducing their symptoms, not the actual illness.

Labels: RFC, workflow