如何在Common Lisp中找到给定项目的完整依赖树?
我已尝试使用(ql-dist:dependency-tree "my-project")
哪些错误((ql-dist:find-system "my-project")
返回nil
无论我的系统是否已加载),(slot-value (asdf/system:find-system "my-project") 'asdf/component:sideway-dependencies)
似乎只返回直接依赖关系,我正在寻找完整的树(它似乎也返回条件/特定于实现的依赖关系,例如sb-posix
和sb-bsd-sockets
,我更愿意这样做
是否有标准的一步式方法,或者我是否需要以递归方式遍历sideway-dependencies
插槽的输出并过滤特异性?
答案 0 :(得分:1)
这是解决方案的一个方面:
拿3分(在这个阶段可能是一个自己的项目):
(defgeneric ->key (thing))
(defmethod ->key ((thing string))
(intern (string-upcase thing) :keyword))
(defmethod ->key ((thing symbol))
(if (keywordp thing)
thing
(intern (symbol-name thing) :keyword)))
(defgeneric dependencies-of (system))
(defmethod dependencies-of ((system symbol))
(mapcar #'->key (slot-value (asdf/system:find-system system) 'asdf/component:sideway-dependencies)))
(defun ordered-dep-tree (dep-tree)
(let ((res))
(labels ((in-res? (dep-name) (member dep-name res))
(insert-pass (remaining)
(loop for (dep . sub-deps) in remaining
for unmet-sub-deps = (remove-if #'in-res? sub-deps)
if (null unmet-sub-deps) do (push dep res)
else collect (cons dep unmet-sub-deps) into next-rems
finally (return next-rems))))
(loop for (dep . callers) in dep-tree for deps-of = (dependencies-of dep)
if (null deps-of) do (push dep res)
else collect (cons dep deps-of) into non-zeros
finally (loop while non-zeros
do (setf non-zeros (insert-pass non-zeros)))))
(reverse res)))
(defgeneric dependency-tree (system))
(defmethod dependency-tree ((system symbol))
(let ((res (make-hash-table)))
(labels ((rec (sys)
(loop with deps = (dependencies-of sys)
for dep in deps for dep-k = (->key dep)
unless (gethash dep-k res) do (rec dep)
do (pushnew (->key sys) (gethash dep-k res)))))
(rec system))
(ordered-dep-tree (alexandria:hash-table-alist res))))
仍然没有过滤sb-*
式的包,但我想我可以在单独的传递中做到这一点。它似乎工作...
CL-USER> (dependency-tree :hunchentoot)
(:SB-BSD-SOCKETS :TRIVIAL-BACKTRACE :RFC2388 :SB-ROTATE-BYTE
:TRIVIAL-GARBAGE :TRIVIAL-FEATURES :CL-PPCRE :ALEXANDRIA :SB-POSIX
:CL-BASE64 :TRIVIAL-GRAY-STREAMS :USOCKET :MD5 :BABEL :FLEXI-STREAMS
:BORDEAUX-THREADS :CHUNGA :CFFI :CL-FAD :CL+SSL)
我认为是在:hunchentoot
之前需要加载的所有软件包的列表,按照可以加载的顺序显示(在所有依赖项之前没有包出现)出现)。它没有处理循环依赖,但我不认为asdf也是如此,所以...