Warning: This software is still BETA 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
$ cd /path/to/myapp # Installing libraries project-locally. $ qlot install # Updating depending libraries of a project. $ qlot update # Updating specific libraries $ qlot update --project mito # Execute a command with a project-local Quicklisp $ qlot exec ros -S . run $ qlot exec clackup app.lisp
What Qlot is trying to solve
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.
It also can be installed with Roswell.
$ ros install qlot # Install the latest version from GitHub $ ros install fukamachi/qlot
It's almost the same as using Quicklisp, except it also introduces a shell command "qlot".
$ which qlot /Users/nitro_idiot/.roswell/bin/qlot $ qlot Usage: qlot COMMAND [ARGS..] COMMANDS: install Installs libraries to './quicklisp'. update Makes './quicklisp' up-to-date and update 'qlfile.lock'. Possible to update specific projects with --project option. ex) qlot update --project mito bundle Dumps all libraries to './bundle-libs' to allow to load them without Qlot and Quicklisp. run Starts REPL with the project local Quicklisp dists (Same as 'qlot exec ros run'). exec [shell-args..] Invokes the following shell-command with the project local Quicklisp.
Put a file "qlfile" at the root of your project directory.
See qlfile syntax section to know how to write it.
Installation of libraries
You can install libraries into the project directory via:
$ qlot install
quicklisp/ directory in the project directory and a file
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.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.'
Updating the project-local quicklisp
You can update the content of
quicklisp/ directory via:
$ qlot update
It will also overwrite
You can bundle all depending libraries into
$ qlot bundle
$ git add bundle-libs/ $ git commit -m 'Bundle dependencies.'
qlot install will install Quicklisp and libraries that declared in
qlfile.lock will be used with precedence if it exists.
$ qlot install $ qlot install /path/to/myapp/qlfile
qlot update will update the project-local
quicklisp/ directory using
$ qlot update
qlot bundle will bundle dependencies into
bundle-libs/ by using
$ qlot bundle
qlot exec does following:
CL_SOURCE_REGISTRYenvironment variable by adding a current directory;
- adds Roswell's
bindirectory to the
- executes given command with arguments.
Here are few usefull commands:
qlot exec ros emacs- starts Emacs for development. Inferior lisp will use only systems, installed by
qlot install. If you want to use systems from directories other than current and
./quicklisp/, then set
CL_SOURCE_REGISTRYvariable before starting
qlot. This can be useful in case, if you have development versions of some systems, for example, in
~/common-lisp/directory and want to use them during project development:
CL_SOURCE_REGISTRY=~/common-lisp// qlot exec ros emacs
Read more about
CL_SOURCE_REGISTRYin asdf's documentation.
qlot exec ros build some-app.ros- another command, useful, to build a binary from systems, fixed in
qlfile.lock. This way you can be sure that your builds are stable.
"qlfile" is a collection of Quicklisp dist declarations. Each line of that represents a dist.
<source> <project name> [arg1, arg2..]
<source> must be one of
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
<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
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
Retrieving from private repository
Qlot doesn't authenticate itself, but retrieving from private repository can be done via git's SSH key authentication. Which means, if the current user can
git clone, Qlot also would be possible to do it.
git myapp firstname.lastname@example.org:somewrite-adtech/myapp
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
Priorities of distributions
If multiple distributions provide the same library, lower one would take priority over higher ones.
Working with SLIME
SLIME is the most popular development environment in Common Lisp. However, its REPL always loads the global Quicklisp, not the project-local one.
Here's quick steps to start project-local REPL with SLIME:
- Add the following function to
(defun slime-qlot-exec (directory) (interactive (list (read-directory-name "Project directory: "))) (slime-start :program "qlot" :program-args '("exec" "ros" "-S" "." "run") :directory directory :name 'qlot :env (list (concat "PATH=" (mapconcat 'identity exec-path ":")))))
- Relaunch the Emacs.
M-x slime-qlot-exec RET /path/to/project/.
Working with local git repositories
PROJECT_ROOT/quicklisp/local-projects can be used for local git repositories. Symbolic links are also be accessible in Qlot environment.
- Eitaro Fukamachi (email@example.com)
Copyright (c) 2014 Eitaro Fukamachi (firstname.lastname@example.org)
Licensed under the MIT License.