Closed17

CommonLisp で local-time を使うと rove でテストが実行できなかったけど解決した

tamura shingotamura shingo

qlot を使うと quicklisp に登録していなくても簡単に quicklisp で自作ライブラリを使うことができるので使用しています。
rove を使用する際にその自作ライブラリを使う関係で qlot 経由で起動しています。

開発を進めていく上で local-time ライブラリを追加したところテストに異常が出たので調査をしました。

まとめ

  • local-time ライブラリを読み込むと rove のテストが動かなくなる(テスト対象が0件になる)
  • 原因は local-time ライブラリが要求している uiop と sbcl 付属の uiop のバージョンが違うため
    • asdf:*user-cache* を見てソースコードの位置を特定しテスト対象かどうかを判別しているが、新しいバージョンの uiop を入れることで asdf:*user-cache* が変わってしまった
  • 処理系に付属の asdf を最新化すると repl ではテストが成功するが、 rove コマンドでテストを実行すると結果が出力されない謎の症状が出た
  • 処理系に付属の asdf を最新化するのではなく、 qlotuiop の古いバージョンを落とすようにすると上手くいった
tamura shingotamura shingo

再現環境

func/
├── src/
│   └── func.lisp
├── tests/
│   └── func-test.lisp
└── func.asd
func.asd
(in-package #:cl-user)

(defpackage #:func-system
  (:use #:asdf #:cl))

(in-package #:func-system)

(defsystem func
;;  :depends-on ("local-time")
  :components ((:module "src"
                :components
                ((:file "func"))))
  :in-order-to ((test-op (test-op "func-test"))))

(defsystem func-test
  :depends-on ("func"
               "rove")
  :components ((:module "test"
                :components
                ((:file "func-test"))))
  :perform (test-op (op c) (uiop:symbol-call '#:rove '#:run c)))
func.lisp
(in-package #:cl-user)
(defpackage func
  (:use #:cl)
  (:export :add3))
(in-package #:func)

(defun add3 (x)
  (+ x 3))
func-test.lisp
(in-package #:cl-user)
(defpackage func-test
  (:use #:cl
        #:func
        #:rove))
(in-package #:func-test)

(deftest add3-is-correct
  (ok (= 6 (add3 3))))
tamura shingotamura shingo

通常のテストの実行

% export CL_SOURCE_REGISTRY=$PWD
% rove func.asd
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:PREPARE-OP
                                                     "func-test"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                                   "func") wasn't done yet!

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                              "func") wasn't done yet!
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/FIND-SYSTEM:DEFINE-OP
                                                                              "func") wasn't done yet!
tamura shingotamura shingo

qlot 経由でのテストの実行 (local-timeなし)

qlot install

% qlot install
Installing Quicklisp to /Users/tamurashingo/cl/func/.qlot/...
Reading '/Users/tamurashingo/cl/func/qlfile'...
✓ [1/1] quicklisp  Newly installed "quicklisp" version "2024-10-12".
Loaded 1 system files.
Ensuring 9 dependencies installed.
Successfully installed.

テストの実行

% qlot exec rove func.asd
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:PREPARE-OP
                                                     "func-test"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                                   "func") wasn't done yet!

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                              "func") wasn't done yet!
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/FIND-SYSTEM:DEFINE-OP
                                                                              "func") wasn't done yet!

local-time がない場合は問題なく実行できている

tamura shingotamura shingo

qlot経由でのテスト実行(local-timeあり)

asdf ファイルの変更

--- func.asd.old	2024-12-31 19:40:56
+++ func.asd	2024-12-31 19:41:02
@@ -6,7 +6,7 @@
 (in-package #:func-system)

 (defsystem func
-;;  :depends-on ("local-time")
+  :depends-on ("local-time")
   :components ((:module "src"
                 :components
                 ((:file "func"))))

ライブラリのインストール

% qlot install
Reading '/Users/tamurashingo/cl/func/qlfile'...
Loaded 1 system files.
Ensuring 11 dependencies installed.
Successfully installed.

テストの実行

% qlot exec rove func.asd

; file: /Users/tamurashingo/cl/func/.qlot/dists/quicklisp/software/local-time-20241012-git/src/local-time.lisp
; in: DEFUN %SPLIT-TIMESTRING
;     (= (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS)) 4)
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a SINGLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a DOUBLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).
;
; note: unable to open code because: The operands might not be the same type.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.

;     (+ (CAAR LOCAL-TIME::PARTS) 4)
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.

;     (= (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS)) 2)
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a SINGLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a DOUBLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).
;
; note: unable to open code because: The operands might not be the same type.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.

;     (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS))
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The second argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a T, not a SINGLE-FLOAT.
;       The second argument is a T, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES SINGLE-FLOAT
;                                                                &OPTIONAL).
;       etc.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.

;     (+ (CAAR LOCAL-TIME::PARTS) 4)
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.

;     (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS))
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The second argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a T, not a SINGLE-FLOAT.
;       The second argument is a T, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES SINGLE-FLOAT
;                                                                &OPTIONAL).
;       etc.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.
;
; compilation unit finished
;   printed 20 notes
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:PREPARE-OP
                                                     "func-test"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                                   "func") wasn't done yet!

Testing System func-test

✓ 0 tests completed

Summary:
  All 0 tests passed.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                              "func") wasn't done yet!
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/FIND-SYSTEM:DEFINE-OP
                                                                              "func") wasn't done yet!

テストが実行されていない。。。

tamura shingotamura shingo

確認

rove コマンドを変更するのは骨なので、REPLから起動できることを確認しておきました。

