История установки RULISP для изучения.
Предварительные условия: у меня на машине с Gentoo установлен свежий SBCL (1.0.38.gentoo-r0), в портеж добавлен оверлей gentoo-lisp-overlay, из которого я буду ставить большинство пакетов CL. Также из портежа поставлен PostgreSQL 8.4 для базы данных форума.
Использовалась инструкция по установке отсюда.
Этап 1. Подготовка
- Для начала я создал рабочую директорию
~/workspace/lisp
- здесь будут находиться пакеты, необходимые для запуска RULISP. - В эту директорию загрузил следующие пакеты с гитхаба: cl-closure-template, cl-pdf, cl-recaptcha, cl-routes, colorize, garbage-pools, puri-unicode, restas, restas-colorize, restas-directory-publisher, restas-forum, restas-planet, restas-simple-auth, restas-wiki, rulisp.
- Создал директорию
~/workspace/lisp/systems
для добавления пакетов в ASDF. - Сделал симлинки на все файлы
*.asd
из загруженных пакетов. - В
~/.sbclrc
прописал строчку для того, чтобы установленные пакеты были доступны в ASDF:
(push (merge-pathnames "workspace/lisp/systems/" (user-homedir-pathname)) asdf:*central-registry*)
- Создал от рута директории
/var/cache/rulisp
(для кэша планеты) и/var/rulisp
(здесь будут храниться данные для вики). Так как я буду запускать программу от своего имени, то сделал chown на эти директории. - Скачал
http://pcl.catap.ru/snapshot.zip
и распаковал файлы из содержащейся в нем директории/var/www/pcl.catap.ru/htdocs/data/pages/pcl/
в/var/rulisp/pcl
- это страницы dokuwiki для отображения в разделе PCL. В файлеrulisp/pref.lisp
исправил строчку, указывающую на расположение страниц PCL:
(defparameter *pcl-dir* #P"/var/rulisp/pcl/")
- Чтобы не мучиться с зависимостями пакетов, имея оверлей gentoo-lisp-overlay, я просто поставил оттуда пакет restas - он вытянул все необходимые для компиляции пакеты, а моя настройка в
~/.sbclrc
заставляет SBCL использовать версии пакетов из гита. (Как вариант можно во время компиляции получать ошибки вида "пакет XXX не найден" и тут же бежать в консоль его ставить. Но это неинтересно :).
Этап 2. Создание базы
Postgres у меня уже был настроен, так что я запустил psql и создал базу rulisp:
$ psql > create database rulisp;Далее нужно было создать структуру базы, я воспользовался скриптами из директории
rulisp/install
:> \i ~/workspace/rulisp/install/user.sql > \i ~/workspace/rulisp/install/forum.sql > \i ~/workspace/rulisp/install/format.sqlНа файле
forum.sql
я получил ошибку вида:psql:forum.sql:83: ERROR: language "plpgsql" does not existКак выяснилось - для хранимых функций требуется поддержка языка PgPlSQL. Чтобы её добавить, выполнил от имени пользователя
postgres
следующую команду:> create procedural language pgplsql;Теперь повторный запуск скрипта
forum.sql
выполнился весь. Осталось выполнить скрипты обновлений users.update-01.sql
, users.update-02.sql
, forum.update-1.sql
и format.update-01.sql
.В последнюю очередь исправил в файле
rulisp/pref.lisp
строчку с параметрами подключения к базе данных (второе значение - имя пользователя, а третье я оставил пустым, так как запускаю из-под того же пользователя):(defparameter *rulisp-db* '("rulisp" "lisp" "123" "localhost"))
Этап 3. Запуск
Запускал RULISP конечно же в Emacs со SLIME-ом. SLIME тоже взял с гита. Выполнил загрузку пакета rulisp:
CL-USER> (asdf:oos 'asdf:load-op :rulisp)
Подождал немного, пока оно собирается и... получил странное сообщение:erred while invoking #<COMPILE-OP NIL {1003B3B5D1}> on #<CL-SOURCE-FILE "pcl" {10047DBF01}>Мучился я с ним недолго - такое уже бывало раньше при большом изменении пакетов. Я просто удалил FASL-ы из
~/.fasls
и запустил сборку еще раз. Теперь все прошло хорошо.Наконец-то :) запустил движок:
CL-USER> (restas:start '#:rulisp :port 8080)Открыл в браузере
http://localhost:8080
и получил что-то очень знакомое. :) Побродил по страницам и разок выскочила ошибка Internal Server Error 500
. Чтобы посмотреть что происходит установил отладочный параметр:CL-USER> (setf hunchentoot:*catch-errors-p* nil)Теперь в случае ошибок в Emacs выскакивает отладчик. Можно поглядеть содержимое переменных с помощью инспектора по C-c I.
Заключение
Теперь в моей рабочей директории целая куча репозиториев, которые надо периодически синхронизировать. Чтобы меньше трудиться, написал простой скрипт для обновления
update.sh
:#!/bin/sh # Сначала обновляем все локальные репозитории for i in `find . -maxdepth 1 -mindepth 1 -type d`; do if [ -d "${i}/.git" ]; then echo "******* Обновление пакета ${i}" cd $i git pull cd .. fi done # Теперь собираем образ SBCL со SWANK sbcl --noinform --noprint --disable-debugger --eval \ "(progn (load \"/home/maestro/workspace/lisp/slime-archimag/swank-loader.lisp\")\ (save-lisp-and-die \"/home/maestro/.emacs.d/sbcl.core-for-slime\"))"И положил этот скрипт в директорию
~/workspace/lisp/
- скрипт обходит все поддиректории и проверяет, есть ли в них .git
, а потом вызывает git pull
для обновления. Потом производится сборка образа SBCL для быстрой загрузки в Emacs.