https://github.com/fukamachi/qlot Skip to content Navigation Menu Toggle navigation Sign in * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + GitHub Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code Explore + All features + Documentation + GitHub Skills + Blog * Solutions By size + Enterprise + Teams + Startups By industry + Healthcare + Financial services + Manufacturing By use case + CI/CD & Automation + DevOps + DevSecOps * Resources Topics + AI + DevOps + Security + Software Development Explore + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Enterprise + Enterprise platform AI-powered developer platform Available add-ons + Advanced Security Enterprise-grade security features + GitHub Copilot Enterprise-grade AI features + Premium Support Enterprise-grade 24/7 support * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up Reseting focus You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} fukamachi / qlot Public * * Notifications You must be signed in to change notification settings * Fork 37 * Star 421 A project-local library installer for Common Lisp qlot.tech License MIT license 421 stars 37 forks Branches Tags Activity Star Notifications You must be signed in to change notification settings * Code * Issues 26 * Pull requests 4 * Actions * Security * Insights Additional navigation options * Code * Issues * Pull requests * Actions * Security * Insights fukamachi/qlot This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. master BranchesTags Go to file Code Folders and files Name Name Last commit Last commit message date Latest commit History 1,290 Commits .github .github local-init local-init quicklisp-client quicklisp-client roswell roswell scripts scripts src src tests tests .dockerignore .dockerignore .gitignore .gitignore Dockerfile Dockerfile LICENSE.txt LICENSE.txt Makefile Makefile README.markdown README.markdown qlot-tests.asd qlot-tests.asd qlot.asd qlot.asd View all files Repository files navigation * README * MIT license Qlot Build Status [6874747073] Qlot (pronounced kyu-'lat, like culotte) is a project-local library installer using Quicklisp facility. This aims to be like Bundler of Ruby or Carton of Perl. Table of Contents * Usage * What Qlot is trying to solve * Requirements * Installation + Automatic installer + via Roswell + via Quicklisp + Manual installation + Install from source + via Docker * Optional settings + ASDF configuration to prevent from loading by mistake * Tutorial * qlfile syntax * Priorities of distributions * Working with SLIME + Lem + Emacs + Vim/Neovim * Working with local git repositories Usage Shell $ cd /path/to/myapp # Initialize the project to start using Qlot. $ qlot init # Install libraries project-locally. $ qlot install # Add the upstream version of a library $ qlot add mito --upstream # Add a library from GitHub $ qlot add fukamachi/anypool # Update specific libraries $ qlot update mito # Run a REPL with a project-local Quicklisp $ qlot exec sbcl REPL (experimental) ;; Move to the project root ;; (not necessary if the REPL is invoked by 'qlot exec') (setf qlot:*project-root* #P"/path/to/project/") ;; Initialize the project to start using Qlot. (qlot:init #P"/path/to/project/") ;; Install libraries project-locally. (qlot:install) ;; Add the upstream version of a library (qlot:add :mito :upstream t) ;; Add a library from GitHub (qlot:add "fukamachi/anypool") ;; Update specific libraries (qlot:update :mito) 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. 1. They are not project-local. If you have multiple projects that use different versions of the same library, it would be a problem. 2. They are difficult to fix the version or to update them. If your project needs to work on other than your machine, for instance on other people's machines or on servers, the version of depending libraries should be the same. This is what Qlot is trying to solve. Requirements * Roswell or SBCL * OpenSSL (Unix only) + [Ubuntu/Debian] sudo apt install libssl-dev + [macOS] brew install openssl * git (for installation from git repositories) Installation Automatic installer (recommended) $ curl -L https://qlot.tech/installer | sh It also requires curl (or wget) and tar. To uninstall Qlot, run a Qlot uninstaller like: $ ~/.qlot/qlot/scripts/qlot-uninstaller.sh via Roswell If you're already using Roswell, Qlot can be installed by ros install. # Install from the Quicklisp dist $ ros install qlot # Or, install the latest version from the git repository $ ros install fukamachi/qlot # For older Roswell (Not required since v23.10.14.114 or above) $ ros -e '(ql:quickload :qlot/distify)' Roswell adds an executable script under $HOME/.roswell/bin. Make sure the directory exists in $PATH. $ which qlot /Users/fukamachi/.roswell/bin/qlot Run ros update qlot to update Qlot. via Quicklisp If Quicklisp is set up on your home directory, Qlot can be installed by ql:quickload. (ql:quickload :qlot) Use functions exported by qlot package for using Qlot. To update Qlot, run (ql:update-all-dists) in the REPL. Manual installation If you don't use both Roswell and Quicklisp for some reason, Qlot also can be installed manually. The advantage of this method is no dependencies are required other than sbcl and OpenSSL. # Getting the latest version $ curl -sL https://api.github.com/repos/fukamachi/qlot/releases/latest | jq -rM '.name' 1.3.5 $ curl https://github.com/fukamachi/qlot/releases/download/1.3.5/qlot-1.3.5.tar.gz -o qlot.tar.gz $ tar xfz qlot.tar.gz $ cd qlot $ scripts/setup.sh $ sudo scripts/install.sh Install from source $ git clone https://github.com/fukamachi/qlot $ cd qlot $ scripts/setup.sh $ sudo scripts/install.sh To update Qlot, run git pull && scripts/setup.sh. WARNING: Don't add the Qlot source directory to any ASDF loadable directories, such as ~/common-lisp or ~/quicklisp/local-projects. ASDF accidentally loads dependencies of Qlot in a REPL even in case you don't need it. (See also ASDF configuration section) via Docker Docker Pulls $ docker run --rm -it fukamachi/qlot You can build it by yourself with docker build: $ git clone https://github.com/fukamachi/qlot $ cd qlot $ docker build -t qlot . Optional settings ASDF configuration to prevent from loading by mistake ASDF loads any ASD files under a directory ~/common-lisp including its subdirectories. It is easily understandable and convenient. However, it will lead to a problematic situation which ASDF accidentally loads libraries under ".qlot/" even in case you don't need it. To avoid the situation, we recommend not to use ~/common-lisp directory, or add the following lines to your Lisp's init file such as ~/.sbclrc for SBCL. ;; .sbclrc (push ".qlot" asdf::*default-source-registry-exclusions*) (asdf:initialize-source-registry) Roswell doesn't require this setting since it ignores directories starting with a dot. Tutorial Start using Qlot $ qlot init It creates 2 files "qlfile" and "qlfile.lock", and a directory ".qlot /" at the root of your project directory. qlfile is a file clarifying the project dependencies. See qlfile syntax for the details. qlfile.lock is similar to qlfile except the library versions are clarified. 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. $ git add qlfile qlfile.lock $ git commit -m 'Start using Qlot.' Adding a new dependency $ qlot add # Add a new library from Quicklisp explicitly $ qlot add --upstream # Add an upstream version of a Quicklisp library $ qlot add # Add a new library from a GitHub repository You can also edit a qlfile file directly. See qlfile syntax section to know how to write it. Be sure to run qlot install to install new dependencies. Updating the project-local Quicklisp You can update the version of dependencies via: $ qlot update # Update a specific project $ qlot update mito $ qlot update mito sxql It will also overwrite qlfile.lock. Commands install qlot install will install Quicklisp and libraries that are declared in qlfile project-locally. qlfile.lock will be used with precedence if it exists. $ qlot install update qlot update will update the project-local .qlot/ directory using qlfile. $ qlot update # Update a specific project $ qlot update mito $ qlot update mito sxql add qlot add will add a line to qlfile and invoke qlot install internally. It replaces an existing line if a library with the same name already exists. Its arguments are same as the qlfile syntax. $ qlot add mito # ql mito $ qlot add mito --latest # ql mito :latest $ qlot add mito --upstream # ql mito :upstream $ qlot add fukamachi/datafly # github datafly fukamachi/datafly $ qlot add fukamachi/datafly --branch stable # github datafly fukamachi/datafly :branch stable $ qlot add ultralisp egao1980-cl-idna # ultralisp egao1980-cl-idna remove qlot remove will remove libraries from qlfile and invoke qlot install internally. $ qlot remove mito $ qlot remove mito datafly # can specify multiple names exec qlot exec does following: * configures ASDF's source registries; * adds Roswell's bin directory to the PATH environment variable; * executes given command with arguments. Here are few useful 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 ./.qlot/, then set CL_SOURCE_REGISTRY variable 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_REGISTRY in asdf's documentation. * qlot exec ros build some-app.ros - another command, useful, to build a binary from systems, fixed in qlfile and qlfile.lock. This way you can be sure that your builds are stable. qlfile syntax "qlfile" is a collection of Quicklisp dist declarations. Each line of that represents a dist. [arg1, arg2..] Currently, must be one of dist, ql, ultralisp, http, git or github. ql ql ql ql source will download libraries from Quicklisp official dist. If you want to use Clack in Quicklisp dist of January 13, 2014, qlfile would be like this. ql clack 2014-01-13 If :latest is specified for the version, the latest Quicklisp dist version will be used. If :upstream is specified, Qlot downloads the latest code from the upstream git repository. ultralisp ultralisp ultralisp ultralisp is same as ql except downloading from Ultralisp. http http [] http source will download a tarball. http yason http://netzhansa.com/yason.tar.gz git git git :ref git :branch git :tag 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 Retrieving from private repository Qlot doesn't authenticate itself, but retrieving from private repository can be done via git's SSH key authentication. This means, if the current user can git clone, Qlot also would be possible to do it. git myapp git@github.com:somewrite-adtech/myapp github github github :ref github :branch github :tag 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 fukamachi/datafly github fukamachi/datafly :branch develop local local Add a directory to the ASDF's source registry. local rove ~/Programs/lib/rove dist dist [] dist allows to use a custom Quicklisp dist, like Ultralisp. dist http://beta.quicklisp.org/dist/quicklisp.txt dist http://dist.ultralisp.org/ Priorities of distributions If multiple distributions provide the same library, lower ones 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 for each text editor: Lem 1. Add lem-project/micros to .qlot/local-projects. $ git clone https://github.com/lem-project/micros .qlot/local-projects/micros 2. Add the following function to ~/.lem/init.lisp. (define-command slime-qlot-exec () () (let ((command (first (lem-lisp-mode/implementation::list-roswell-with-qlot-commands)))) (when command (lem-lisp-mode:run-slime command)))) 3. Relaunch the Lem, or reload the init file with M-x lisp-load-file RET ~/.lem/init.lisp. 4. Invoke M-x slime-qlot-exec RET /path/to/project/. Emacs 1. Add one of the following functions to init.el. a) SLIME (setq slime-lisp-implementations '((sbcl ("sbcl") :coding-system utf-8-unix) (qlot ("qlot" "exec" "sbcl") :coding-system utf-8-unix))) See the SLIME manual to set up multiple Lisps. b) Sly (setq sly-lisp-implementations '((sbcl ("sbcl") :coding-system utf-8-unix) (qlot ("qlot" "exec" "sbcl") :coding-system utf-8-unix))) See the Sly manual to set up multiple Lisps. 2. Relaunch the Emacs or load the config file. 3. Invoke M-- M-x slime RET qlot RET. Vim/Neovim 1. Install vlime/vlime. 2. Add the following code to your Vim/Neovim init.vim. let g:vlime_cl_use_terminal = v:true let s:vlime_path = '/path/to/vlime' function! VlimeBuildServerCommandFor_qlot(vlime_loader, vlime_eval) return ["qlot", "exec", "ros", "run", \ "--load", s:vlime_path . "/lisp/load-vlime.lisp", \ "--eval", vlime_eval] endfunction function! VlimeQlotExec() call vlime#server#New(v:true, get(g:, "vlime_cl_use_terminal", v:false), v:null, "qlot") endfunction 3. Relaunch the Vim/Neovim. 4. Change the directory by :cd /path/to/project/ and invoke :call VlimeQlotExec(). Working with local git repositories PROJECT_ROOT/.qlot/local-projects can be used for local git repositories. Symbolic links are also accessible in Qlot environment. Author * Eitaro Fukamachi (e.arrows@gmail.com) License See LICENSE.txt. The license of bundled Quicklisp installer can be found at quicklisp/ LICENSE.txt. About A project-local library installer for Common Lisp qlot.tech Topics package-manager common-lisp Resources Readme License MIT license Activity Stars 421 stars Watchers 22 watching Forks 37 forks Report repository Releases 33 1.5.9 Latest Aug 6, 2024 + 32 releases Sponsor this project Sponsor Learn more about GitHub Sponsors Contributors 19 * @fukamachi * @svetlyak40wt * @mtstickney * @snmsts * @daewok * @EuAndreh * @egao1980 * @cmpitg * @rudolph-miller * @govm * @wnortje * @windymelt * @cxxxr * @seanfarley + 5 contributors Languages * Common Lisp 98.8% * Other 1.2% Footer (c) 2024 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact * Manage cookies * Do not share my personal information You can't perform that action at this time.