Description
Since #14953 the compiler can run external executables as subcommands as an alternative to builtin commands.
This kind of subcommand delegation needs to ensure consistency in the compiler version being used.
For example, let's run path/to/crystal subcommand
which calls crystal-subcommand
from somewhere in $PATH
. The subcommand needs to be aware that the target compiler is path/to/crystal
, not whatever crystal
is in $PATH
.
The current solution from #14953 passes the environment variable $CRYSTAL
to the subcommand which has the full path to the compiler.
I don't think it works very well. It requires the subcommand to recognize the environment variable. But it must also expect it to be unset when the command is executed directly (as crystal-subcommand
). And this trickles down to other processes that the subcommand might spawn. They typically should also be aware of the target crystal compiler. This is practically impossible to realize with the $CRYSTAL
environment variable.
git
uses a similar mechanism to run subcommands and handles propagating the target instance in a different way: It prepends the path to the parent directory of the executable to $PATH
. That means if the subcommand process calls git
, it'll resolve to the original one. Path lookup just works when the subcommand is executed directly.
Additionally, git
also puts this directory path in the environment variable $GIT_EXEC_PATH
. I'm not familiar with the specific details when one is used over the other, but it looks like the prepended $PATH
and $GIT_EXEC_PATH
are identical.
I think we should add the compiler's parent directory to $PATH
. This feature is still brand new and AFAIK not actively used, so I think it should be acceptable to replace the $CRYSTAL
variable. We could consider keeping it along, but if we do that, we'll need to do that for a long time. I think it's better to drop it in order to avoid new subcommands ever depend on it.
Introducing a separate $CRYSTAL_EXEC_PATH
could also be valuable. I believe it could be a more generic replacement to $CRYSTAL_SPEC_COMPILER_BIN
which we use in the spec suite.