Comment by nrclark
Agreed with this sentiment, but with one minor modification: use a Makefile instead. Recipes are still chunks of shell, and they don’t need to produce or consume any files if you want to keep it all task-based. You get tab-completion, parallelism, a DAG, and the ability to start anywhere on the task graph that you want.
It’s possible to do all of this with a pure shell script, but then you’re probably reimplementing some or all of the list above.
Just be aware of the "Makefile effect"[1] which can easily devolve into the Makefile also being "over there", far from the application, just because it's actually a patchwork of copy-paste targets stitched together.
[1] https://news.ycombinator.com/item?id=42663231