Lua! It compiles fast and starts fast
luarocks is the package manager for lua.
By default lua tries to write to the system directory at /usr/local
,
however this would require sudo.
Fortunately, you can install to ~/.luarocks
with --local
:
$ luarocks install --local cmark
You can see the result of the install like so:
$ luarocks show cmark
cmark 0.31.1-1 - Lua wrapper for libcmark, CommonMark Markdown parsing
...
Modules:
cmark (/Users/razzi/.luarocks/lib/lua/5.4/cmark.so)
cmark.builder (/Users/razzi/.luarocks/share/lua/5.4/cmark/builder.lua)
However if you try to require it you’ll get an error:
$ lua
Lua 5.4.7 Copyright (C) 1994-2024 Lua.org, PUC-Rio
> require 'cmark'
stdin:1: module 'cmark' not found:
no field package.preload['cmark']
no file '/usr/local/share/lua/5.4/cmark.lua'
...
The problem is that it hasn’t added ~/.luarocks
to your lua require path.
Fortunately luarocks knows the commands it needs to add its installs to your lua require path:
$ luarocks path
export LUA_PATH='/usr/local/Cellar/luarocks/3.11.1/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua;/usr/local/lib/lua/5.4/?.lua;/usr/local/lib/lua/5.4/?/init.lua;./?.lua;./?/init.lua;/Users/razzi/.local/lib/lua/share/lua/5.4/?.lua;/Users/razzi/.luarocks/lib/lua/5.4/?.lua;/Users/razzi/.luarocks/lib/luarocks/5.4/?.lua;/Users/razzi/.luarocks/lib/luarocks/rocks-5.4/?.lua;/Users/razzi/.luarocks/share/lua/5.4/?.lua;/Users/razzi/.luarocks/share/lua/5.4/?/init.lua'
export LUA_CPATH='/usr/local/lib/lua/5.4/?.so;/usr/local/lib/lua/5.4/loadall.so;./?.so;/Users/razzi/.luarocks/lib/lua/5.4/?.so'
export PATH='/Users/razzi/.local/bin:/Users/razzi/.luarocks/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'
You could evaluate this directly like so:
$ eval $(luarocks path)
However I prefer to avoid eval in such contexts, so I take the output of luarocks path
and add it to my ~/.profile
myself.
$ export LUA_CPATH="$HOME/.luarocks/lib/lua/5.4/?.so"
Now I can require my module!
$ lua
Lua 5.4.7 Copyright (C) 1994-2024 Lua.org, PUC-Rio
> cmark = require 'cmark'
table: 0x7fb04d704240 /Users/razzi/.luarocks/lib/lua/5.4/cmark.so
The above works fine when just hacking around.
When it’s time to build out an application, there are 2 helpful practices:
The way lua declares its dependencies is using a rockspec
file. Here’s an example:
razzi-dev-1.rockspec
rockspec_format = "3.0"
package = "razzi"
version = "dev-1"
source = {
url = ""
}
dependencies = {
"cmark == 0.31.1",
}
And the way to install dependencies in a local folder is as follows:
$ luarocks make --tree lua_modules --deps-only
You must also add the local path to your PATH:
$ luarocks path --tree lua_modules
export LUA_PATH='/Users/razzi/hack/vendor/share/lua/5.4/?.lua;...
As above, you can either eval
this or add it to a .env
file or similar:
$ luarocks path --tree lua_modules/ > .env
$ source .env
$ lua
Lua 5.4.7 Copyright (C) 1994-2024 Lua.org, PUC-Rio
> require 'cmark'
table: 0x7f872e004290 /Users/razzi/hack/lua_modules/lib/lua/5.4/cmark.so
This approach is taken a slightly different direction here: https://leafo.net/guides/customizing-the-luarocks-tree.html
The main benefit being that it is all tracked in code, versus my approach,
which would end up adding the lua_modules
and .env
to .gitignore
, which would
then require an explanation how to set things up in the README or other doc.
The leafo approach also requires a bit of extra command setup, but that could be put in a Makefile.
The .env
approach can also be automated with shell integration.