Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Luarocks manager #33959

Open
19 of 51 tasks
rarkins opened this issue Jan 31, 2025 · 1 comment
Open
19 of 51 tasks

Luarocks manager #33959

rarkins opened this issue Jan 31, 2025 · 1 comment
Labels
new package manager New package manager support priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others type:feature Feature (new functionality)

Comments

@rarkins
Copy link
Collaborator

rarkins commented Jan 31, 2025

Discussed in #33945

Originally posted by kikito January 30, 2025

Tell us more.

New package manager questionnaire

Did you read our documentation on adding a package manager?

Basics

What's the name of the package manager?

Luarocks

What language(s) does this package manager support?

Lua

How popular is this package manager?

It's the most popular package manager for the Language. Number 1

Does this language have other (competing?) package managers?

  • Yes (give names).
  • No.

What are the big selling points for this package manager?

It is the only one for Lua

Detecting package files

What kind of package files, and names, does this package manager use?

The package files are called "rocks". They usually have the ".rockspec" extension and are usually named like the "package/project" that they correspond to. The filename will often also contain a version number.

Example: https://github.com/kikito/inspect.lua/blob/master/rockspecs/inspect-3.1.3-0.rockspec

They are usually in the root folder, sometimes inside a folder called "rockspecs". The folder can have more than one rockspec inside, in which case the one with the most recent version number is the most recent one. The version number is similar to semver, with one addition - the "prerelease" field is used to denote "versioning of the luarock file itself". (see
"version" in https://github.com/luarocks/luarocks/wiki/Rockspec-format)

Which fileMatch pattern(s) should Renovate use?

"fileMatch": ["(.+).rockspec$", "rockspecs/(.+).rockspec$"],

Do many users need to extend the fileMatch pattern for custom file names?

  • Yes, provide details.
  • No.

Is the fileMatch pattern going to get many "false hits" for files that have nothing to do with package management?

No, but it might hit older versions of the rockspec as well as the most recent one. Usually only the most recent one is relevant for dependency management.

Parsing and Extraction

Can package files have "local" links to each other that need to be resolved?

No

Package file parsing method

The package files should be:

  • Parsed together (in serial).
  • Parsed independently.

(Only one package file needs to be parse)

Which format/syntax does the package file use?

  • JSON
  • TOML
  • YAML
  • Custom (explain below)

The rockspec file is written in Lua itself, so you actually need a Lua parser in order to read it properly. The result of evaluating the file in Lua should put several Lua tables in the global namespace, for example rockspec_format should be a string. The full list of fields is available here: https://github.com/luarocks/luarocks/wiki/Rockspec-format

How should we parse the package files?

  • Off the shelf parser.
  • Using regex.
  • Custom-parsed line by line.
  • Other.

The ideal way to parse rockspec files is by using Lua itself, but there's many different versions of Lua (and LuaJIT) and exactly how to do it changes from version to version. Here's a lua file which should be able to convert any rockspec given to a json file, using any version of Lua/LuaJIT. From there it is possible to export it however is convenient. On the following example we are using the cjson library to encode the resulting table. If cjson isn't available, we could just print a bunch of stuff.

-- file: rockparse.lua
local cjson=require "cjson"

local env = setmetatable({}, {__index=_G})

if setfenv then -- Lua 5.1 / LuaJIT
  local chunk = assert(loadfile((...), "t")) -- Load the file
  setfenv(chunk, env)
  chunk()
else -- Lua 5.2+
  assert(loadfile((...), "t", env))()
end

print(cjson.encode(env))

Usage: lua rockparse.lua inspect-3.1.3-0.rockspec

Output:

{"package":"inspect","dependencies":["lua >= 5.1"],"version":"1.2-2","description":{"detailed":"    inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name, handles data recursion\n  ","license":"MIT <http:\/\/opensource.org\/licenses\/MIT>","homepage":"https:\/\/github.com\/kikito\/inspect.lua","summary":"Lua table visualizer, ideal for debugging"},"build":{"modules":{"inspect":"inspect.lua"},"type":"builtin"},"source":{"dir":"inspect.lua-1.2.0","url":"https:\/\/github.com\/kikito\/inspect.lua\/archive\/v1.2.0.tar.gz"}}

Does the package file have different "types" of dependencies?

  • Yes, production and development dependencies.
  • No, all dependencies are treated the same.

List all the sources/syntaxes of dependencies that can be extracted

Copy-paste from https://github.com/luarocks/luarocks/wiki/Rockspec-format#dependency-information :

  • supported_platforms (array of strings) - If this array is not present, the rock is assumed to be portable to any platform. If present, this should contain strings containing LuaRocks platform identifiers, optionally preceded by a "!" to indicate a negative match. If only negative entries are listed, the rock is assumed to be portable to any platform except those listed. If any positive entry exists, then at least one entry must match positively to the currently running platform. Currently supported LuaRocks platform identifiers are: "unix", "windows", "win32", "cygwin", "macosx", "linux", "freebsd". Platforms may have more than one valid identifier; e.g. Linux defines both "unix" and "linux". Note that, as of 0.6, Cygwin under Windows defines {"unix", "cygwin"} but not "windows".
  • dependencies (array of strings) - Each string represents a package this rock depends on, containing a package name followed by a comma-separated list of constraints. Example: {"lfs >= 1.0, &lt; 2.0"}. Accepted operators are the relational operators of Lua: == ~= < > <= >= , as well as a special operator, ~>, inspired by the "pessimistic operator" of RubyGems ("~> 2" means ">= 2, < 3"; "~> 2.4" means ">= 2.4, < 2.5"). The absence of an operator means an implicit == (i.e., "lfs 1.0" is the same as "lfs == 1.0"). "lua" is an special dependency name; it matches not a rock, but the version of Lua in use. Supports per-platform overrides.
  • build_dependencies (array of strings) (since 3.0) - Dependencies that apply at build-time only, but not when installing binary (.<platform>.rock) or pure-Lua (.all.rock) rocks. Each string represents a package this rock depends on at build time, containing a package name followed by a comma-separated list of constraints. The syntax in the same as the dependencies field. Supports per-platform overrides.
  • external_dependencies (table) - For each key in the external_dependencies table in the rockspec file, four variables available to the build rules are created: key_DIR, key_BINDIR, key_INCDIR and key_LIBDIR. These are not overwritten if already set (e.g. by the LuaRocks config file or through the command-line). The base prefix for these can be given explicitly setting key_DIR in the config file or through the command-line, or implicitly, defaulting to the value of default_external_deps_dir, set in the config file. Values in the external_dependencies table are tables that may contain a "header" or a "library" field, with filenames to be tested for existence. Example: { EXPAT = { header = "expat.h" } } -- on Unix, this will check that EXPAT_DIR/include/expat.h exists and will create variables accordingly. You can also use platform overrides or specify files of external dependencies in a platform-agnostic manner. Supports per-platform overrides.
  • test_dependencies (array of strings) (since 3.0) - Dependencies that apply at test-time only, that is, only needed when running luarocks test. Each string represents a package this rock depends on at test time, containing a package name followed by a comma-separated list of constraints. The syntax in the same as the dependencies field. Supports per-platform overrides.

Describe which types of dependencies above are supported and which will be implemented in future

I don't understand the question. I have not implemented anything.

Versioning

What versioning scheme does the package file(s) use?

The version number can be assumed to be Semver. As mentioned above, luarocks itself uses an extra number for the rare case where a luarock was uploaded but it was incorrect and needed modifications.

Does this versioning scheme support range constraints, like ^1.0.0 or 1.x?

  • Supports range constraints (for example: ^1.0.0 or 1.x), provide details.
  • No.

Accepted operators are the relational operators of Lua: == ~= < > <= >= , as well as a special operator, ~>, inspired by the "pessimistic operator" of RubyGems ("~> 2" means ">= 2, < 3"; "~> 2.4" means ">= 2.4, < 2.5"). The absence of an operator means an implicit == (i.e., "lfs 1.0" is the same as "lfs == 1.0"). "lua" is an special dependency name; it matches not a rock, but the version of Lua in use.

Lookup

Is a new datasource required?

  • Yes, provide details.
  • No.

The datasource would be the luarocks server/API: https://luarocks.org/

Will users want (or need to) set a custom host or custom registry for Renovate's lookup?

  • [] Yes, provide details.
  • No.

Unsure of what "custom host or custom registry" means. It is possible to configure private luarocks repos, which should be compatible with luarocks.org's API.

Where can Renovate find the custom host/registry?

  • No custom host or registry is needed.
  • In the package file(s), provide details.
  • In some other file inside the repository, provide details.
  • User needs to configure Renovate where to find the information, provide details.

Are there any constraints in the package files that Renovate should use in the lookup procedure?

  • Yes, there are constraints on the parent language (for example: supports only Python v3.x), provide details.
  • Yes, there are constraints on the parent platform (for example: only supports Linux, Windows, etc.), provide details.
  • Yes, some other kind of constraint, provide details.
  • No constraints.

When multiple package files are found, the one with the most recent version should be used.

Will users need the ability to configure language or other constraints using Renovate config?

  • Yes, provide details.
  • No.

Artifacts

Does the package manager use a lock file or checksum file?

  • Yes, uses lock file.
  • Yes, uses checksum file.
  • Yes, uses lock file and checksum file.
  • No lock file or checksum.

Is the locksum or checksum mandatory?

  • Yes, locksum is mandatory.
  • Yes, checksum is mandatory.
  • Yes, lock file and checksum are mandatory.
  • No mandatory locksum or checksum.
  • Package manager does not use locksums or checksums.

If lockfiles or checksums are used: what tool and exact commands should Renovate use to update one (or more) package versions in a dependency file?

Package manager cache

Does the package manager use a cache?

  • Yes, provide details.
  • No.

If the package manager uses a cache, how can Renovate control the cache?

  • Package manager does not use a cache.
  • Controlled via command line interface, provide details.
  • Controlled via environment variables, provide details.

Should Renovate keep a cache?

  • Yes, ignore/disable the cache.
  • No.

Generating a lockfile from scratch

Renovate can perform "lock file maintenance" by getting the package manager to generate a lockfile from scratch.
Can the package manager generate a lockfile from scratch?

  • Yes, explain which command Renovate should use to generate the lockfile.
  • No, the package manager does not generate a lockfile from scratch.
  • No, the package manager does not use lockfiles.

Other

What else should we know about this package manager?

Main websites/reference:

@rarkins rarkins added new package manager New package manager support priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others type:feature Feature (new functionality) labels Jan 31, 2025
@renovatebot renovatebot deleted a comment from github-actions bot Jan 31, 2025
@kikito
Copy link

kikito commented Jan 31, 2025

Hello, I am afraid I can't edit this issue since I am not the original author. I am the original author of the discussion that originated this issue.

I would like to make an amend: Luarocks does in fact support lockfiles. It's just that I had never used the feature before.

Given a rockspec like kong's: https://github.com/Kong/kong/blob/master/kong-3.10.0-0.rockspec

Executing luarocks make --pin will produce the following lockfile:

Lockfile
return {
   dependencies = {
      ansicolors = "1.0.2-3",
      binaryheap = "0.4-1",
      date = "2.2.1-1",
      etlua = "1.3.0-1",
      inspect = "3.1.3-0",
      ["kong-lapis"] = "1.16.0.1-1",
      ["kong-pgmoon"] = "1.16.2-1",
      loadkit = "1.1.0-1",
      lpeg = "1.1.0-2",
      ["lua-ffi-zlib"] = "0.6-0",
      ["lua-messagepack"] = "0.5.4-1",
      ["lua-protobuf"] = "0.5.2-1",
      ["lua-resty-acme"] = "0.15.0-1",
      ["lua-resty-ada"] = "1.1.0-1",
      ["lua-resty-aws"] = "1.5.4-1",
      ["lua-resty-counter"] = "0.2.1-1",
      ["lua-resty-gcp"] = "0.0.13-1",
      ["lua-resty-healthcheck"] = "3.1.0-1",
      ["lua-resty-http"] = "0.17.2-0",
      ["lua-resty-ipmatcher"] = "0.6.1-0",
      ["lua-resty-jit-uuid"] = "0.0.7-2",
      ["lua-resty-jwt"] = "0.2.3-0",
      ["lua-resty-ljsonschema"] = "1.2.0-2",
      ["lua-resty-luasocket"] = "1.1.2-1",
      ["lua-resty-openssl"] = "1.5.1-1",
      ["lua-resty-session"] = "4.0.5-1",
      ["lua-resty-snappy"] = "1.0-1",
      ["lua-resty-timer"] = "1.1.0-1",
      ["lua-resty-timer-ng"] = "0.2.7-1",
      lua_pack = "2.0.0-0",
      lua_system_constants = "0.1.4-0",
      luaexpat = "1.5.2-1",
      luafilesystem = "1.8.0-1",
      lualogging = "1.8.2-1",
      luasec = "1.3.2-1",
      luasocket = "3.0rc1-2",
      luasyslog = "2.0.1-1",
      luatz = "0.4-1",
      luaxxhash = "1.0.0-1",
      lyaml = "6.2.8-1",
      multipart = "0.5.9-1",
      ["net-url"] = "1.2-1",
      penlight = "1.14.0-2",
      version = "1.0.1-2"
   },
}

Similarly to rockspecs, it's in Lua format and intended to be parsed by Lua itself. This particular one could be parsed and transformed to json with this program. Given that the results are returned instead of written in the global environment, it is compatible with all versions of Lua:

-- file: lockparse.lua
local cjson=require "cjson"

local lock=assert(loadfile((...), "t"))()

print(cjson.encode(lock))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new package manager New package manager support priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others type:feature Feature (new functionality)
Projects
None yet
Development

No branches or pull requests

2 participants