Commit 5e9ef771 authored by Robert Goldman's avatar Robert Goldman
Browse files

Merge branch 'iss39' into 'master'

Fix for issue 39: refine handling of serial dependencies

See merge request asdf/asdf!163
parents 0ac93efe 717fb693
Loading
Loading
Loading
Loading
+1 −0
Changes for doc/Changelog: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
cl-asdf (2:3.3.5-1) unstable; urgency=low IN PROGRESS

* Fix bug in handling combination of :serial and :if-feature dependencies.
* Add support for package local nicknames to UIOP:DEFINE-PACKAGE and
	ASDF's package-inferred systems.  Extend support for package local
	nicknames to more lisp implementations.
+40 −13
Changes for parse-defsystem.lisp: 40 added lines, 13 removed lines.
Original line number Diff line number Diff line
@@ -268,7 +268,43 @@ Please only define ~S and secondary systems with a name starting with ~S (e.g. ~
system names contained using COERCE-NAME. Return the result."
    (mapcar 'parse-dependency-def dd-list))

  (defun* (parse-component-form) (parent options &key previous-serial-component)
  ;;; Helper function for parse-component-form.  Sets the CHILDREN slot of
  ;;; COMPONENT, using COMPONENTS list, and adds dependency links if
  ;;; the COMPONENT is a serial component. Should ONLY be called on a
  ;;; PARENT-COMPONENT.
  ;;; Returns the list of child components -- it's not entirely clear to me
  ;;; what is the set of possible values for elements of this list.
  (declaim (ftype (function (parent-component list (or t nil)) t)
                   compute-component-children)
           (ftype (function ((or parent-component null) list &key (:previous-serial-components list)))
                  parse-component-form))

  (defun* compute-component-children (component components serial-p)
    (prog1
        (setf (component-children component)
              (loop
                :with previous-components = nil ; list of strings
                :for c-form :in components
                :for c = (parse-component-form component c-form
                                               :previous-serial-components previous-components)
                :for name :of-type string = (component-name c)
                :collect c
                :when serial-p
                  ;; if this is an if-feature component, we need to make a serial link
                  ;; from previous components to following components -- otherwise should
                  ;; the IF-FEATURE component drop out, the chain of serial dependencies will be
                  ;; broken.
                  :unless (component-if-feature c)
                    :do (setf previous-components nil)
                :end
                :and :do (push name previous-components)))
      (compute-children-by-name component)))

  (defun* stable-union (s1 s2 &key (test #'eql) (key 'identity))
   (append s1
     (remove-if #'(lambda (e2) (member (funcall key e2) (funcall key s1) :test test)) s2)))

  (defun* (parse-component-form) (parent options &key previous-serial-components)
    (destructuring-bind
        (type name &rest rest &key
                                (builtin-system-p () bspp)
@@ -320,18 +356,9 @@ system names contained using COERCE-NAME. Return the result."
        ;; A better fix is required.
        (setf (slot-value component 'version) version)
        (when (typep component 'parent-component)
          (setf (component-children component)
                (loop
                  :with previous-component = nil
                  :for c-form :in components
                  :for c = (parse-component-form component c-form
                                                 :previous-serial-component previous-component)
                  :for name = (component-name c)
                  :collect c
                  :when serial :do (setf previous-component name)))
          (compute-children-by-name component))
        (when previous-serial-component
          (push previous-serial-component depends-on))
          (compute-component-children component components serial))
        (when previous-serial-components
          (setf depends-on (stable-union depends-on previous-serial-components :test #'equal)))
        (when weakly-depends-on
          ;; ASDF4: deprecate this feature and remove it.
          (appendf depends-on
+10 −0
Changes for test/test-serial-dependencies.asd: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
;;; This test example shows a failure in propagating serial dependencies across :if-feature
;;; conditionalization.

(asdf:defsystem test-serial-dependencies
    :serial t
  :components ((:file "file1")
               (:file "file4" :if-feature :undef)
               (:file "file3" :if-feature :undef)
               ;; we expect an error loading here, because file1 won't be loaded
               (:file "file2")))
+14 −0
Changes for test/test-serial-dependencies.script: 14 added lines, 0 removed lines.
Original line number Diff line number Diff line
;;; -*- mode: common-lisp; -*-

(in-package :asdf-test)

(configure-asdf)

;;; According to Gitlab issue 39, this should cause an error. We can't use
;;; LOAD-SYSTEM because LOAD-OP is a downward operation. Therefore the plan
;;; will always have a LOAD-OP on every source file of the system (in serial
;;; order).
;;;
(asdf:operate 'asdf:load-op
              (asdf:find-component (asdf:find-system "test-serial-dependencies")
                                   (list "file2")))