Qlot is a project-local library installer using Quicklisp facility. This aims to be like Bundler of Ruby or Carton of Perl.
Warning: This software is still ALPHA quality. The APIs will be likely to change.
# "qlfile" of "myapp"
git clack https://github.com/fukamachi/clack.git
github datafly fukamachi/datafly :branch v0.7.x
ql log4cl 2014-03-17
;; Installing libraries project-locally.
(qlot:install :myapp)
;; Loading a project with its project-local quicklisp.
(qlot:quickload :myapp)
;; Updating depending libraries of a project.
(qlot:update :myapp)
We have Quicklisp, the central library registry. It made installation of libraries damn easy.
However, what only you can specify is the month of distribution. Which means you have to use all libraries of the same moment and you cannot use a newer/older version of a library for your project.
"local-projects/" or ASDF configurations may be a solution to this problem, but there are a couple of problems.
-
They are not project-local. If you have multiple projects that use the different version of the same library, it would be a problem.
-
They are difficult to fix the version or to update them. If your project need to work on other than your machine, for instance on other people's machine or on servers, the version of depending libraries should be the same.
This is what qlot is trying to solve.
As qlot is going to be included in Quicklisp dist in August 2014, you can install it through Quicklisp.
(ql:quickload :qlot)
Put a file "qlfile" at the root of your project directory.
See qlfile syntax section to know how to write it.
You can install libraries into the project directory via:
(qlot:install :myapp)
It creates quicklisp/
directory in the project directory and a file qlfile.lock
.
qlfile.lock
is similar to qlfile
except the library versions are qualified. This will ensure that other developers or your deployment environment use exactly the same versions of libraries you just installed.
Make sure you add qlfile
and qlfile.lock
to your version controlled repository and make the quicklisp/
directory ignored.
$ echo quicklisp/ >> .gitignore
$ git add qlfile qlfile.lock
$ git commit -m 'Start using qlot.'
To load your qlot-ready application, use qlot:quickload
instead of ql:quickload
.
(qlot:quickload :myapp)
Although qlot:quickload
loads a project with its project-local Quicklisp, the Quicklisp path will be restored to the default one after that.
This could cause significant problem if your application loads other libraries during run-time.
For example, Clack loads a server handler when executing clackup
and, the important part is, it loads with the system default Quicklisp, not the project-local one.
To prevent the mess, wrap all code which would load other libraries in run-time with qlot:with-local-quicklisp
.
(qlot:with-local-quicklisp :myapp
(clack:clackup *app* :server :wookie))
You can update the content of quicklisp/
directory via:
(qlot:update :myapp)
It will also overwrite qlfile.lock
.
You can bundle all depending libraries by adding the project-local quicklisp/
directory to version controll repository.
(qlot:install :myapp)
$ echo quicklisp/cache >> .gitignore
$ echo quicklisp/tmp >> .gitignore
$ git add .gitignore quicklisp/
$ git commit -m 'Bundle dependencies.'
qlot:install
will install Quicklisp and libraries that declared in qlfile
project-locally. qlfile.lock
will be used with precedence if it exists.
(qlot:install :myapp)
(qlot:install #P"/path/to/myapp/")
(qlot:install #P"/path/to/myapp/my-qlfile")
qlot:update
will update the project-local quicklisp/
directory using qlfile
.
(qlot:update :myapp)
(qlot:update #P"/path/to/myapp/")
(qlot:update #P"/path/to/myapp/my-qlfile")
qlot:quickload
is similar to ql:quickload
except it uses its project-local quicklisp/
directory.
(qlot:quickload :myapp)
Eval the given form in the local quicklisp environment.
(qlot:with-local-quicklisp :myapp
(ql:quickload :drakma))
"qlfile" is a collection of Quicklisp dist declarations. Each line of that represents a dist.
<source> <project name> [arg1, arg2..]
Currently, <source>
must be one of ql
, http
, git
or github
.
ql <project name> <version>
ql <project name> :latest
ql :all <version>
ql
source will download libraries from Quicklisp official dist, but you can specify the version.
If you want to use Clack in Quicklisp dist of January 13, 2014, qlfile would be like this.
ql clack 2014-01-13
ql
source also allows :all
as <dist name>
and :latest
as the version.
ql :all 2014-01-13
ql clack :latest
http <project name> <url> [<file md5>]
http
source will download a tarball.
http yason http://netzhansa.com/yason.tar.gz
git <project name> <repos url>
git <project name> <repos url> :ref <commit ref>
git <project name> <repos url> :branch <branch name>
git <project name> <repos url> :tag <tag name>
git
source will download libraries from a public git repository.
git clack https://github.com/fukamachi/clack.git
You can also specify :ref
, :branch
or :tag
.
git clack https://github.com/fukamachi/clack.git :branch develop
git datafly https://github.com/fukamachi/datafly.git :tag v0.7.4
git cl-dbi https://github.com/fukamachi/cl-dbi.git :ref 54928984e5756e92ba298aae51de8b95a6b0cf4b
github <project name> <repos>
github <project name> <repos> :ref <commit ref>
github <project name> <repos> :branch <branch name>
github <project name> <repos> :tag <tag name>
github
source is similar to git
, but it is specifically for GitHub. As it uses GitHub API and tarballs GitHub serves, it doesn't require "git" command.
github datafly fukamachi/datafly
github datafly fukamachi/datafly :branch develop
If multiple distributions provide the same library, lower one would take priority over higher ones.
Set :quicklisp-home
of your system and (qlot:install :myapp)
.
(defsystem myapp
:defsystem-depends-on (:qlot)
:class :qlot-system
:quicklisp-home #P".ql/"
:components ((:file "src/myapp")))
- Eitaro Fukamachi ([email protected])
Copyright (c) 2014 Eitaro Fukamachi ([email protected])
Licensed under the MIT License.