It looks like the core issue is that we simply have different goals in
mind. When we were deciding on how the build description works back
then, we basically had these:
- The build description can be reasoned about in a generic way (not
generally possible with an imperative scripting language)
- It avoids security issues when doing so (DoS, attack surface for
more sophisticated attacks), so that it can be done on a server with
decent confidence and without expensive safeguards
- It avoids dependencies on the host environment, so that reasoning
about the build description can be done independently of the target
platform/environment
- Should work seamlessly for 99% of the projects, but allows to invoke
external tools to handle the rest
- Avoids any form of redundant information as far as possible (such as
compiler or OS specific compiler flags)
- Can be mapped to the typical IDE project file types, as well as to
other kinds of build descriptions
The first goals are only achievable with either a declarative approach,
or with a very limited imperative approach (which in the end is no more
powerful than the declarative one). I also think that we can easily
achieve the 99%/1% goal (if that has been reached already is difficult
to tell, but with C-class language support it will most definitely be),
and if we do, it's hard to justify why this approach with limited
expressibility should be regarded as a failure.
I'm not sure why some people insist that it must be possible to achieve
everything with one tool. Of course that is a noble goal and definitely
can have its beauty, but, assuming that the 99%/1% rule holds, it may
not be one that has much importance in practice (other than producing
controversy). On the other hand, being able to reason about the build
description without actually executing a build script on each of the
interesting platforms/environments can be a big win and we'd otherwise
lose some possibly important automation opportunities (mostly when
talking about a public web service scale).
For me, the current solution seems to be a good trade off, ignoring the
missing support for other languages for a moment. It has successfully
laid the basis for a constantly growing ecosystem of pure D packages and
now it's time to carefully support the more advanced use cases.
In this process, we can of course always go through the initial goals
and revise them where appropriate, or evaluate any other possible
approaches that can fulfill those goals. But we have to be very careful
to not make the mistake and disrupt the existing ecosystem. Backwards
compatibility is a must, and ideally any possible new approach should
fit well with the existing system (it doesn't have to fit well with the
JSON format, though, it just has to fit somehow).
One possible alternative to a full procedural build description could be
the introduction of a plugin system, where each plugin is written in D
and can be invoked from within the package description. I personally
would like to let the selection of an approach be guided by actual use
cases instead of just focusing on the maximum expressibility.