common-lisp - 查找系统的依赖项

标签 common-lisp

如何在 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) 似乎只返回 direct 依赖关系,我正在寻找完整的树(它似乎也返回条件/特定于实现的依赖关系,例如 sb-posixsb-bsd-sockets,我宁愿没有它们。

是否有标准的一步法来执行此操作,或者我是否需要递归遍历 sideway-dependencies 插槽的输出并进行特殊过滤?

最佳答案

解决方法如下:

Take 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-* 风格的包,但我想我可以在一个单独的 channel 中做到这一点。它似乎工作虽然...

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 也不处理,所以...

关于common-lisp - 查找系统的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22722500/

相关文章:

list - 递归拆分列表函数 LISP

common-lisp - 如何在 Common Lisp 中进行基于图像的开发?

list - 从 Common-lisp 中的列表的任何级别删除所有出现的元素

algorithm - 列表中元素的随机分配

Emacs+Slime lower-lisp 异常退出,代码为 5

lisp - Geany 作为 CommonLisp IDE

common-lisp - 为 eval 设置环境(包?)

common-lisp - 如何 (zerop #*000) 在普通 lisp 中?

error-handling - 启动预先存在的重启的最快、最简单的方法是什么?

java - 你能用 ABCL 写一个 Java 类吗?