Rockamalg amalgamates several Lua files with all their dependencies into a single Lua file.
It uses LuaRocks to install dependencies and amalg.lua to amalgamate.
Enapter Blueprints uses a single Lua file. But it can be complex to manage, and developers may want to split them into several modules or use existing modules. So we need a tool to combine multiple Lua modules into a single file.
Enapter has an official tutorial about Rockamalg usage.
You can describe dependencies in rockspec format like this:
lua-string ~> 1.2
inspect ~> 3.1.2
beemovie
Note, that Lua version should not be specified and commas and quotes are omitted.
Save this into file (e.g. deps
) and you can amalgamate your ucm.lua
with all dependencies via command:
docker run --rm -it \
-v $(pwd):/app \
enapter/rockamalg \
amalg -o out.lua -d deps ucm.lua
Or your can use rockspec if you have. It is used only for dependencies resolving. The minimal spec file looks like:
rockspec_format = '3.0'
package = 'generated'
version = 'dev-1'
source = {
url = 'generated'
}
dependencies = {
'lua ~> 5.3',
'lua-string ~> 1.2',
'inspect ~> 3.1.2',
'beemovie'
}
This file should have a specific name generated-dev-1.rockspec
. The parts of name should be the same as described inside specfile: <package>-<version>.rockspec
.
After that you can amalgamate your ucm.lua
with all dependencies via command:
docker run --rm -it \
-v $(pwd):/app \
enapter/rockamalg \
amalg -o out.lua -r my.rockspec ucm.lua
You can split ucm.lua
into multiple files and use Lua modules as usual. The only one requirement is that entrypoint should have name main.lua
.
E.g. your scrpt is placed in lua_dir
. So you can amalgamate your ucm.lua
by the following command:
docker run --rm -it \
-v $(pwd):/app \
enapter/rockamalg \
amalg -o ucm.lua -d deps lua_dir
It's possible to run rockamalg in server mode. This mode is useful to integrate with another services, which works in separate Docker containers.
🚧 At now caching is not recommended to use. Run server with --disable-cache
flag to completly disable it. The problem is caching is prevent for use new version. E.g. you have dependency inspect >= 3.1
and amalgamate your script with 3.1 version. But if a new version of inspect will be released, the rockamalg will use cached 3.1 version to satisfy dependency.
Downloading dependencies for each amalgamation could take a lot of time. By default rockamalg uses dependency cache to speedup the amalgamation.
You need to mount a volume into /opt/rockamalg/.cache
to reuse cache between runs.
Single run:
docker run --rm -it \
-v $(pwd):/app \
-v rockamalg-cache:/opt/rockamalg/.cache \
enapter/rockamalg \
amalg -o ucm.lua -d deps lua_dir
Server mode:
docker run --rm -d -e LISTEN_ADDRESS=0.0.0.0:9090 -e RETRY_TIMEOUT=1s \
-p 9090:9090 \
enapter/rockamalg \
server
Sometimes running result file can cause an error like:
lua: main.lua:5: module 'mymode' not found:
no field package.preload['mymode']
no file '/opt/homebrew/share/lua/5.3/mymode.lua'
no file '/opt/homebrew/share/lua/5.3/mymode/init.lua'
no file '/opt/homebrew/lib/lua/5.3/mymode.lua'
no file '/opt/homebrew/lib/lua/5.3/mymode/init.lua'
no file './mymode.lua'
no file './mymode/init.lua'
no file '/opt/homebrew/lib/lua/5.3/mymode.so'
no file '/opt/homebrew/lib/lua/5.3/loadall.so'
no file './mymode.so'
stack traceback:
[C]: in function 'require'
main.lua:5: in main chunk
ucm.lua:11: in main chunk
[C]: in ?
It means, that rockamalg failed to detect all required Lua modules. In that case run rockamalg in isolate mode using -i
flag:
docker run --rm -it \
-v $(pwd):/app \
enapter/rockamalg \
amalg -i -o ucm.lua -d deps lua_dir
To generate GRPC API use the following command:
./scripts/gogen.sh go generate -v ./internal/api/rockamalgrpc/generate.go
To pack rocks for integration tests use the pack_rocks.sh
script:
docker run --rm \
-v $(pwd)/tests/integration/testdata/rocks:/opt/res \
--entrypoint /opt/tools/pack_rocks.sh \
enapter/rockamalg \
inspect@3.1.2