bootstrap topologically sorts packages before installing them them to ensure dependencies exist before being required, which is awesome. This behavior would be valuable to have with the run command as well. I work on a Typescript-based project, and if I change the interface of a package and want to rebuild everything, I have to make sure I run things in the right order manually or shoehorn it into prepublish and depend on bootstrap to do it the right way. I currently do the latter, but it's somewhat clunky since I incur the entire cost of bootstrap just to recompile a couple things (since bootstrap isn't scope-able: #341) and it's not really documented behavior anyway. Consistency between commands also seems valuable (perhaps appropriate for exec as well?).
Code-wise, I'm thinking that BootstrapCommand could delegate to RunCommand (or they delegate to a shared method), and that this method could have some kind of --toposort flag. Not sure if said flag should be default on/off, nor if bootstrap should have a different default. I suggest the flag only because there are potential performance implications: I use --concurrency 16 in CI; if everything was uncontrollably bottlenecked on a few dependencies when it didn't need to be I would be sad. If that wasn't a concern, unconditionally toposorting would probably be the way to go.
Alternately, a more complex toposorting could be used such that a concurrent task fetches the next package that has no unfinished dependents. This would make the flag less useful (though bottlenecking is still possible, it's less likely). This method would be slightly more complicated than just toposort-and-run (which is what bootstrap does now, though in a batched way) since you have to make sure dependencies have actually finished before starting a dependent (since we're not single-threaded).
bootstraptopologically sorts packages before installing them them to ensure dependencies exist before being required, which is awesome. This behavior would be valuable to have with theruncommand as well. I work on a Typescript-based project, and if I change the interface of a package and want to rebuild everything, I have to make sure I run things in the right order manually or shoehorn it intoprepublishand depend onbootstrapto do it the right way. I currently do the latter, but it's somewhat clunky since I incur the entire cost ofbootstrapjust to recompile a couple things (sincebootstrapisn't scope-able: #341) and it's not really documented behavior anyway. Consistency between commands also seems valuable (perhaps appropriate forexecas well?).Code-wise, I'm thinking that
BootstrapCommandcould delegate toRunCommand(or they delegate to a shared method), and that this method could have some kind of--toposortflag. Not sure if said flag should be default on/off, nor if bootstrap should have a different default. I suggest the flag only because there are potential performance implications: I use--concurrency 16in CI; if everything was uncontrollably bottlenecked on a few dependencies when it didn't need to be I would be sad. If that wasn't a concern, unconditionally toposorting would probably be the way to go.Alternately, a more complex toposorting could be used such that a concurrent task fetches the next package that has no unfinished dependents. This would make the flag less useful (though bottlenecking is still possible, it's less likely). This method would be slightly more complicated than just toposort-and-run (which is what bootstrap does now, though in a batched way) since you have to make sure dependencies have actually finished before starting a dependent (since we're not single-threaded).