Hi Robert,
I hope you do not mind I CC this email to the list, because I think you made pretty good points and I think I also have some valid answers to them.
2009/10/19 Robert Goldman rpgoldman@sift.info:
Yes, that's right. You /do/ need to run through all of ASDF's code. I have been going through that code. I am trying to tell the list what I found there.
And I thank you for that. I probably never got as far as understanding TRAVERSE and the way it works and this is one of the reasons why I feel my design of the ASDF-ECL extensions might be very fragile.
ASDF invokes TRAVERSE to make a /plan/ for performing an operation. A plan is an ordered list of operation . component pairs. After traverse returns this plan, OPERATE loops over the ordered list, calling PERFORM on each pair.
Understood. However note one thing: these are ASDF internals. They are not "exposed" to the users and not fixed by the manual. ASDF might work equally well if one changes the way OPERATE uses the output of TRAVERSE, or if we fix an order for TRAVERSE, or if we dispense the plan-and-then-execute setup.
This means that the return values of PERFORM are /discarded/.
Not necesseraly.
It also means that it's not obvious to find which are the component operations that are done for some operation X. That is, if you do (OP1 . A) (OP2 . B) and (OP3 . C) in order to do (OP . X) all you know is that the first three will appear /somewhere/ before (OP . X) in the plan --- you have no stronger guarantee about where they are. In particular, there is no top-level function call to do OP X that will be on the stack when the three subsidiary operations are done.
Understood as well. However, this also does not prevent ASDF from exposing a history of what it has done so far and let later operations use that.
I attach a simple extension to ASDF's OPERATE that creates a log. The log is a list of objects, each one containing the operation that was performed, whether it failed, and the output of PERFORM. With that log it is easy to build a TEST function that parses only the log entries related to tests.
* (multiple-value-setq (op log) (asdf:operate 'asdf:load-op 'cl-unicode))
[...] ;;; Computing Hangul syllable names #<ASDF:LOAD-OP NIL {12229E41}> * (mapc #'asdf::print-log-entry log) ;;; Log entry: ;;; #<LOAD-OP NIL {12229E41}> on #<SYSTEM "cl-unicode" {11A88DF9}> ;;; No return values [...] * (describe (first log)) #<ASDF:LOG-ENTRY {12E80A69}> is an instance of class #<STANDARD-CLASS ASDF:LOG-ENTRY>. The following slots have :INSTANCE allocation: COMPONENT #<ASDF:SYSTEM "cl-unicode" {11A88DF9}> OPERATION #<ASDF:LOAD-OP NIL {12229E41}> FAILED-P NIL RETURN-VALUES NIL
Could we agree that this is a valid starting point? It is really compatible with previous uses of ASDF and it only asks one thing: PERFORM, applied on TEST-OP should return two values, success-p and a list of objects containing the tests, so that we can analyze the log.
Juanjo
On Mon, Oct 19, 2009 at 10:10 PM, Juan Jose Garcia-Ripoll juanjose.garciaripoll@googlemail.com wrote:
I attach a simple extension to ASDF's OPERATE that creates a log. The log is a list of objects, each one containing the operation that was performed, whether it failed, and the output of PERFORM. With that log it is easy to build a TEST function that parses only the log entries related to tests.
I forgot to add a patch containing the extension, which I now include with a couple more files.
This version includes also an RT-TEST-OP which hacks around the regression-test package. It is realy a hack,because this library is not designed to have more than one test suite. What the operation does is to load (not as a dependency but as per OPERATE) and then clear all the variables from the test library. This forces the tests to be run every time.
The idea is that one can write things like
(defsystem :my-package :components ((:file "my-package")) :in-order-to ((test-op (rt-test-op :my-package-test))))
without really writing our own methods. The different operations will take care of using the appropriate regression test library.
The function TEST is invoked as in (asdf:test 'asdf:test-op :my-package) and it filters the ASDF log looking for test operations and signalling when all of them succeeded and returning the list of failed tests.
Problems:
- The interface to the RT library is a horrible hack - ASDF decides that it has to run RT-TEST-OP for some reason I do not know.
Other than this, it works for the toy example I attach.
Juanjo