Общая организация исходного кода Lisp

Я новичок в CL и использую AllegroCL. Я пытаюсь выяснить, как организовать мой исходный код для удовлетворения следующих требований:

  1. Я хочу, чтобы код src не включал мои тестовые наборы.
  2. Я хочу объявить зависимости проекта (как src, так и test deps) переносимым способом, чтобы другим членам моей команды не приходилось изменять свои системы.
  3. Я хочу упростить непрерывную интеграцию при регистрации, включая сборки и тесты.

Я пытался творчески использовать ASDF для удовлетворения этих требований, и я не могу понять это правильно. Как другие люди подходят к этой проблеме? Эти 2 требования просто не "Lispy"?

5 ответов

Решение

Используйте ASDF или инструмент защиты Allegro CL.

  1. сделать их двумя разными системами. Система набора тестов зависит от системы программного обеспечения.
  2. Используйте относительные имена путей, вычисляйте абсолютные пути на основе расположения файла определения системы или, в "профессиональной" версии, используйте логические имена путей (которые являются путями в CL, которые могут быть переназначены в соответствии с правилами).
  3. Возможно, для 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,

Другие вопросы по тегам