% ros run
* (ql:quickload '("rove" "func"))
To load "rove":
  Load 1 ASDF system:
    rove
; Loading "rove"
...
To load "func":
  Load 1 ASDF system:
    func
; Loading "func"

("rove" "func")
* (rove:run "func-test")
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
T
(#<ROVE/CORE/RESULT:PASSED-TEST func-test (PASSED=1, FAILED=0)>)

qlot 経由でも同様にテストできることを確認したいので、 .qlot を消して local-time を読まないようにしてやった結果がこちらです。

% rm -rf .qlot qlfile qlfile.lock
% vi func.asd
% # ;;  :depends-on ("local-time") となるように修正
% qlot install
Installing Quicklisp to /Users/tamurashingo/cl/func/.qlot/...
Reading '/Users/tamurashingo/cl/func/qlfile'...
✓ [1/1] quicklisp  Newly installed "quicklisp" version "2024-10-12".
Loaded 1 system files.
Ensuring 9 dependencies installed.
Successfully installed.
% qlot exec ros run
* (ql:quickload '("rove" "func"))
To load "rove":
  Load 1 ASDF system:
    rove
; Loading "rove"
...
To load "func":
  Load 1 ASDF system:
    func
; Loading "func"
[package func]
("rove" "func")
* (rove:run "func-test")
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
T
(#<ROVE/CORE/RESULT:PASSED-TEST func-test (PASSED=1, FAILED=0)>)

qlot 経由でも local-time を使わないのであれば同じテスト結果となることが確認できました。

tamura shingotamura shingo

rove に確認用のコードを埋め込む

github から落としてきた rove でテストが動くようにします.

% git clone https://github.com/fukamachi/rove.git
% vi main.lisp

デバッグ用のメッセージを埋め込みました。

--- a/main.lisp
+++ b/main.lisp
@@ -74,6 +74,7 @@
       (run-test-functions tests))))

 (defmethod run (target &key (style *default-reporter*) (env *default-env*))
+  (format t "modified~%")
   (with-local-envs env
     (with-reporter style
       (run-system-tests target))))

このディレクトリを優先的に読み込むように quicklisp に指定させます。

* (push #P"/Users/tamurashingo/cl/rove" ql:*local-project-directories*)
(#P"/Users/tamurashingo/cl/rove"
 #P"/Users/tamurashingo/cl/func/.qlot/local-projects/")

* (ql:quickload '("rove" "func"))
To load "rove":
  Load 1 ASDF system:
    rove
; Loading "rove"
[package rove/core/result]........................
[package rove/stats]..............................
[package rove/core/assertion].....................
[package rove/core/suite/file]....................
[package rove/core/suite/package].................
[package rove/core/test]..........................
[package rove/core/suite].........................
[package rove/reporter/registry]..................
[package rove/reporter]...........................
[package rove/misc/color].........................
[package rove/misc/stream]........................
[package rove/utils/reporter].....................
[package rove/reporter/spec]......................
[package rove/reporter/dot]...
To load "func":
  Load 1 ASDF system:
    func
; Loading "func"

("rove" "func")

* (rove:run "func-test")
modified
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
T
(#<ROVE/CORE/RESULT:PASSED-TEST func-test (PASSED=1, FAILED=0)>)

追加したメッセージ "modified" が出力されました。
これで、githubから落としてきたソースコードでテストが動かせるようになりました。

tamura shingotamura shingo

調査メモ

テスト実行時の差分

何がどこまで動いているのか rove の中身を把握するのが良いのでしょうが、とりあえず出力の差分を見て確認していきます。

テストできているとき

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.

テストできていないとき

Testing System func-test

✓ 0 tests completed

Summary:
  All 0 tests passed.

これを見ると

Tesing System func-test

の後にテストが実行されていそうです。
grep するとコードが見つかりました。

% git grep -ni 'Testing System'
reporter/spec.lisp:97:  (format (reporter-stream reporter) "~2&Testing System ~A~%" (asdf:component-name system)))
(defmethod system-tests-begin ((reporter spec-reporter) system)
  (format (reporter-stream reporter) "~2&Testing System ~A~%" (asdf:component-name system)))

system-tests-begin が呼ばれている場所を探します。

% git grep -n 'system-tests-begin'
core/stats.lisp:24:           #:system-tests-begin
core/stats.lisp:165:(defgeneric system-tests-begin (stats system)
core/suite.lisp:45:    (system-tests-begin *stats* system)
reporter/spec.lisp:96:(defmethod system-tests-begin ((reporter spec-reporter) system)

core/suite.lisp にあるので確認します。

(defgeneric run-system (system)
  (:method ((system symbol))
    (run-system (asdf:find-system system)))
  (:method ((system string))
    (run-system (asdf:find-system system)))
  (:method ((system asdf:system))
    #+quicklisp (ql:quickload (asdf:component-name system) :silent t)
    #-quicklisp (asdf:load-system (asdf:component-name system))

    (system-tests-begin *stats* system)
    (with-context (context :name (asdf:component-name system))
      (typecase system
        (asdf:package-inferred-system
          (let* ((package-name (string-upcase (asdf:component-name system)))
                 (package (find-package package-name)))
            (unless package
              (setf package (find-package package-name)))
            ;; Loading dependencies beforehand
            (let ((pkgs (system-packages system)))
              (dolist (package pkgs)
                (let ((suite (package-suite package)))
                  (when suite
                    (run-suite suite)))))

            (when package
              (let ((suite (package-suite package)))
                (when suite
                  (run-suite suite))))))
        (otherwise
          (dolist (suite (system-suites system))
            (run-suite suite)))))
    (system-tests-finish *stats* system)))

今回の func-testasdf:package-inferred-system ではないのでこの部分がテストを実行している箇所のようです。

          (dolist (suite (system-suites system))
            (run-suite suite)))))

さらに確認

system-suites の中身を確認していきます。

% git grep -n system-suites
core/suite.lisp:11:                #:system-suites
core/suite.lisp:65:          (dolist (suite (system-suites system))
core/suite/package.lisp:21:           #:system-suites
core/suite/package.lisp:45:(defun system-suites (system)
(defun system-suites (system)
  (mapcar (lambda (package)
            (gethash package *package-suites*))
          (system-packages system)))

system-packages で返ってきたリストに対して *package-suites* からテストの何かを取得しています。

まずは、テストが実行できる環境で値を確認します。

% ros run

念のためテストまで実行しておきます。

* (ql:quickload '("rove" "func"))
* (rove:run "func-test")
* (rove/core/suite/package::system-suites (asdf:find-system "func-test"))
(#<ROVE/CORE/SUITE/PACKAGE::SUITE {700754F143}>)

つぎにテストが実行できなかった環境で確認します。

% qlot exec ros run

こちらも念のためテストまで実行してから確認をします。

* (rove/core/suite/package::system-suites (asdf:find-system "func-test"))
NIL

ここの値が NIL のためテストが実行されていないようです。

さらにさらに確認

(defun system-suites (system)
  (mapcar (lambda (package)
            (gethash package *package-suites*))
          (system-packages system)))

system-packages を更に確認していきます。

% git grep -n system-packages
core/suite.lisp:18:                #:system-packages)
core/suite.lisp:54:            (let ((pkgs (system-packages system)))
core/suite/file.lisp:92:(defun system-packages (system)
core/suite/package.lisp:7:                #:system-packages)
core/suite/package.lisp:48:          (system-packages system)))
(defun system-packages (system)
  (let ((files (system-files system)))
    (remove-duplicates
     (remove nil
             (mapcar (lambda (file)
                       (file-package file nil))
                     files))
     :from-end t)))

まずは戻り値の確認

テストできる環境

* (rove/core/suite/file::system-packages (asdf:find-system "func-test"))
(#<PACKAGE "FUNC-TEST">)

テストできない環境

* (rove/core/suite/file::system-packages (asdf:find-system "func-test"))
NIL

戻り値が違う原因を探ります。

system-files を確認してみます。

テストできる環境

* (rove/core/suite/file::system-files (asdf:find-system "func-test"))
(#P"/Users/tamurashingo/cl/func/test/func-test.lisp")

テストできない環境

* (rove/core/suite/file::system-files (asdf:find-system "func-test"))
(#P"/Users/tamurashingo/cl/func/test/func-test.lisp")

ここでの結果は同じで、ソースコードの位置が返ってきています。

ということは system-packages はこういう感じになっているハズです。

(defun system-packages (system)
  (remove-duplicates
   (remove nil
           (mapcar (lambda (file)
                     (file-package file nil))
                   '(#P"/Users/tamurashingo/cl/func/test/func-test.lisp")))
   :from-end t))

このテスト対象のコードのパスを file-package で何かしています.

(defun file-package (file &optional (warn t))
  (let ((package (gethash (uiop:native-namestring file) *file-package*)))
    (when (and (null package)
               warn)
      (warn "No package found for file '~A'." file))
    package))

テストできる環境

* (rove/core/suite/file::file-package #P"/Users/tamurashingo/cl/func/test/func-test.lisp")
#<PACKAGE "FUNC-TEST">

テストできない環境

* (rove/core/suite/file::file-package #P"/Users/tamurashingo/cl/func/test/func-test.lisp")
WARNING:
   No package found for file '/Users/tamurashingo/cl/func/test/func-test.lisp'.
NIL

ということは *file-package* に入っている値が違っていそうです。

テストできる環境

* (maphash #'(lambda (key value)
               (format t "~A => ~A~%" key value))
           rove/core/suite/file::*file-package*)
/Users/tamurashingo/cl/func/test/func-test.lisp => #<PACKAGE "FUNC-TEST">
NIL

テストできない環境

* (maphash #'(lambda (key value)
               (format t "~A => ~A~%" key value))
           rove/core/suite/file::*file-package*)
/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/func/test/func-test.lisp => #<PACKAGE "FUNC-TEST">
NIL

*file-package* が保持しているキーが違うため戻り値が NIL になり、テストが実行されていないようです。

tamura shingotamura shingo

*file-package* へのセット

(defun (setf file-package) (package file)
  (setf (gethash (uiop:native-namestring file) *file-package*) package))

setf が用意されていて、これで *file-package* に値をセットしているようです。

で、 grep したところこの関数にたどりつきました。

(defun make-new-suite (package)
  (let ((pathname (resolve-file (or *load-pathname* *compile-file-pathname*))))
    (when (and pathname
               (not (file-package pathname nil)))
      (setf (file-package pathname) package)))
  (make-instance 'suite
                 :name (string-downcase (package-name package))
                 :package package))

ここにデバッグ用のメッセージを仕込んで実行させたところ、このような結果になりました。

テストできる環境

make-new-suite:pathname: /Users/tamurashingo/cl/func/test/func-test.lisp
make-new-suite:load-pathname: /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/func/test/func-test.fasl
make-new-suite:compile-file-pathname: NIL

テストできない環境

make-new-suite:pathname: /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/func/test/func-test.lisp
make-new-suite:load-pathname: /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/func/test/func-test.fasl
make-new-suite:compile-file-pathname: NIL

渡っている値は同じですが、戻り値が違います。
resolve-file に何かありそうです。

(defun resolve-file (pathname)
  (block nil
    (unless pathname
      (return nil))
    (let ((pathname (uiop:ensure-absolute-pathname pathname)))
      (unless (compile-file-p pathname)
        (return pathname))
      (unless asdf:*user-cache*
        (return pathname))
      (if (eql (search (namestring asdf:*user-cache*)
                       (namestring pathname))
               0)
          (let* ((directories (nthcdr (length (pathname-directory asdf:*user-cache*))
                                      (pathname-directory pathname)))
                 (device (pathname-device pathname))
                 (device (when (and device (not (eq device :unspecific)))
                           (pop directories))))
            (make-pathname
             :type "lisp"
             :defaults pathname
             :device device
             :directory (cons :absolute directories)))
          (uiop:lispize-pathname pathname)))))

処理を見ると

引数の pathnameasdf:*user-cache* で始まっていたら pathname を作って返す
引数の pathnameasdf:*user-cache* で始まっていなかったら lisp のファイルとして pathname を返す

という処理です。

テストできる環境

* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/"

テストできない環境

* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64-s/"

テストできない環境は最後に -s が付いています。
このため、 pathname を作り直して返すのではなく、引数の pathname のディレクトリ構造をそのまま返していたようです。

tamura shingotamura shingo

asdf:*user-cache* の確認

-s が付くのはどういう条件でなのかを確認したところ、 local-time を追加で読み込むときに何かが起こっていそうだなと掴みました。

これを見ると qlot 経由かどうかは関係ないようです。
quicklisp で読みこんでいるときに user-cache に対して何かをやっているのかな?

ros run 直後

問題なし

% ros run
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/"

ros run 後に local-time をロード

問題なし

* (ql:quickload "local-time")
To load "local-time":
  Load 1 ASDF system:
    local-time
; Loading "local-time"

("local-time")
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/"

qlot exec ros run 直後

問題なし

 % qlot exec ros run
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/"

qlot exec ros run 後に local-time をロード

ダメ

* (ql:quickload "local-time")
To load "local-time":
  Load 1 ASDF system:
    local-time
; Loading "local-time"

("local-time")
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64-s/"

ros run 後に依存パッケージに local-time があるライブラリのロード

ダメ

% ros run
* (push #P"/Users/tamurashingo/cl/func" ql:*local-project-directories*)
(#P"/Users/tamurashingo/cl/func"
 #P"/Users/tamurashingo/.roswell/lisp/quicklisp/local-projects/")
* (ql:quickload "func")
To load "func":
  Load 1 ASDF system:
    func
; Loading "func"

("func")
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64-s/"

qlot exec ros run 後に依存パッケージに local-time があるライブラリのロード

ダメ

% qlot exec ros run
* (ql:quickload "func")
To load "func":
  Load 1 ASDF system:
    func
; Loading "func"

("func")
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64-s/"
tamura shingotamura shingo

asdf:*user-cache* の確認 part2

quicklisp を使ったロードは確認できたので、今度は asdf でロードしたらどうなるかを確認してみます。

ディレクトリ構成はこうなっています。

/Users/tamurashingo/cl
├── func/
├── local-time/
├── qlfile
└── qlfile.lock

実行した結果、 qlot exec ros run で起動した環境では、 asdflocal-time を読み込むと asdf:*user-cache* の値が変わることがわかりました。

ちなみに、 asdf での読み込みは (asdf:oos 'asdf:load-op 'func) のようにやっているのですが、 (asdf:load-system 'local-time) でもこの事象は発生しました。

ros run 後に local-time をロード

問題なし

% ros run
* (push #P"/Users/tamurashingo/cl/" asdf:*central-registry*)
(#P"/Users/tamurashingo/cl/"
 #P"/Users/tamurashingo/.roswell/lisp/quicklisp/quicklisp/")
* (asdf:oos 'asdf:load-op 'local-time)
#<ASDF/LISP-ACTION:LOAD-OP >
#<ASDF/PLAN:SEQUENTIAL-PLAN {70073B0073}>
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/"

ros run 後に依存パッケージに local-time があるライブラリをロード

問題なし

% ros run
* (push #P"/Users/tamurashingo/cl/" asdf:*central-registry*)
(#P"/Users/tamurashingo/cl/"
 #P"/Users/tamurashingo/.roswell/lisp/quicklisp/quicklisp/")
* (asdf:oos 'asdf:load-op 'func)
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.
#<ASDF/LISP-ACTION:LOAD-OP >
#<ASDF/PLAN:SEQUENTIAL-PLAN {700730CE43}>
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/"

qlot exec ros run 後に local-time をロード

ダメ

% qlot exec ros run
* (push #P"/Users/tamurashingo/cl/" asdf:*central-registry*)
(#P"/Users/tamurashingo/cl/" #P"/Users/tamurashingo/cl/.qlot/quicklisp/")
* (asdf:oos 'asdf:load-op 'local-time)
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/package.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/package-tmpGHU3ALSV.fasl
; compilation finished in 0:00:00.194
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/common-lisp.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/common-lisp-tmpAAURSO1.fasl
; compilation finished in 0:00:00.006
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/utility.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/utility-tmp5GEXGEG5.fasl
; compilation finished in 0:00:00.069
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/version.lisp" (written 29 JAN 2024 02:36:46 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/version-tmpAR3FSGEY.fasl
; compilation finished in 0:00:00.026
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/os.lisp" (written 29 JAN 2024 02:36:46 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/os-tmpJAIDFZTC.fasl
; compilation finished in 0:00:00.027
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/pathname.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/pathname-tmp8V3J6PE9.fasl
; compilation finished in 0:00:00.044
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/filesystem.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/filesystem-tmp9V47YWQF.fasl
; compilation finished in 0:00:00.049
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/stream.lisp" (written 29 JAN 2024 02:36:46 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/stream-tmp9BN22RMA.fasl
; compilation finished in 0:00:00.101
WARNING: redefining UIOP/STREAM:OUTPUT-STRING in DEFUN
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/image.lisp" (written 29 JAN 2024 02:36:46 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/image-tmp1CXFJSK9.fasl
; compilation finished in 0:00:00.030
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/lisp-build.lisp" (written 29 JAN 2024 02:36:46 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/lisp-build-tmpX4BRKI0R.fasl
; compilation finished in 0:00:00.056
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/launch-program.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/launch-program-tmpQ371UGST.fasl
; compilation finished in 0:00:00.048
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/run-program.lisp" (written 08 JAN 2022 01:11:18 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/run-program-tmp2OWI3Q7U.fasl
; compilation finished in 0:00:00.088
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/configuration.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/configuration-tmp9KKTJMYV.fasl
; compilation finished in 0:00:00.106
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/backward-driver.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/backward-driver-tmpJU0JWO19.fasl
; compilation finished in 0:00:00.009
; compiling file "/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/driver.lisp" (written 28 JAN 2024 04:15:00 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/driver-tmpZX2WN8N4.fasl
; compilation finished in 0:00:00.001
; compiling file "/Users/tamurashingo/cl/local-time/src/package.lisp" (written 02 JAN 2025 08:44:14 AM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/local-time/src/package-tmpOU81XRV0.fasl
; compilation finished in 0:00:00.000
; compiling file "/Users/tamurashingo/cl/local-time/src/local-time.lisp" (written 02 JAN 2025 08:44:14 AM):

; file: /Users/tamurashingo/cl/local-time/src/local-time.lisp
; in: DEFUN %SPLIT-TIMESTRING
;     (= (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS)) 4)
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a SINGLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a DOUBLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).
;
; note: unable to open code because: The operands might not be the same type.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.

;     (+ (CAAR LOCAL-TIME::PARTS) 4)
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.

;     (= (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS)) 2)
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a SINGLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a DOUBLE-FLOAT.
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
;
; note: unable to
;   open-code FLOAT to RATIONAL comparison
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).
;
; note: unable to open code because: The operands might not be the same type.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: unable to
;   associate +/(+ -) of constants
; due to type uncertainty:
;   The first argument is a NUMBER, not a RATIONAL.

;     (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS))
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The second argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a T, not a SINGLE-FLOAT.
;       The second argument is a T, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES SINGLE-FLOAT
;                                                                &OPTIONAL).
;       etc.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.

;     (+ (CAAR LOCAL-TIME::PARTS) 4)
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.

;     (- (CDAR LOCAL-TIME::PARTS) (CAAR LOCAL-TIME::PARTS))
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The second argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a T, not a SINGLE-FLOAT.
;       The second argument is a T, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES SINGLE-FLOAT
;                                                                &OPTIONAL).
;       etc.

;     (+ (CAAR LOCAL-TIME::PARTS) 2)
;
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a T, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &OPTIONAL).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a T, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (UNSIGNED-BYTE 64)
;                                                         &OPTIONAL).
;       etc.


; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/local-time/src/local-time-tmpY2ML9CFA.fasl
; compilation finished in 0:00:00.265
;
; compilation unit finished
;   printed 20 notes
#<ASDF/LISP-ACTION:LOAD-OP >
#<ASDF/PLAN:SEQUENTIAL-PLAN {7005950373}>
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64-s/"

長すぎて怒られたので次に続きます。

tamura shingotamura shingo

続きです。

qlot exec ros run 後に依存パッケージに local-time があるライブラリをロード

ダメ

% qlot exec ros run
* (push #P"/Users/tamurashingo/cl/" asdf:*central-registry*)
(#P"/Users/tamurashingo/cl/" #P"/Users/tamurashingo/cl/.qlot/quicklisp/")
* (asdf:oos 'asdf:load-op 'func)
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.
WARNING: redefining UIOP/PACKAGE:FIND-PACKAGE* in DEFUN
WARNING: redefining UIOP/PACKAGE:FIND-SYMBOL* in DEFUN
WARNING: redefining UIOP/PACKAGE:SYMBOL-CALL in DEFUN
WARNING: redefining UIOP/PACKAGE:INTERN* in DEFUN
WARNING: redefining UIOP/PACKAGE:EXPORT* in DEFUN
WARNING: redefining UIOP/PACKAGE:IMPORT* in DEFUN
WARNING: redefining UIOP/PACKAGE:SHADOWING-IMPORT* in DEFUN
WARNING: redefining UIOP/PACKAGE:SHADOW* in DEFUN
WARNING: redefining UIOP/PACKAGE:MAKE-SYMBOL* in DEFUN
WARNING: redefining UIOP/PACKAGE:UNINTERN* in DEFUN
WARNING: redefining UIOP/PACKAGE:SYMBOL-SHADOWING-P in DEFUN
WARNING: redefining UIOP/PACKAGE:HOME-PACKAGE-P in DEFUN
WARNING: redefining UIOP/PACKAGE:SYMBOL-PACKAGE-NAME in DEFUN
WARNING: redefining UIOP/PACKAGE:STANDARD-COMMON-LISP-SYMBOL-P in DEFUN
WARNING: redefining UIOP/PACKAGE:REIFY-PACKAGE in DEFUN
WARNING: redefining UIOP/PACKAGE:UNREIFY-PACKAGE in DEFUN
WARNING: redefining UIOP/PACKAGE:REIFY-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE:UNREIFY-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE::RECORD-FISHY in DEFUN
WARNING: redefining UIOP/PACKAGE::WHEN-PACKAGE-FISHINESS in DEFMACRO
WARNING: redefining UIOP/PACKAGE::NOTE-PACKAGE-FISHINESS in DEFMACRO
WARNING: redefining UIOP/PACKAGE::SET-DUMMY-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE::MAKE-DUMMY-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE::DUMMY-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE::GET-DUMMY-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE:NUKE-SYMBOL-IN-PACKAGE in DEFUN
WARNING: redefining UIOP/PACKAGE:NUKE-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE:REHOME-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE:ENSURE-PACKAGE-UNUSED in DEFUN
WARNING: redefining UIOP/PACKAGE:DELETE-PACKAGE* in DEFUN
WARNING: redefining UIOP/PACKAGE:PACKAGE-NAMES in DEFUN
WARNING: redefining UIOP/PACKAGE:PACKAGES-FROM-NAMES in DEFUN
WARNING: redefining UIOP/PACKAGE:FRESH-PACKAGE-NAME in DEFUN
WARNING: redefining UIOP/PACKAGE:RENAME-PACKAGE-AWAY in DEFUN
WARNING: redefining UIOP/PACKAGE:PACKAGE-DEFINITION-FORM in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-SHADOWING-IMPORT in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-IMPORTED in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-IMPORT in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-INHERITED in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-MIX in DEFUN
WARNING: redefining UIOP/PACKAGE::RECYCLE-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE::SYMBOL-RECYCLED-P in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-SYMBOL in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-EXPORTED-TO-USER in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-EXPORTED in DEFUN
WARNING: redefining UIOP/PACKAGE::ENSURE-EXPORT in DEFUN
WARNING: redefining UIOP/PACKAGE:ENSURE-PACKAGE in DEFUN
WARNING: redefining UIOP/PACKAGE:PARSE-DEFINE-PACKAGE-FORM in DEFUN
WARNING: redefining UIOP/PACKAGE:DEFINE-PACKAGE in DEFMACRO
WARNING: redefining UIOP/COMMON-LISP::FROB-SUBSTRINGS in DEFUN
WARNING: redefining UIOP/COMMON-LISP::COMPATFMT in DEFMACRO
WARNING: redefining UIOP/UTILITY:WITH-UPGRADABILITY in DEFMACRO
WARNING: redefining UIOP/UTILITY:UIOP-DEBUG in DEFMACRO
WARNING: redefining UIOP/UTILITY:LOAD-UIOP-DEBUG-UTILITY in DEFUN
WARNING: redefining UIOP/UTILITY:NEST in DEFMACRO
WARNING: redefining UIOP/UTILITY:IF-LET in DEFMACRO
WARNING: redefining UIOP/UTILITY:PARSE-BODY in DEFUN
WARNING: redefining UIOP/UTILITY:WHILE-COLLECTING in DEFMACRO
WARNING: redefining UIOP/UTILITY:APPENDF in DEFMACRO
WARNING: redefining UIOP/UTILITY:LENGTH=N-P in DEFUN
WARNING: redefining UIOP/UTILITY:ENSURE-LIST in DEFUN
WARNING: redefining UIOP/UTILITY:REMOVE-PLIST-KEY in DEFUN
WARNING: redefining UIOP/UTILITY:REMOVE-PLIST-KEYS in DEFUN
WARNING: redefining UIOP/UTILITY:EMPTYP in DEFUN
WARNING: redefining UIOP/UTILITY:CHARACTER-TYPE-INDEX in DEFUN
WARNING: redefining UIOP/UTILITY:BASE-STRING-P in DEFUN
WARNING: redefining UIOP/UTILITY:STRINGS-COMMON-ELEMENT-TYPE in DEFUN
WARNING: redefining UIOP/UTILITY:REDUCE/STRCAT in DEFUN
WARNING: redefining UIOP/UTILITY:STRCAT in DEFUN
WARNING: redefining UIOP/UTILITY:FIRST-CHAR in DEFUN
WARNING: redefining UIOP/UTILITY:LAST-CHAR in DEFUN
WARNING: redefining UIOP/UTILITY:SPLIT-STRING in DEFUN
WARNING: redefining UIOP/UTILITY:STRING-PREFIX-P in DEFUN
WARNING: redefining UIOP/UTILITY:STRING-SUFFIX-P in DEFUN
WARNING: redefining UIOP/UTILITY:STRING-ENCLOSED-P in DEFUN
WARNING: redefining UIOP/UTILITY:STRIPLN in DEFUN
WARNING: redefining UIOP/UTILITY:STANDARD-CASE-SYMBOL-NAME in DEFUN
WARNING: redefining UIOP/UTILITY:FIND-STANDARD-CASE-SYMBOL in DEFUN
WARNING: redefining UIOP/UTILITY:TIMESTAMP< in DEFUN
WARNING: redefining UIOP/UTILITY:TIMESTAMPS< in DEFUN
WARNING: redefining UIOP/UTILITY:TIMESTAMP*< in DEFUN
WARNING: redefining UIOP/UTILITY:TIMESTAMP<= in DEFUN
WARNING: redefining UIOP/UTILITY:EARLIER-TIMESTAMP in DEFUN
WARNING: redefining UIOP/UTILITY:TIMESTAMPS-EARLIEST in DEFUN
WARNING: redefining UIOP/UTILITY:EARLIEST-TIMESTAMP in DEFUN
WARNING: redefining UIOP/UTILITY:LATER-TIMESTAMP in DEFUN
WARNING: redefining UIOP/UTILITY:TIMESTAMPS-LATEST in DEFUN
WARNING: redefining UIOP/UTILITY:LATEST-TIMESTAMP in DEFUN
WARNING: redefining UIOP/UTILITY:LATEST-TIMESTAMP-F in DEFMACRO
WARNING: redefining UIOP/UTILITY:ENSURE-FUNCTION in DEFUN
WARNING: redefining UIOP/UTILITY:ACCESS-AT in DEFUN
WARNING: redefining UIOP/UTILITY:ACCESS-AT-COUNT in DEFUN
WARNING: redefining UIOP/UTILITY:CALL-FUNCTION in DEFUN
WARNING: redefining UIOP/UTILITY:CALL-FUNCTIONS in DEFUN
WARNING: redefining UIOP/UTILITY:REGISTER-HOOK-FUNCTION in DEFUN
WARNING: redefining UIOP/UTILITY:COERCE-CLASS in DEFUN
WARNING: redefining UIOP/UTILITY:ENSURE-GETHASH in DEFUN
WARNING: redefining UIOP/UTILITY:LIST-TO-HASH-SET in DEFUN
WARNING: redefining UIOP/UTILITY:LEXICOGRAPHIC< in DEFUN
WARNING: redefining UIOP/UTILITY:LEXICOGRAPHIC<= in DEFUN
WARNING: redefining UIOP/UTILITY:STYLE-WARN in DEFUN
WARNING: redefining UIOP/UTILITY:MATCH-CONDITION-P in DEFUN
WARNING: redefining UIOP/UTILITY:MATCH-ANY-CONDITION-P in DEFUN
WARNING: redefining UIOP/UTILITY:CALL-WITH-MUFFLED-CONDITIONS in DEFUN
WARNING: redefining UIOP/UTILITY:WITH-MUFFLED-CONDITIONS in DEFMACRO
WARNING: redefining UIOP/UTILITY:NOT-IMPLEMENTED-ERROR in DEFUN
WARNING: redefining UIOP/UTILITY:PARAMETER-ERROR in DEFUN
WARNING: redefining UIOP/VERSION:UNPARSE-VERSION in DEFUN
WARNING: redefining UIOP/VERSION:PARSE-VERSION in DEFUN
WARNING: redefining UIOP/VERSION:NEXT-VERSION in DEFUN
WARNING: redefining UIOP/VERSION:VERSION< in DEFUN
WARNING: redefining UIOP/VERSION:VERSION<= in DEFUN
WARNING: redefining UIOP/VERSION::DEPRECATED-FUNCTION-CONDITION-KIND in DEFUN
WARNING:
   redefining PRINT-OBJECT (#<SB-PCL::CONDITION-CLASS UIOP/VERSION:DEPRECATED-FUNCTION-CONDITION>
                            #<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING: redefining UIOP/VERSION::NOTIFY-DEPRECATED-FUNCTION in DEFUN
WARNING: redefining UIOP/VERSION:VERSION-DEPRECATION in DEFUN
WARNING: redefining UIOP/VERSION:WITH-DEPRECATION in DEFMACRO
WARNING: redefining UIOP/OS:FEATUREP in DEFUN
WARNING: redefining UIOP/OS:OS-MACOSX-P in DEFUN
WARNING: redefining UIOP/OS:OS-UNIX-P in DEFUN
WARNING: redefining UIOP/OS:OS-WINDOWS-P in DEFUN
WARNING: redefining UIOP/OS:OS-GENERA-P in DEFUN
WARNING: redefining UIOP/OS::OS-OLDMAC-P in DEFUN
WARNING: redefining UIOP/OS::OS-HAIKU-P in DEFUN
WARNING: redefining UIOP/OS:DETECT-OS in DEFUN
WARNING: redefining UIOP/OS:OS-COND in DEFMACRO
WARNING: redefining UIOP/OS:GETENV in DEFUN
WARNING: redefining UIOP/OS:GETENVP in DEFUN
WARNING: redefining UIOP/OS::FIRST-FEATURE in DEFUN
WARNING: redefining UIOP/OS:IMPLEMENTATION-TYPE in DEFUN
WARNING: redefining UIOP/OS:OPERATING-SYSTEM in DEFUN
WARNING: redefining UIOP/OS:ARCHITECTURE in DEFUN
WARNING: redefining UIOP/OS:LISP-VERSION-STRING in DEFUN
WARNING: redefining UIOP/OS:IMPLEMENTATION-IDENTIFIER in DEFUN
WARNING: redefining UIOP/OS:HOSTNAME in DEFUN
WARNING: redefining UIOP/OS:GETCWD in DEFUN
WARNING: redefining UIOP/OS:CHDIR in DEFUN
WARNING: redefining UIOP/OS:READ-NULL-TERMINATED-STRING in DEFUN
WARNING: redefining UIOP/OS:READ-LITTLE-ENDIAN in DEFUN
WARNING: redefining UIOP/OS:PARSE-FILE-LOCATION-INFO in DEFUN
WARNING: redefining UIOP/OS:PARSE-WINDOWS-SHORTCUT in DEFUN
WARNING:
   redefining UIOP/PATHNAME:NORMALIZE-PATHNAME-DIRECTORY-COMPONENT in DEFUN
WARNING:
   redefining UIOP/PATHNAME:DENORMALIZE-PATHNAME-DIRECTORY-COMPONENT in DEFUN
WARNING: redefining UIOP/PATHNAME:MERGE-PATHNAME-DIRECTORY-COMPONENTS in DEFUN
WARNING: redefining UIOP/PATHNAME:MAKE-PATHNAME* in DEFUN
WARNING: redefining UIOP/PATHNAME:MAKE-PATHNAME-COMPONENT-LOGICAL in DEFUN
WARNING: redefining UIOP/PATHNAME:MAKE-PATHNAME-LOGICAL in DEFUN
WARNING: redefining UIOP/PATHNAME:MERGE-PATHNAMES* in DEFUN
WARNING: redefining UIOP/PATHNAME:LOGICAL-PATHNAME-P in DEFUN
WARNING: redefining UIOP/PATHNAME:PHYSICAL-PATHNAME-P in DEFUN
WARNING: redefining UIOP/PATHNAME:PHYSICALIZE-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:NIL-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:WITH-PATHNAME-DEFAULTS in DEFMACRO
WARNING: redefining UIOP/PATHNAME:PATHNAME-EQUAL in DEFUN
WARNING: redefining UIOP/PATHNAME:ABSOLUTE-PATHNAME-P in DEFUN
WARNING: redefining UIOP/PATHNAME:RELATIVE-PATHNAME-P in DEFUN
WARNING: redefining UIOP/PATHNAME:HIDDEN-PATHNAME-P in DEFUN
WARNING: redefining UIOP/PATHNAME:FILE-PATHNAME-P in DEFUN
WARNING: redefining UIOP/PATHNAME:PATHNAME-DIRECTORY-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:PATHNAME-PARENT-DIRECTORY-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:DIRECTORY-PATHNAME-P in DEFUN
WARNING: redefining UIOP/PATHNAME:ENSURE-DIRECTORY-PATHNAME in DEFUN
WARNING:
   redefining UIOP/PATHNAME:SPLIT-UNIX-NAMESTRING-DIRECTORY-COMPONENTS in DEFUN
WARNING: redefining UIOP/PATHNAME:SPLIT-NAME-TYPE in DEFUN
WARNING: redefining UIOP/PATHNAME:PARSE-UNIX-NAMESTRING in DEFUN
WARNING: redefining UIOP/PATHNAME:UNIX-NAMESTRING in DEFUN
WARNING: redefining UIOP/PATHNAME:SUBPATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:SUBPATHNAME* in DEFUN
WARNING: redefining UIOP/PATHNAME:PATHNAME-ROOT in DEFUN
WARNING: redefining UIOP/PATHNAME:PATHNAME-HOST-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:ENSURE-ABSOLUTE-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:SUBPATHP in DEFUN
WARNING: redefining UIOP/PATHNAME:ENOUGH-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:CALL-WITH-ENOUGH-PATHNAME in DEFUN
WARNING: redefining UIOP/PATHNAME:WITH-ENOUGH-PATHNAME in DEFMACRO
WARNING: redefining UIOP/PATHNAME:WILDEN in DEFUN
WARNING: redefining UIOP/PATHNAME:RELATIVIZE-DIRECTORY-COMPONENT in DEFUN
WARNING: redefining UIOP/PATHNAME:RELATIVIZE-PATHNAME-DIRECTORY in DEFUN
WARNING: redefining UIOP/PATHNAME:DIRECTORY-SEPARATOR-FOR-HOST in DEFUN
WARNING: redefining UIOP/PATHNAME:DIRECTORIZE-PATHNAME-HOST-DEVICE in DEFUN
WARNING: redefining UIOP/PATHNAME:TRANSLATE-PATHNAME* in DEFUN
WARNING: redefining UIOP/FILESYSTEM:NATIVE-NAMESTRING in DEFUN
WARNING: redefining UIOP/FILESYSTEM:PARSE-NATIVE-NAMESTRING in DEFUN
WARNING: redefining UIOP/FILESYSTEM:TRUENAME* in DEFUN
WARNING: redefining UIOP/FILESYSTEM:SAFE-FILE-WRITE-DATE in DEFUN
WARNING: redefining UIOP/FILESYSTEM:PROBE-FILE* in DEFUN
WARNING: redefining UIOP/FILESYSTEM:DIRECTORY-EXISTS-P in DEFUN
WARNING: redefining UIOP/FILESYSTEM:FILE-EXISTS-P in DEFUN
WARNING: redefining UIOP/FILESYSTEM:DIRECTORY* in DEFUN
WARNING: redefining UIOP/FILESYSTEM:FILTER-LOGICAL-DIRECTORY-RESULTS in DEFUN
WARNING: redefining UIOP/FILESYSTEM:DIRECTORY-FILES in DEFUN
WARNING: redefining UIOP/FILESYSTEM:SUBDIRECTORIES in DEFUN
WARNING: redefining UIOP/FILESYSTEM:COLLECT-SUB*DIRECTORIES in DEFUN
WARNING: redefining UIOP/FILESYSTEM:TRUENAMIZE in DEFUN
WARNING: redefining UIOP/FILESYSTEM:RESOLVE-SYMLINKS in DEFUN
WARNING: redefining UIOP/FILESYSTEM:RESOLVE-SYMLINKS* in DEFUN
WARNING: redefining UIOP/PATHNAME:ENSURE-PATHNAME in DEFUN
WARNING: redefining UIOP/FILESYSTEM:GET-PATHNAME-DEFAULTS in DEFUN
WARNING: redefining UIOP/FILESYSTEM:CALL-WITH-CURRENT-DIRECTORY in DEFUN
WARNING: redefining UIOP/FILESYSTEM:WITH-CURRENT-DIRECTORY in DEFMACRO
WARNING: redefining UIOP/FILESYSTEM:INTER-DIRECTORY-SEPARATOR in DEFUN
WARNING: redefining UIOP/FILESYSTEM:SPLIT-NATIVE-PATHNAMES-STRING in DEFUN
WARNING: redefining UIOP/FILESYSTEM:GETENV-PATHNAME in DEFUN
WARNING: redefining UIOP/FILESYSTEM:GETENV-PATHNAMES in DEFUN
WARNING: redefining UIOP/FILESYSTEM:GETENV-ABSOLUTE-DIRECTORY in DEFUN
WARNING: redefining UIOP/FILESYSTEM:GETENV-ABSOLUTE-DIRECTORIES in DEFUN
WARNING: redefining UIOP/FILESYSTEM:LISP-IMPLEMENTATION-DIRECTORY in DEFUN
WARNING: redefining UIOP/FILESYSTEM:LISP-IMPLEMENTATION-PATHNAME-P in DEFUN
WARNING: redefining UIOP/FILESYSTEM:ENSURE-ALL-DIRECTORIES-EXIST in DEFUN
WARNING: redefining UIOP/FILESYSTEM:DELETE-FILE-IF-EXISTS in DEFUN
WARNING: redefining UIOP/FILESYSTEM:RENAME-FILE-OVERWRITING-TARGET in DEFUN
WARNING: redefining UIOP/FILESYSTEM:DELETE-EMPTY-DIRECTORY in DEFUN
WARNING: redefining UIOP/FILESYSTEM:DELETE-DIRECTORY-TREE in DEFUN
WARNING: redefining UIOP/STREAM:SETUP-STDIN in DEFUN
WARNING: redefining UIOP/STREAM:SETUP-STDOUT in DEFUN
WARNING: redefining UIOP/STREAM:SETUP-STDERR in DEFUN
WARNING: redefining UIOP/STREAM:ALWAYS-DEFAULT-ENCODING in DEFUN
WARNING: redefining UIOP/STREAM:DETECT-ENCODING in DEFUN
WARNING: redefining UIOP/STREAM:DEFAULT-ENCODING-EXTERNAL-FORMAT in DEFUN
WARNING: redefining UIOP/STREAM:ENCODING-EXTERNAL-FORMAT in DEFUN
WARNING: redefining UIOP/STREAM:WITH-SAFE-IO-SYNTAX in DEFMACRO
WARNING: redefining UIOP/STREAM:CALL-WITH-SAFE-IO-SYNTAX in DEFUN
WARNING: redefining UIOP/STREAM:SAFE-READ-FROM-STRING in DEFUN
WARNING: redefining UIOP/STREAM:CALL-WITH-OUTPUT-FILE in DEFUN
WARNING: redefining UIOP/STREAM:WITH-OUTPUT-FILE in DEFMACRO
WARNING: redefining UIOP/STREAM::CALL-WITH-OUTPUT in DEFUN
WARNING: redefining UIOP/STREAM:OUTPUT-STRING in DEFUN
WARNING: redefining UIOP/STREAM:CALL-WITH-INPUT-FILE in DEFUN
WARNING: redefining UIOP/STREAM:WITH-INPUT-FILE in DEFMACRO
WARNING: redefining UIOP/STREAM::CALL-WITH-INPUT in DEFUN
WARNING: redefining UIOP/STREAM:WITH-INPUT in DEFMACRO
WARNING: redefining UIOP/STREAM:INPUT-STRING in DEFUN
WARNING: redefining UIOP/STREAM:NULL-DEVICE-PATHNAME in DEFUN
WARNING: redefining UIOP/STREAM:CALL-WITH-NULL-INPUT in DEFUN
WARNING: redefining UIOP/STREAM:WITH-NULL-INPUT in DEFMACRO
WARNING: redefining UIOP/STREAM:CALL-WITH-NULL-OUTPUT in DEFUN
WARNING: redefining UIOP/STREAM:WITH-NULL-OUTPUT in DEFMACRO
WARNING: redefining UIOP/STREAM:FINISH-OUTPUTS in DEFUN
WARNING: redefining UIOP/STREAM:FORMAT! in DEFUN
WARNING: redefining UIOP/STREAM:SAFE-FORMAT! in DEFUN
WARNING: redefining UIOP/STREAM:COPY-STREAM-TO-STREAM in DEFUN
WARNING: redefining UIOP/STREAM:CONCATENATE-FILES in DEFUN
WARNING: redefining UIOP/STREAM:COPY-FILE in DEFUN
WARNING: redefining UIOP/STREAM:SLURP-STREAM-STRING in DEFUN
WARNING: redefining UIOP/STREAM:SLURP-STREAM-LINES in DEFUN
WARNING: redefining UIOP/STREAM:SLURP-STREAM-LINE in DEFUN
WARNING: redefining UIOP/STREAM:SLURP-STREAM-FORMS in DEFUN
WARNING: redefining UIOP/STREAM:SLURP-STREAM-FORM in DEFUN
WARNING: redefining UIOP/STREAM:READ-FILE-STRING in DEFUN
WARNING: redefining UIOP/STREAM:READ-FILE-LINES in DEFUN
WARNING: redefining UIOP/STREAM:READ-FILE-LINE in DEFUN
WARNING: redefining UIOP/STREAM:READ-FILE-FORMS in DEFUN
WARNING: redefining UIOP/STREAM:READ-FILE-FORM in DEFUN
WARNING: redefining UIOP/STREAM:SAFE-READ-FILE-LINE in DEFUN
WARNING: redefining UIOP/STREAM:SAFE-READ-FILE-FORM in DEFUN
WARNING: redefining UIOP/STREAM:EVAL-INPUT in DEFUN
WARNING: redefining UIOP/STREAM:EVAL-THUNK in DEFUN
WARNING: redefining UIOP/STREAM:STANDARD-EVAL-THUNK in DEFUN
WARNING: redefining UIOP/STREAM:PRINTLN in DEFUN
WARNING: redefining UIOP/STREAM:WRITELN in DEFUN
WARNING: redefining UIOP/STREAM:DEFAULT-TEMPORARY-DIRECTORY in DEFUN
WARNING: redefining UIOP/STREAM:TEMPORARY-DIRECTORY in DEFUN
WARNING: redefining UIOP/STREAM:SETUP-TEMPORARY-DIRECTORY in DEFUN
WARNING: redefining UIOP/STREAM:CALL-WITH-TEMPORARY-FILE in DEFUN
WARNING: redefining UIOP/STREAM:WITH-TEMPORARY-FILE in DEFMACRO
WARNING: redefining UIOP/STREAM::GET-TEMPORARY-FILE in DEFUN
WARNING: redefining UIOP/STREAM:ADD-PATHNAME-SUFFIX in DEFUN
WARNING: redefining UIOP/STREAM:TMPIZE-PATHNAME in DEFUN
WARNING: redefining UIOP/STREAM:CALL-WITH-STAGING-PATHNAME in DEFUN
WARNING: redefining UIOP/STREAM:WITH-STAGING-PATHNAME in DEFMACRO
WARNING: redefining UIOP/STREAM:FILE-STREAM-P in DEFUN
WARNING: redefining UIOP/STREAM:FILE-OR-SYNONYM-STREAM-P in DEFUN
WARNING: redefining UIOP/IMAGE:QUIT in DEFUN
WARNING: redefining UIOP/IMAGE:DIE in DEFUN
WARNING: redefining UIOP/IMAGE:RAW-PRINT-BACKTRACE in DEFUN
WARNING: redefining UIOP/IMAGE:PRINT-BACKTRACE in DEFUN
WARNING: redefining UIOP/IMAGE:PRINT-CONDITION-BACKTRACE in DEFUN
WARNING: redefining UIOP/IMAGE:FATAL-CONDITION-P in DEFUN
WARNING: redefining UIOP/IMAGE:HANDLE-FATAL-CONDITION in DEFUN
WARNING: redefining UIOP/IMAGE:CALL-WITH-FATAL-CONDITION-HANDLER in DEFUN
WARNING: redefining UIOP/IMAGE:WITH-FATAL-CONDITION-HANDLER in DEFMACRO
WARNING: redefining UIOP/IMAGE:SHELL-BOOLEAN-EXIT in DEFUN
WARNING: redefining UIOP/IMAGE:REGISTER-IMAGE-RESTORE-HOOK in DEFUN
WARNING: redefining UIOP/IMAGE:REGISTER-IMAGE-DUMP-HOOK in DEFUN
WARNING: redefining UIOP/IMAGE:CALL-IMAGE-RESTORE-HOOK in DEFUN
WARNING: redefining UIOP/IMAGE:CALL-IMAGE-DUMP-HOOK in DEFUN
WARNING: redefining UIOP/IMAGE:RAW-COMMAND-LINE-ARGUMENTS in DEFUN
WARNING: redefining UIOP/IMAGE:COMMAND-LINE-ARGUMENTS in DEFUN
WARNING: redefining UIOP/IMAGE:ARGV0 in DEFUN
WARNING: redefining UIOP/IMAGE:SETUP-COMMAND-LINE-ARGUMENTS in DEFUN
WARNING: redefining UIOP/IMAGE:RESTORE-IMAGE in DEFUN
WARNING: redefining UIOP/IMAGE:DUMP-IMAGE in DEFUN
WARNING: redefining UIOP/IMAGE:CREATE-IMAGE in DEFUN
WARNING:
   redefining UIOP/LISP-BUILD::SB-GROVEL-UNKNOWN-CONSTANT-CONDITION-P in DEFUN
WARNING:
   redefining UIOP/LISP-BUILD:CALL-WITH-MUFFLED-COMPILER-CONDITIONS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:WITH-MUFFLED-COMPILER-CONDITIONS in DEFMACRO
WARNING: redefining UIOP/LISP-BUILD:CALL-WITH-MUFFLED-LOADER-CONDITIONS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:WITH-MUFFLED-LOADER-CONDITIONS in DEFMACRO
WARNING: redefining UIOP/LISP-BUILD:CHECK-LISP-COMPILE-WARNINGS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:CHECK-LISP-COMPILE-RESULTS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:REIFY-SIMPLE-SEXP in DEFUN
WARNING: redefining UIOP/LISP-BUILD:UNREIFY-SIMPLE-SEXP in DEFUN
WARNING: redefining UIOP/LISP-BUILD::REIFY-UNDEFINED-WARNING in DEFUN
WARNING: redefining UIOP/LISP-BUILD:REIFY-DEFERRED-WARNINGS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:UNREIFY-DEFERRED-WARNINGS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:RESET-DEFERRED-WARNINGS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:SAVE-DEFERRED-WARNINGS in DEFUN
WARNING: redefining UIOP/LISP-BUILD:WARNINGS-FILE-TYPE in DEFUN

; ----------
; 長すぎたので省略
; ----------

; compiling file "/Users/tamurashingo/cl/func/src/func.lisp" (written 31 DEC 2024 07:32:24 PM):

; wrote /Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64/Users/tamurashingo/cl/func/src/func-tmpGHU3ALSV.fasl
; compilation finished in 0:00:00.001
#<ASDF/LISP-ACTION:LOAD-OP >
#<ASDF/PLAN:SEQUENTIAL-PLAN {7006455533}>
* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64-s/"
tamura shingotamura shingo

警告メッセージを見ると uiop/package のメソッドが再定義されているんですよね。
ということは、システムに付属の UIOP とは違う UIOP を新たに読んでいそうです。

WARNING: redefining UIOP/PACKAGE:FIND-PACKAGE* in DEFUN
WARNING: redefining UIOP/PACKAGE:FIND-SYMBOL* in DEFUN

警告が出ていない方の UIOP の場所

NIL ってことはシステムに統合されているってことでしょうか

* (asdf:component-pathname (asdf:find-system :uiop))
NIL

警告が出ている方の UIOP の場所

ソースコードがありました。

* (asdf:component-pathname (asdf:find-system :uiop))
#P"/Users/tamurashingo/cl/.qlot/dists/quicklisp/software/uiop-3.3.7/"

コードを grep すると *user-cache* をセットしている箇所がわかりました。

 % grep -ni user-cache *
configuration.lisp:18:   #:report-invalid-form #:invalid-configuration #:*ignored-configuration-form* #:*user-cache*
configuration.lisp:173:  (defvar *user-cache* nil
configuration.lisp:208:       ((eql :user-cache) (resolve-absolute-location
configuration.lisp:209:                           *user-cache* :ensure-directory t :wilden nil)))
configuration.lisp:243:                        (member :root :home :here :user-cache))))
configuration.lisp:420:  (defun compute-user-cache ()
configuration.lisp:421:    "Compute (and return) the location of the default user-cache for translate-output
configuration.lisp:423:    (setf *user-cache* (xdg-cache-home "common-lisp" :implementation)))
configuration.lisp:424:  (register-image-restore-hook 'compute-user-cache)

xdg-cache-home の定義はここ

  (defun xdg-cache-home (&rest more)
    "The base directory relative to which user specific non-essential data files should be stored.
Returns an absolute directory pathname.
MORE may contain specifications for a subpath relative to this directory: a
subpathname specification and keyword arguments as per RESOLVE-LOCATION \(see
also \"Configuration DSL\"\) in the ASDF manual."
    (resolve-absolute-location
     `(,(or (getenv-absolute-directory "XDG_CACHE_HOME")
            (os-cond
             ((os-windows-p) (xdg-data-home "cache/"))
             (t (subpathname* (user-homedir-pathname) ".cache/"))))
       ,more)))

これは最終的にはこうなってます。

(resolve-absolute-location '(#P"/Users/tamurashingo/.cache" "common-lisp" :implementation))

resolve-absolute-location も同じ uiop/configuration で定義してあります。

  (defun resolve-absolute-location (x &key ensure-directory wilden)
    "Given a designator X for an absolute location, resolve it to a pathname"
    (ensure-pathname
     (etypecase x
       (null nil)
       (pathname x)
       (string
        (let ((p #-mcl (parse-namestring x)
                 #+mcl (probe-posix x)))
          #+mcl (unless p (error "POSIX pathname ~S does not exist" x))
          (if ensure-directory (ensure-directory-pathname p) p)))
       (cons
        (return-from resolve-absolute-location
          (if (null (cdr x))
              (resolve-absolute-location
               (car x) :ensure-directory ensure-directory :wilden wilden)
              (merge-pathnames*
               (resolve-relative-location
                (cdr x) :ensure-directory ensure-directory :wilden wilden)
               (resolve-absolute-location
                (car x) :ensure-directory t :wilden nil)))))
       ((eql :root)
        ;; special magic! we return a relative pathname,
        ;; but what it means to the output-translations is
        ;; "relative to the root of the source pathname's host and device".
        (return-from resolve-absolute-location
          (let ((p (make-pathname :directory '(:relative))))
            (if wilden (wilden p) p))))
       ((eql :home) (user-homedir-pathname))
       ((eql :here) (resolve-absolute-location
                     (or *here-directory* (pathname-directory-pathname (truename (load-pathname))))
                     :ensure-directory t :wilden nil))
       ((eql :user-cache) (resolve-absolute-location
                           *user-cache* :ensure-directory t :wilden nil)))
     :wilden (and wilden (not (pathnamep x)))
     :resolve-symlinks *resolve-symlinks*
     :want-absolute t))

引数 x(#P"〜〜" "common-lisp" :implementation) なので以下の部分が実行されます。

        (return-from resolve-absolute-location
          (if (null (cdr x))
              (resolve-absolute-location
               (car x) :ensure-directory ensure-directory :wilden wilden)
              (merge-pathnames*
               (resolve-relative-location
                (cdr x) :ensure-directory ensure-directory :wilden wilden)
               (resolve-absolute-location
                (car x) :ensure-directory t :wilden nil))))

resolve-relative-location も同じパッケージで定義されています。
ここでの引数 x("common-lisp" :implementation) なので string:implementation の場合の2パターンが処理対象になります。

  (defun resolve-relative-location (x &key ensure-directory wilden)
    "Given a designator X for an relative location, resolve it to a pathname."
    (ensure-pathname
     (etypecase x
       (null nil)
       (pathname x)
       (string (parse-unix-namestring
                x :ensure-directory ensure-directory))
       (cons
        (if (null (cdr x))
            (resolve-relative-location
             (car x) :ensure-directory ensure-directory :wilden wilden)
            (let* ((car (resolve-relative-location
                         (car x) :ensure-directory t :wilden nil)))
              (merge-pathnames*
               (resolve-relative-location
                (cdr x) :ensure-directory ensure-directory :wilden wilden)
               car))))
       ((eql :*/) *wild-directory*)
       ((eql :**/) *wild-inferiors*)
       ((eql :*.*.*) *wild-file*)
       ((eql :implementation)
        (parse-unix-namestring
         (implementation-identifier) :ensure-directory t))
       ((eql :implementation-type)
        (parse-unix-namestring
         (string-downcase (implementation-type)) :ensure-directory t))
       ((eql :hostname)
        (parse-unix-namestring (hostname) :ensure-directory t)))
     :wilden (and wilden (not (pathnamep x)) (not (member x '(:*/ :**/ :*.*.*))))
     :want-relative t))

ここで :implementation だった場合に implementation-identifier を実行しています。

  (defun implementation-identifier ()
    "Return a string that identifies the ABI of the current implementation,
suitable for use as a directory name to segregate Lisp FASLs, C dynamic libraries, etc."
    (substitute-if
     #\_ #'(lambda (x) (find x " /:;&^\\|?<>(){}[]$#`'\""))
     (format nil "~(~a~@{~@[-~a~]~}~)"
             (or (implementation-type) (lisp-implementation-type))
             (lisp-version-string)
             (or (operating-system) (software-type))
             (or (architecture) (machine-type))
             #+sbcl (if (featurep :sb-thread) "S" "")))))

sbcl で :sb-thread がある場合に "S" が付いています。

それぞれ確認してみます。

テストできる環境

* (in-package :uiop/os)
#<PACKAGE "UIOP/OS">
* (implementation-identifier)
"sbcl-2.4.9.roswell-macosx-arm64"

テストできない環境

* (in-package :uiop/os)
#<PACKAGE "UIOP/OS">
* (implementation-identifier)
"sbcl-2.4.9.roswell-macosx-arm64-s"

この変更が入ったのがいつなのかを確認してみます。

tamura shingotamura shingo

uiop/os::implementation-identifier
に変更が入ったのがこのコミットでした。
https://gitlab.common-lisp.net/asdf/asdf/-/commit/92fb0e6ee7127e10ede9767bf3473316a7b80a7d

これをチェックアウトしてそのときのバージョンを確認すると、3.3.6.1 なのでそれ以降のバージョンで導入されたようです。

% git grep uiop-version
backward-driver.lisp:(with-deprecation ((version-deprecation *uiop-version* :style-warning "3.2" :warning "3.4"))
version.lisp:   #:*uiop-version*
version.lisp:  (defparameter *uiop-version* "3.3.6.1")

ros run での uiop のバージョンは 3.3.1 で、この -s が入る前のバージョンでした。

% ros run
* uiop:*uiop-version*
"3.3.1"

qlot exec ros runlocal-time をロードしたあとの uiop のバージョンは 3.3.7 でした。

% qlot exec ros run
* (ql:quickload :local-time)
To load "local-time":
  Load 1 ASDF system:
    local-time
; Loading "local-time"

(:LOCAL-TIME)
* uiop:*uiop-version*
"3.3.7"

ということで、 local-time をロードすると rove でテストできない原因は local-timeuiop を明示的に依存ライブラリとして呼び出しているので、処理系に付属の uiop よりバージョンが上がってしまったことによるもの、と考えられそうです。

tamura shingotamura shingo

で、どうしたか?

asdf をバージョンアップ (grade up) を実施しました。

https://asdf.common-lisp.dev/asdf.html#Replacing-your-implementation_0027s-ASDF

この内容を参考に、 asdf を clone してきて (load "tools/install-asdf.lisp") を実行しました。

* asdf:*user-cache*
#P"/Users/tamurashingo/.cache/common-lisp/sbcl-2.4.9.roswell-macosx-arm64-s/"
* (ql:quickload '("rove" "func"))
To load "rove":
  Load 1 ASDF system:
    rove
; Loading "rove"
....
To load "func":
  Load 1 ASDF system:
    func
; Loading "func"

("rove" "func")
* (rove:run "func-test")

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
T
(#<ROVE/CORE/RESULT:PASSED-TEST func-test (PASSED=1, FAILED=0)>)

無事にテストができました。

tamura shingotamura shingo

別の問題

REPL からのテストはできたのですが、 rove コマンドを使ったテストが動かなくなりました。
いや、動いてはいるのですが結果が出力されなくなりました 🥲

% qlot exec rove func.asd
% echo $?
0

rove コマンドに *standard-output* を変更している部分があるのですが、

(defun run-file-tests (file)
  (let ((tries-so-far (make-hash-table :test 'equalp))
        (rove/core/suite:*rove-standard-output* (get-real-stream *standard-output*))
        (rove/core/suite:*rove-error-output* (get-real-stream *error-output*))
        (*standard-output* (make-broadcast-stream))
        (system-name (cond
                       ((equal (pathname-type file) "lisp")
                        (let ((*print-case* :downcase))

この部分を

(defun run-file-tests (file)
  (let ((tries-so-far (make-hash-table :test 'equalp))
        (rove/core/suite:*rove-standard-output* (get-real-stream *standard-output*))
        (rove/core/suite:*rove-error-output* (get-real-stream *error-output*))
;;        (*standard-output* (make-broadcast-stream))
        (system-name (cond
                       ((equal (pathname-type file) "lisp")
                        (let ((*print-case* :downcase))
                          (princ-to-string
                           (second (asdf/package-inferred-system::file-defpackage-form file)))))
                       ((equal (pathname-type file) "asd")
                        (pathname-name file)))))
    (tagbody retry
       (handler-case

こうコメントアウトして実行してみると、ちゃんと結果が出力されています。

% qlot exec rove func.asd

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
tamura shingotamura shingo

これだと CI に組み込むのが難しいので、もうちょっと正攻法で行こうと思います。
(sbcl はインストールしなおして 3.3.1 を使うようにしてあります)

quicklispuiop を落とすと 3.3.7 になるのが問題なので、 qlotsbcl 付属と同じ 3.3.1 を落としておけばよいではないでしょうか。

quicklisp では https https://asdf.common-lisp.dev/archives/uiop.tar.gz と指定されています。

https://github.com/quicklisp/quicklisp-projects/blob/master/projects/uiop/source.txt

ここからこのディレクトリを直接見に行くと、過去のバージョンも落とせることがわかりました。

qlfile には次のように記入します。

qlfile
ql rove
http uiop https://asdf.common-lisp.dev/archives/uiop-3.3.1.tar.gz

これで qlot install して実行すると無事にテストが実行できました。

% qlot install
Installing Quicklisp to /Users/tamurashingo/cl/func/.qlot/...
Reading '/Users/tamurashingo/cl/func/qlfile'...
✓ [1/3] quicklisp  Newly installed "quicklisp" version "2024-10-12".
✓ [2/3] rove  Newly installed "rove" version "ql-2024-10-12".
✓ [3/3] uiop  Newly installed "uiop" version "http-7a90377c4fc96676d5fa5197d9e9ec11".
Loaded 1 system files.
Ensuring 11 dependencies installed.
Successfully installed.
% qlot exec rove func.asd
WARNING: System definition file #P"/Users/tamurashingo/cl/func/func.asd" contains definition for system "func-test". Please only define "func" and secondary systems with a name starting with "func/" (e.g. "func/test") in that file.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:PREPARE-OP
                                                     "func-test"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                                   "func") wasn't done yet!

Testing System func-test

;; testing 'func-test'
add3-is-correct
  ✓ Expect (= 6 (ADD3 3)) to be true.

✓ 1 test completed

Summary:
  All 1 test passed.
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/LISP-ACTION:LOAD-OP
                                                                              "func") wasn't done yet!
WARNING:
   Computing just-done stamp in plan NIL for action (ASDF/LISP-ACTION:TEST-OP
                                                     "func"), but dependency (ASDF/FIND-SYSTEM:DEFINE-OP
                                                                              "func") wasn't done yet!
このスクラップは2025/01/16にクローズされました