Addon author's guide
NOTE: At this moment the addon system described in this page is not yet merged. It can be found in the "addon-prototype" branch of xiaq's clone (https://github.com/xiaq/luarocks/tree/addon-prototype). There are also some rough edges and planned features; they are noted below.
Addons are used to introduce new, optional behavior to LuaRocks. They may introduce a new command and introduce new rockspec fields, and hook into various execution points of LuaRocks.
TODO: New flags for existing commands is a planned feature.
An addon named $a
is the Lua module luarocks.addon.$a
. There are two entry points to the addon, run
and load
, which correspond to two ways of activating the addon, either by calling the eponymous subcommand of LuaRocks, or using the addon through a rockspec.
-
When an addon is installed, an eponymous subcommand of LuaRocks is automatically enabled; e.g. with
luarocks.addon.test
installed, the user may useluarocks test ...
. When this subcommand is called, therun
function of the addon is called with the command line arguments.NOTE: Some global options are processed before calling
run
and do not appear in its parameter list. The exact behavior should be documented later; the curious may consult relevant code incommand_line.run_command
. -
The
load
function is called when the name of the addon appears in theaddons
field of the rockspec.
Two new fields are now available in the rockspec, build_dependencies
and addons
. The former follows exactly the same format as dependencies
, except that they are satisfied at build-time and not required to install the built binary rocks. The latter is a list of addon names; named addons are loaded during the loading of the rockspec. To use an addon, its name should appear in addons
and the name of the rock should appear in build_dependencies
. For instance, to use an addon test
provided by a rock luarocks-addon-test
, the following is needed:
build_dependencies = {"luarocks-addon-test"}
addons = {"test"}
NOTE: This will change before the release. One problem is the duplication in the example above. Another more important problem is that addons are not really "build-time dependencies" but "load-time dependencies" (now build-time dependencies are treated like load-time dependencies).
The addon should then make use of the luarocks.api
module to alter the behavior of LuaRocks. The most essential functions exposed through the module are:
-
api.register_rockspec_field(name, typetbl, callback)
: register a new rockspec field. The first parameter,name
, can be a dot-separated string to refer to subfields of existing fields. The parametertypetbl
is a table that stipulates the type of the new field; it is documented in the comment intype_check.lua
. The parametercallback
is called after the parsing of the rockspec is finished and is supplied the value of the registered field and the whole rockspec; it is not called if any part of the rockspec fails type-checking.For instance, the following code registers a new subfield
foo
in thebuild
field, which is required to be a string, and prints the package name and value of the new field:api.register_rockspec_field( "build.foo", {_type="string"}, function(foo, rockspec) print("package="..rockspec.package..", foo="..foo) end )
The new field must not collide with existing ones - neither builtin fields like
package
orbuild
, nor those registered by other addons. In case of registering a new subfield, all but the last one component must exist; registeringa.b.c.d
requires thata
,a.b
,a.b.c
exist, buta.b.c.d
should not. -
api.register_hook(point, callback)
: register a new hook callback. The parameterpoint
specifies the point at which the callback is to be called; the current possible values forname
arebuild.before
andbefore.after
. Both are triggered during the building procedure. The former is triggered just after all dependencies of the rock has been satisfied and the source has been fetched. The latter is triggered just the rock has been built and installed.The callbacks are given the current rockspec as their sole parameters.
TODO: The names and semantics of
build.before
andbuild.after
might change before the release. More hook points should be introduced.
TODO: When callbacks are supplied the "rockspec", they are not supplied the original rockspec, but a intermediate version where some fields have been "parsed". Notably, the values in dependencies
and build_dependencies
fields are not strings but an internal representation. This will be fixed before the release.
There are other API functions exposed through this module. For instance api.load_rockspec
is likely useful in the run
function of an addon. For now, the reader has to consult the source of api.lua
and relevant functions in other files.
You should not require
other luarocks.*
modules, since the internal APIs are not guaranteed to be backward-compatible; doing so will end up with an error. (It is possible to circumvent this limitation, but then you are at your own risk.)
Two sample addons have been developed, luarocks-addon-moonc and luarocks-addon-test. Both addons work with the builtin
build backend and look into the build.modules
field:
-
The moonc addon checks the existence of the files named in
build.modules
. If a.lua
file does not exist, but a corresponding.moon
files does, it compiles the latter to the former. For instance, with the following in the rockspec:build = { type = 'builtin', modules = { ["foo"] = "src/foo.lua", }, }
If `src/foo.lua` does not exist but `src/foo.moon` does, the latter is compiled to the former. This compilation process is triggered either *before* building by having `moonc` in `addons` of the rockspec, or by calling `luarocks moonc [rockspec]` manually.
- The test addon tries to find test files for files in
build.modules
. For instance, with the rockspec above, it will try to findsrc/foo_test.lua
and run it. This testing process is triggered either after building by havingtest
inaddons
of the rockspec, or by callingluarocks test [rockspec]
manually.
There is also a dinner module that uses the above two addons. All these modules are also available in xiaq's modules registry. (Weirdly they do appear on the root registry of luarocks.org.)
TODO: The design of the test addon is a bit confusing. If the tests are run after building, they may assume that the rock is installed and can be require
d. If the tests are run manually, they may not assume so.