[This is long and in parts is something of a rant. You have been
forewarned!]
The current Parrot configuration system is essentially a harness.
P::C::runsteps() will go from one step to the next regardless of whether
the first step completes successfully. So critical failures don't cause
configuration as a whole to abort.
But 'critical' is in the eye of the beholder.
Take configuration step #1, init::manifest, for example. Currently,
when it fails to locate all the files listed in the MANIFEST, it
complains -- or, more precisely, acks -- about missing files and then
allows config step #2 to begin. When this has happened to me, I tend to
make a mental note, I continue to hack on whatever I was doing, and then
resolve the question of the missing file before my next 'svn ci' and
'perl Configure.pl'. That's because I'm usually more interested in
what's happening in step #10 or #12 than I am in immediately correcting
step #1. But, as we saw recently, other dedicated Parrot developers may
feel that step #1 should cause the whole configuration process to come
to an immediate halt.
(I should note that init::manifest is more polite than other config
steps in that it prints an helpful failure message to STDOUT when it fails.)
The problem is: We have no way by which to 'objectively' measure the
relative criticality of the particular configuration steps. If we were
to decide that, say, a failure in inter::progs is so serious that
configuration should grind to a halt, what is there to prevent someone
from saying, "Hey! What about step x::y? Isn't that equally as
critical as inter::progs?"
So I think our alternatives are either:
(1) Retain the current system, in which the failure of one step does not
prevent Configure.pl from attempting the next step.
(2) Jettison the current system completely and require that each config
step demonstrate (say, by returning a true value rather than 'undef')
that it has completed successfully.
(3) Have the Parrot leadership make an explicitly subjective judgment
that some config steps are more equal than others and allow them to have
a different interface (specifically, different return values) from all
the others.
Personally, I think (1) is the best choice.
But that doesn't make me a fan of the current configuration system by
any means. The current system was designed long before I joined the
Parrot project, so I have no ego investment in it.
The current system consists of 58 separate programs which vary markedly
in terms of purpose and complexity. The only things they share in
common are (a) that they are required to have a $description and a sub
runstep() to fit into the harness run by Parrot::Configure::runsteps and
(b) that they return either a Parrot::Configure::Step object or 'undef'.
The most common reason to place code in a subroutine is code re-use,
but none of the 58 different step runstep() subroutines is ever re-used.
We could just as easily rename each of them main() and pretend we're
writing bad C.
The fact that virtually all the functionality of any particular Parrot
configuration step is packed into a single runstep() subroutine means
that for such a subroutine it is darn near impossible to follow the
maxim, "Have your subroutine do one thing and do it well."
It also means -- and here comes the place where I have major ego
investment -- that many of the step runstep() routines are difficult to
test thoroughly. Since June I have been writing tests for the
config/*/*.pm packages in the reconfigure/ branch and, as they have
matured, have brought them into trunk. But the fact that only about 13
of the 58 config steps are yet represented by tests in t/configure/ is
testimony to the difficulty in thoroughly testing many of them.
And I hate code that I cannot test thoroughly. (In fact, I'm going to
use it as an example of untestable and uncoverable code in my talk on
coverage analysis at Pittsburgh Perl Workshop next month.)
Nonetheless, the fact is that while the design of the Parrot
configuration process is less than ideal, it is good enough for most of
us most of the time. Most of the time, it does not prevent the compiler
developers from working on the PMCs, the C code and all that other
mysterious (to me) stuff. Most of the time, the configuration process
does not prevent the language developers from trying to port languages
to Parrot. So, as much as I dislike aspects of the configuration
process's design, it is not the main problem with Parrot right now --
either code-wise or human-wise.
I'm eager to work with other Parrot developers at planning for the
evolution of the configuration process (e.g., the file-based
configuration suggested by particle), but I think we should be cautious
about overhauling the current system and even more cautious about
allowing particular configuration steps to behave differently from others.
kid51