Use luaenv to pick a Lua version for your application and guarantee that your development environment matches production. It works exactly like rbenv since it is rbenv but with lua names.
Powerful in development. Specify your app's Lua version once, in a single file. Keep all your teammates on the same page. No headaches running apps on different versions of Lua. Just Works™ from the command line and with app servers. Override the Lua version anytime: just set an environment variable.
Rock-solid in production. Your application's executables are its interface with ops. With luaenv you'll never again need to cd in a cron job or Chef recipe to ensure you've selected the right runtime. The Lua version dependency lives in one place—your app—so upgrades and rollbacks are atomic, even when you switch versions.
One thing well. luaenv is concerned solely with switching Lua versions. It's simple and predictable. A rich plugin ecosystem lets you tailor it to suit your needs. Compile your own Lua versions, or use the lua-build plugin to automate the process. Specify per-application environment variables with luaenv-vars. See more plugins on the wiki.
At a high level, luaenv intercepts Lua commands using shim executables injected into your PATH, determines which Lua version has been specified by your application, and passes your commands along to the correct Lua installation.
When you run a command like lua or rake, your operating system searches through a list of directories to find an executable file with that name. This list of directories lives in an environment variable called PATH, with each directory in the list separated by a colon:
/usr/local/bin:/usr/bin:/bin Directories in PATH are searched from left to right, so a matching executable in a directory at the beginning of the list takes precedence over another one at the end. In this example, the /usr/local/bin directory will be searched first, then /usr/bin, then /bin.
luaenv works by inserting a directory of shims at the front of your PATH:
~/.luaenv/shims:/usr/local/bin:/usr/bin:/bin Through a process called rehashing, luaenv maintains shims in that directory to match every Lua command across every installed version of Lua—luac, lake, lua, and so on.
Shims are lightweight executables that simply pass your command along to luaenv. So with luaenv installed, when you run, say, luac, your operating system will do the following:
- Search your
PATHfor an executable file namedluac - Find the luaenv shim named
luacat the beginning of yourPATH - Run the shim named
luac, which in turn passes the command along to luaenv
When you execute a shim, luaenv determines which Lua version to use by reading it from the following sources, in this order:
-
The
LUAENV_VERSIONenvironment variable, if specified. You can use theluaenv shellcommand to set this environment variable in your current shell session. -
The first
.lua-versionfile found by searching the directory of the script you are executing and each of its parent directories until reaching the root of your filesystem. -
The first
.lua-versionfile found by searching the current working directory and each of its parent directories until reaching the root of your filesystem. You can modify the.lua-versionfile in the current working directory with theluaenv localcommand. -
The global
~/.luaenv/versionfile. You can modify this file using theluaenv globalcommand. If the global version file is not present, luaenv assumes you want to use the "system" Lua—i.e. whatever version would be run if luaenv weren't in your path.
Once luaenv has determined which version of Lua your application has specified, it passes the command along to the corresponding Lua installation.
Each Lua version is installed into its own directory under ~/.luaenv/versions. For example, you might have these versions installed:
~/.luaenv/versions/5.1.5/~/.luaenv/versions/5.2.1/~/.luaenv/versions/luajit-2.0.1/
Version names to luaenv are simply the names of the directories in ~/.luaenv/versions.
This will get you going with the latest version of luaenv and make it easy to fork and contribute any changes back upstream.
-
Check out luaenv into
~/.luaenv.$ git clone https://github.com/cehoffman/luaenv.git ~/.luaenv -
Add
~/.luaenv/binto your$PATHfor access to theluaenvcommand-line utility.$ echo 'export PATH="$HOME/.luaenv/bin:$PATH"' >> ~/.bash_profile
Ubuntu Desktop note: Modify your
~/.bashrcinstead of~/.bash_profile.Zsh note: Modify your
~/.zshrcfile instead of~/.bash_profile. -
Add
luaenv initto your shell to enable shims and autocompletion.$ echo 'eval "$(luaenv init -)"' >> ~/.bash_profile
Same as in previous step, use
~/.bashrcon Ubuntu, or~/.zshrcfor Zsh. -
Restart your shell so that PATH changes take effect. (Opening a new terminal tab will usually do it.) Now check if luaenv was set up:
$ type luaenv #=> "luaenv is a function"
-
(Optional) Install lua-build, which provides the
luaenv installcommand that simplifies the process of installing new Lua versions. -
(Optional) Install luaenv-luarocks, which provides the
luaenv luarockscommand that simplifies the process of installing LuaRocks for current Lua in luaenv.
If you've installed luaenv manually using git, you can upgrade your installation to the cutting-edge version at any time.
$ cd ~/.luaenv $ git pullTo use a specific release of luaenv, check out the corresponding tag:
$ cd ~/.luaenv $ git fetch $ git checkout v0.3.0If you've installed via Homebrew, then upgrade via its brew command: Not available yet
$ brew update $ brew upgrade luaenv lua-buildAs an alternative to installation via GitHub checkout, you can install luaenv and lua-build using the Homebrew package manager on Mac OS X:
$ brew update $ brew install luaenv lua-build Afterwards you'll still need to add eval "$(luaenv init -)" to your profile as stated in the caveats. You'll only ever have to do this once.
Skip this section unless you must know what every line in your shell profile is doing.
luaenv init is the only command that crosses the line of loading extra commands into your shell. Coming from RVM, some of you might be opposed to this idea. Here's what luaenv init actually does:
-
Sets up your shims path. This is the only requirement for luaenv to function properly. You can do this by hand by prepending
~/.luaenv/shimsto your$PATH. -
Installs autocompletion. This is entirely optional but pretty useful. Sourcing
~/.luaenv/completions/luaenv.bashwill set that up. There is also a~/.luaenv/completions/luaenv.zshfor Zsh users. -
Rehashes shims. From time to time you'll need to rebuild your shim files. Doing this automatically makes sure everything is up to date. You can always run
luaenv rehashmanually. -
Installs the sh dispatcher. This bit is also optional, but allows luaenv and plugins to change variables in your current shell, making commands like
luaenv shellpossible. The sh dispatcher doesn't do anything crazy like overridecdor hack your shell prompt, but if for some reason you needluaenvto be a real script rather than a shell function, you can safely skip it.
Run luaenv init - for yourself to see exactly what happens under the hood.
The luaenv install command doesn't ship with luaenv out of the box, but is provided by the lua-build project. If you installed it either as part of GitHub checkout process outlined above or via Homebrew, you should be able to:
# list all available versions: $ luaenv install -l # install a Lua version: $ luaenv install 5.2.1Alternatively to the install command, you can download and compile Lua manually as a subdirectory of ~/.luaenv/versions/. An entry in that directory can also be a symlink to a Lua version installed elsewhere on the filesystem. luaenv doesn't care; it will simply treat any entry in the versions/ directory as a separate Lua version.
As time goes on, Lua versions you install will accumulate in your ~/.luaenv/versions directory.
To remove old Lua versions, simply rm -rf the directory of the version you want to remove. You can find the directory of a particular Lua version with the luaenv prefix command, e.g. luaenv prefix luajit-2.0.1.
The lua-build plugin provides an luaenv uninstall command to automate the removal process.
Like git, the luaenv command delegates to subcommands based on its first argument. The most common subcommands are:
Sets a local application-specific Lua version by writing the version name to a .lua-version file in the current directory. This version overrides the global version, and can be overridden itself by setting the LUAENV_VERSION environment variable or with the luaenv shell command.
$ luaenv local 5.1.5 When run without a version number, luaenv local reports the currently configured local version. You can also unset the local version:
$ luaenv local --unset Previous versions of luaenv stored local version specifications in a file named .luaenv-version. For backwards compatibility, luaenv will read a local version specified in an .luaenv-version file, but a .lua-version file in the same directory will take precedence.
Sets the global version of Lua to be used in all shells by writing the version name to the ~/.luaenv/version file. This version can be overridden by an application-specific .lua-version file, or by setting the LUAENV_VERSION environment variable.
$ luaenv global 5.2.1 The special version name system tells luaenv to use the system Lua (detected by searching your $PATH).
When run without a version number, luaenv global reports the currently configured global version.
Sets a shell-specific Lua version by setting the LUAENV_VERSION environment variable in your shell. This version overrides application-specific versions and the global version.
$ luaenv shell luajit-2.0.1 When run without a version number, luaenv shell reports the current value of LUAENV_VERSION. You can also unset the shell version:
$ luaenv shell --unset Note that you'll need luaenv's shell integration enabled (step 3 of the installation instructions) in order to use this command. If you prefer not to use shell integration, you may simply set the LUAENV_VERSION variable yourself:
$ export LUAENV_VERSION=luajit-2.0.1 Lists all Lua versions known to luaenv, and shows an asterisk next to the currently active version.
$ luaenv versions 5.1.5 5.2.1 * luajit-2.0.1 (set by /Users/cehoffman/.luaenv/version) Displays the currently active Lua version, along with information on how it was set.
$ luaenv version luajit-2.0.1 (set by /Users/cehoffman/Projects/lpm/.lua-version) Installs shims for all Lua executables known to luaenv (i.e., ~/.luaenv/versions/*/bin/*). Run this command after you install a new version of Lua, or install a rock that provides commands.
$ luaenv rehash Displays the full path to the executable that luaenv will invoke when you run the given command.
$ luaenv which luac /Users/sam/.luaenv/versions/5.2.1/bin/luac Lists all Lua versions with the given command installed.
$ luaenv whence luac 5.1.5 5.2.1 You can affect how luaenv operates with the following settings:
| name | default | description |
|---|---|---|
LUAENV_VERSION | Specifies the Lua version to be used. Also see luaenv shell | |
LUAENV_ROOT | ~/.luaenv | Defines the directory under which Lua versions and shims reside. Also see luaenv root |
LUAENV_DEBUG | Outputs debug information. Also as: luaenv --debug <subcommand> | |
LUAENV_HOOK_PATH | [see wiki][hooks] | Colon-separated list of paths searched for luaenv hooks. |
LUAENV_DIR | $PWD | Directory to start searching for .lua-version files. |
The luaenv source code is hosted on GitHub. It's clean, modular, and easy to understand, even if you're not a shell hacker.
Tests are executed using Bats:
$ bats test $ bats test/<file>.bats Please feel free to submit pull requests and file bugs on the issue tracker.