Общая организация исходного кода Lisp
Я новичок в CL и использую AllegroCL. Я пытаюсь выяснить, как организовать мой исходный код для удовлетворения следующих требований:
- Я хочу, чтобы код src не включал мои тестовые наборы.
- Я хочу объявить зависимости проекта (как src, так и test deps) переносимым способом, чтобы другим членам моей команды не приходилось изменять свои системы.
- Я хочу упростить непрерывную интеграцию при регистрации, включая сборки и тесты.
Я пытался творчески использовать ASDF для удовлетворения этих требований, и я не могу понять это правильно. Как другие люди подходят к этой проблеме? Эти 2 требования просто не "Lispy"?
5 ответов
Используйте ASDF или инструмент защиты Allegro CL.
- сделать их двумя разными системами. Система набора тестов зависит от системы программного обеспечения.
- Используйте относительные имена путей, вычисляйте абсолютные пути на основе расположения файла определения системы или, в "профессиональной" версии, используйте логические имена путей (которые являются путями в CL, которые могут быть переназначены в соответствии с правилами).
- Возможно, для Common Lisp есть инструмент непрерывной интеграции, но я еще не использовал его. Наличие описания системы - хорошее начало.
Я использую quicklisp, который создает папку "quicklisp" в вашей домашней папке, в которой можно найти папку "local-project". Этот файл содержит текстовый файл, в который вы можете вставить URI в файлы.asd.
Как использовать эту утилиту:
- сделать "project.asd" и "project-test.asd" в папке проекта
project.asd (управляет включениями для чистого кода проекта)
(asdf:defsystem :project-name
:description "description here"
:version "version here"
:author "your name here"
:depends-on (:a
:list
:of
:dependencie
:libraries)
:components ((:file "sourcefileone")
(:file "sourcefiletwo")))
project-test.asd (управляет включениями для тестового кода)
(asdf:defsystem :project-name-test
:description "testing"
...
:depends-on (:project-name)
:components ((:file "sourcefileone-test")
(:file "sourcefiletwo-test")))
Теперь вставьте URI для этих файлов в вышеупомянутый local-projects.txt
запрограммируйте параллельный источник проекта в файлах
.lisp и вызовы test в файлах -test.lisp (файлы *-test.lisp должны содержать вызов test-execute) запустите ваш sbcl или что вы используете, а затем используйте
(ql:quickload "project-name")
или же(ql:quickload "project-name-test")
в зависимости от того, хотите ли вы загрузить проект или протестировать его.
Единственное, что вам нужно сделать для переноса этого куда-либо еще, - это написать local-projects.txt на компьютере, на который копируется проект. После этого ваши колледжи могут зависеть от этого при использовании asdf-файлов и быстрой загрузки в любой другой проект, который они хотят. Для копирования папки проекта вы можете использовать ctr+c/v или что-то более сложное, например, git.
Для тестирования я запрограммировал свой небольшой набор тестов, но держу пари, что есть хорошие. Более подробную информацию о quicklisp можно найти здесь и об asdf здесь. Может быть, этот вопрос поможет вам, если вы застряли в настройке quicklisp.
Если Quicklisp установлен, вы можете использовать встроенную функцию Quickproject.
(ql:quickload "quickproject")
(quickproject:make-project "~/src/lisp/swatchblade/"
:depends-on '(vecto hunchentoot))
Это создает 4 файла:
- package.lisp
- swatchblade.lisp
- swatchblade.asd
- README.txt
package.lisp определяет пространства имен пакетов:
(defpackage #:swatchblade
(:use #:cl)
(:shadowing-import-from #:vecto
#:with-canvas
#:rounded-rectangle
#:set-rgb-fill
#:save-png-stream))
swatchblade.asd определяет систему / проект, файлы исходного кода, зависимости и т. д.
(asdf:defsystem #:swatchblade
:serial t
:depends-on (#:vecto
#:hunchentoot
#:cl-colors)
:components ((:file "package")
(:file "swatchblade")))
swatchblade.lisp - это место, куда отправляется исходный код.
Вы можете загрузить проект с помощью быстрой загрузки Quicklisp:
* (ql:quickload "swatchblade")
loading output
* (swatchblade:start-web-server :port 8080)
Server started on port 8080.
Если затем вы создадите другой проект, который зависит от системы swatchblade:
quickproject:make-project "~/src/lisp/whimsytron/"
:depends-on '(swatchblade))
Что касается тестов, вы можете добавить еще одно пространство имен в package.lisp для ваших тестов:
(defpackage #:swatchblade-tests
(:use #:cl #:swatchblade))
Создайте тестовый файл, напишите код и добавьте файл в определение системы:
(asdf:defsystem #:swatchblade
:serial t
:depends-on (#:vecto
#:hunchentoot
#:cl-colors)
:components ((:file "package")
(:file "swatchblade")
(:file "swatchglade-tests")))
Загрузите пространство имен swatchblade-tests для запуска тестов.
Пример проекта с тестами здесь
Если вы хотите избежать установки QuickLisp всех зависимостей в систему, вам придется установить эти зависимости и загрузить систему вручную, насколько мне известно.
У автора Quicklisp, Зака Бина, есть более подробное сообщение об использовании quickproject.
По предложению Райнера, я предлагаю вам использовать средство определения системы ASDF для определения двух систем: вашей основной системы foo и вспомогательных систем foo-тестов.
В определении системы foo добавьте спецификацию, которая in-order-to
сделать test-op
на фу, нужно сделать test-op
на фу-тестах. Это гарантирует, что если вы делаете (asdf:test-system "foo")
соответствующая тестовая система с ее зависимостями будет загружена, а затем ASDF выполнит тестовую операцию.
Я считаю, что FiveAM- это подходящая библиотека для построения тестов.
Выше будет загружено все, но теперь вам нужно убедиться, что делать test-op
на foo-tests фактически запускает тесты! Для этого вам нужно добавить метод PERFORM
за TEST-OP
а также (eql (find-system "foo-tests"))
, Тот PERFORM
Метод должен вызвать все тесты FiveAM, которые вы определили, и либо выполнить успешно, либо вызвать ошибку, если тесты не пройдены.
Я сделал дополнение для тестеров FiveAM для ASDF. Я постараюсь узнать, как сделать его общедоступным.
ВАЖНЫЙ
Приведенный выше совет хорош, но вы будете разочарованы, пытаясь проверить не экспортированные вещи. Простой обходной путь - не определять два пакета. Просто поместите ваши тесты в один пакет с другими вашими источниками. В чем вред?
Если вы думаете, что будет вред, вам придется сделать это так:
(defpackage #:sources
(:use #:cl))
(defpackage #:tests
(:use #:cl #:lisp-unit)
(:import-from #:sources))
Важной частью является :import-from
ваш исходный пакет вместо :use
это
Тогда вам нужно будет квалифицировать символы в вашем исходном пакете, когда вы будете использовать их в своем тестовом пакете. Например, скажем, у вас есть эта функция:
(defun return-true () t)
Ваш тест может выглядеть так:
(define-test test-return-true
"Make sure it works"
(assert-equal t (sources::return-true)))
Важная часть твоего говоришь (sources::return-true)
вместо просто (return-true)
, То же самое касается символов, таких как 'sym
; относиться к нему как 'sources::sym
,