Quicklispで自作モジュールを使用する

# Quicklispで自作モジュールを使用する

## MOTIVATION

Quicklispのリポジトリにないライブラリを使いたい！
自作して登録するまでもないようなものや、会社でつくったやつだから外にだせないようなものなど。


## やり方

### Quicklispのホームディレクトリの調査

REPL上で ql:*quicklisp-home* を評価すると教えてくれます。

```cl
CL-USER> ql:*quicklisp-home*
#P"/home/shingo/quicklisp/"
```

ここの下にあるlocal-projectsというディレクトリが、自分で作ったライブラリなどを配置しておく場所になります。


### 展開

今回、このような構成のライブラリを登録します。

```
./
 src/
    my-special-lib.lisp
 t/
  my-special-lib-test.lisp
 my-special-lib.asd
 my-special-lib-test.asd
 package.lisp
```

local-projects下にmy-special-libというディレクトリを掘り、その下にファイルを配置していきます。
ディレクトリ名は何でも大丈夫です。深さがあっても大丈夫です。

なので、自社ライブラリ用とgithub等からダウンロードしてきた用に分ける、という運用もできます。

```cl:my-special-lib.asd
(in-package :cl-user)
(defpackage my-special-lib-asd
  (:use :cl :asdf))
(in-package :my-special-lib-asd)

(defsystem my-special-lib
  :description "sample library"
  :version "0.1"
  :author "tamura shingo"
  :license "GPL"
  :components ((:file "package")
               (:module "src"
                :components
                ((:file "my-special-lib"))))
  :in-order-to ((test-op (load-op my-special-lib-test))))
```
```cl:my-special-lib-test.asd
(in-package :cl-user)
(defpackage my-special-lib-test-asd
  (:use :cl :asdf))
(in-package :my-special-lib-test-asd)

(defsystem my-special-lib-test
  :description "test for my-special-lib"
  :depends-on (:my-special-lib
               :cl-test-more)
  :components ((:module "t"
                :components
                ((:file "my-special-lib-test"))))
  :perform (load-op :after (op c) (asdf:clear-system c)))
```

```cl:package.lisp
(in-package :cl-user)

(defpackage :my-special-lib
  (:use :cl)
  ; src/my-special-lib.lisp
  (:export :greeting))
```

```cl:src/my-special-lib.lisp
(in-package #:my-special-lib)

(defun greeting ()
  "hello world")
```

```cl:t/my-special-lib-test.lisp
(in-package :cl-user)
(defpackage my-special-lib-test
  (:use :cl
        :cl-test-more
        :my-special-lib))
(in-package #:my-special-lib-test)

(plan 1)

(ok (string= (my-special-lib:greeting) "hello world"))

(finalize)
```

### 登録
ローカルプロジェクトの登録を行います。

```cl
CL-USER> (ql:register-local-projects)
NIL
```

local-projectsディレクトリ下にsyystem-index.txtと言うファイルが作成されます。
中身はこんな感じです。

```bash
$ cat system-index.txt 
my-special-lib/my-special-lib.asd
my-special-lib/my-special-lib-test.asd
```


### 使う

登録が完了したらもう使える状態になっています。

```cl
CL-USER> (ql:quickload "my-special-lib")
To load "my-special-lib":
  Load 1 ASDF system:
    my-special-lib
; Loading "my-special-lib"
[package my-special-lib]
("my-special-lib")
CL-USER> (my-special-lib:greeting)
"hello world"
```

テストも行えます。テストにはcl-test-moreを使っています。

```cl
CL-USER> (ql:quickload "my-special-lib-test")
To load "my-special-lib-test":
  Load 1 ASDF system:
    my-special-lib-test
; Loading "my-special-lib-test"
To load "cl-test-more":
  Install 2 Quicklisp releases:
    cl-ppcre cl-test-more
; Fetching #<URL "http://beta.quicklisp.org/archive/cl-ppcre/2014-02-11/cl-ppcre-2.0.7.tgz">
; 154.47KB
==================================================
158,175 bytes in 0.83 seconds (186.33KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/cl-test-more/2014-02-11/cl-test-more-20140211-git.tgz">
; 4.07KB
==================================================
4,166 bytes in 0.00 seconds (5836.96KB/sec)
; Loading "cl-test-more"
[package cl-ppcre]................................
..................................................
..................................................
[package cl-test-more.asdf].......................
[package cl-test-more]...........
; Loading "my-special-lib-test"
[package my-special-lib-test]1..1
ok 1

("my-special-lib-test")
```


## まとめ
* Quicklispのリポジトリに登録されていないモジュールは local-projects 下に配置しましょう
* その後は普通に使えます
* Quicklispでインハウスリポジトリが使えると良いのですが。。。