# Roswell - Common Lisp environment setup Utility

Есть такой интересный проект, связанный с Common Lisp, как [Roswell](https://github.com/roswell/roswell "Roswell"), который предназначен для установки и одновременного использования различных версий лиспа в систему. А так же интегрирован с quicklisp, несколько расширяя его возможности. Помимо прочего предоставляет возможность создания своих собственных скриптов на лиспе.

Использовать можно на целом ряде систем, в MacOS ставить очень просто:

```shell
$ brew install roswell
```

Есть пакет для Arch Linux, и предполагается подготовить для других дистрибутивов. Под Windows мне так и не удалось заставить его работать. Во всех остальных случаях предлагается устанавливать Roswell с помощью компиляции исходников.

По возможностям Roswell отправлять почитать официальную страницу. Довольно подробно описано все, что нужно. А сейчас хотел бы остановиться на некоторых проблемах.

Roswell особо привлекает к себе внимание из-за возможности создавать скрипты, в которых очень просто использовать quicklisp. SBCL в режиме скрипта данной возможности не имеет. Вроде все просто, создаем скрипт:

```sh
$ ros init script
$ cat script.ros
#!/bin/sh
#|-*- mode:lisp -*-|#
#| <Put a one-line description here>
exec ros -Q -- $0 "$@"
|#
(progn ;;init forms
  (ros:ensure-asdf)
  ;;#+quicklisp (ql:quickload '() :silent t)
  )

(defpackage :ros.script.script.3696842266
  (:use :cl))
(in-package :ros.script.script.3696842266)

(defun main (&rest argv)
  (declare (ignorable argv)))
;;; vim: set ft=lisp lisp:
```

Теперь достаточно прописать требуемые действия в функцию `main` и все будет работать. При этом можно парсить аргументы командной строки, что передаются при запуске скрипта, и хранятся в переменной `argv`. К примеру, чтобы вывести первый аргумент (без проверки на его существование), добавляем вызов одной команды:

```lisp
(defun main (&rest argv)
  (declare (ignorable argv))
  (print (first argv)))
```

Теперь при запуске с передачей аргумента увидим ее значение:

```shell
$ ./script.ros 234
"234"
```

Вроде все замечательно и все хорошо. Но я попытался использовать roswell-скрипт Александра Артеменко, что он написал для запуска генератора статических сайтов coleslaw: [coleslaw-cli](https://github.com/40ants/coleslaw-cli/blob/master/coleslaw.ros "Coleslaw CLI"). И сколько я не пытался, скрипт у меня ни разу нормально не отработал.

Для парсинга командной строки Александр использовал библиотеку `clon`. Да, она очень удобна и функциональна, но подружить ее с Roswell мне так и не удалось. При запуске в режиме скрипта clon просто не отрабатывал. А вот если преобразовать скрипт в образ, то парсинг начинает нормально работать.

Хорошо, решил переписать скрипт, отказавшись от clon. В итоге получил следующее:

```sh
#!/bin/sh
#|-*- mode:lisp -*-|#
#| <Put a one-line description here>
exec ros -Q -- $0 "$@"
|#
(progn ;;init forms
  (ros:ensure-asdf)
  #+quicklisp (ql:quickload '("coleslaw") :silent t)
  )

(defpackage :ros.script.col.3696839213
  (:use :cl :coleslaw))
(in-package :ros.script.col.3696839213)

(defun main (&rest argv)
  (declare (ignorable argv))
  (if (< (length argv) 1)
      (progn
        (format t "Please fill directory")
        (SB-EXT:EXIT))
      (progn
        (let ((directory (nth 0 argv)))
          (format t directory)
          (coleslaw:main directory)))))
```

И тут столкнулся очень интересной багой. По другому даже не знаю как назвать. Вызов `coleslaw:main` приводит к запуску функции `main` данного скрипта, что приводит к бесконечному выполнению.

**Update**: После того, как написал статью, Александр указал мне на мою ошибку. Как оказалось, после использования `ql:quickload` не нужно было еще дополнительно прописывать coleslaw в секции `use`. Убрал, все заработало. Более того, используя команду `ros build col.ros` в короткий промежуток времени получил бинарник, который позволяет запускать coleslaw. Век живи, век учись...

