Я работаю над задачами Эйлера проекта в SBCL и сохраняю короткий файл для каждого решения. Каждая проблема имеет несколько тестов, основанных на 5 утра, на которые ссылаются из «основного» набора тестов. Эти тесты запускаются при запуске "tests.lisp". Поскольку мне надоело поддерживать список файлов вручную, я написал код, который делает это за меня:
(defpackage #:euler/asdf
(:use :cl :asdf))
(in-package #:euler/asdf)
;; directory containing the problem files
(defparameter +dir+ "/home/stefan/quicklisp/local-projects/euler")
;; build file list for package components
(defun files-for-problems (dir)
(mapcar #'(lambda (p) (list :file (pathname-name p) :depends-on '("package")))
(directory (concatenate 'string dir "/e????.lisp"))))
;; build dependency list for all tests component
(defun depends-on-problems (dir)
(mapcar #'pathname-name
(directory (concatenate 'string dir "/e????.lisp"))))
;; define euler system
(defsystem euler
:name "euler"
:author "Stefan Schmiedl"
:description "Solutions to problems at http://projecteuler.net"
:depends-on ("iterate" "fiveam" "cl-csv")
:components #.`((:file "package")
,@(files-for-problems +dir+)
#.`(:file "tests" :depends-on ,(depends-on-problems +dir+))))
Короче говоря, defsystem euler
использует все файлы e????.lisp в качестве компонентов, а тесты.lisp зависят от всех этих файлов.
Это хорошая идея? Есть ли «официальный» способ заставить defsystem
использовать все файлы в каталоге или все файлы, соответствующие заданному шаблону имени файла?
Я чувствую, что упускаю здесь что-то элементарное, особенно после прочтения некоторых слайды ELS на github о "более декларативной системе защиты", где то, что я сделал выше, вероятно, будет неодобрительно.
После некоторого возни с предложением Фаре вот что у меня теперь есть:
;; define private package for defsystem
(defpackage #:euler-system
(:use :cl :uiop :asdf))
(in-package #:euler-system)
;; define euler system
(defsystem "euler"
:author "Stefan Schmiedl"
:description "Solutions to problems at http://projecteuler.net"
:depends-on ("iterate" "fiveam" "cl-csv")
:components ((:module "package"
:pathname ""
:components ((:file "package")))
(:module "problems"
:pathname ""
:depends-on ("package")
:components #.(mapcar #'(lambda (p) (list :file (pathname-name p)))
(directory-files (pathname-directory-pathname
(uiop/lisp-build:current-lisp-file-pathname))
"e*.lisp")))
(:module "tests"
:pathname ""
:depends-on ("package" "problems")
:components ((:file "tests")))))
Спасибо за ответ.