local fs = require "luacheck.fs" local utils = require "luacheck.utils" local blacklist = utils.array_to_set({"spec", ".luarocks", "lua_modules", "test.lua", "tests.lua"}) -- This reimplements relevant parts of `luarocks.build.builtin.autodetect_modules`. -- Autodetection works relatively to the directory containing the rockspec. local function autodetect_modules(rockspec_path) rockspec_path = fs.normalize(rockspec_path) local base, rest = fs.split_base(rockspec_path) local project_dir = base .. (rest:match("^(.*)" .. utils.dir_sep .. ".*$") or "") if project_dir == "" then project_dir = "." end local module_dir = project_dir for _, module_subdir in ipairs({"src", "lua", "lib"}) do local full_module_dir = fs.join(project_dir, module_subdir) if fs.is_dir(full_module_dir) then module_dir = full_module_dir break end end local res = {} for _, file in ipairs((fs.extract_files(module_dir, "%.lua$"))) do -- Extract first part of the path from module_dir to the file, or file name itself. if not blacklist[file:match("^" .. module_dir:gsub("%p", "%%%0") .. "[\\/]*([^\\/]*)")] then table.insert(res, file) end end local bin_dir for _, bin_subdir in ipairs({"src/bin", "bin"}) do local full_bin_dir = fs.join(project_dir, bin_subdir) if fs.is_dir(full_bin_dir) then bin_dir = full_bin_dir end end if bin_dir then local iter, state, var = fs.dir_iter(bin_dir) if iter then for basename in iter, state, var do if basename:sub(-#".lua") == ".lua" then table.insert(res, fs.join(bin_dir, basename)) end end end end return res end local function extract_lua_files(rockspec_path, rockspec) local build = rockspec.build if type(build) ~= "table" then return autodetect_modules(rockspec_path) end if not build.type or build.type == "builtin" or build.type == "module" then if not build.modules then return autodetect_modules(rockspec_path) end end local res = {} local function scan(t) if type(t) == "table" then for _, file in pairs(t) do if type(file) == "string" and file:sub(-#".lua") == ".lua" then table.insert(res, file) end end end end scan(build.modules) if type(build.install) == "table" then scan(build.install.lua) scan(build.install.bin) end table.sort(res) return res end -- Receives a name of a rockspec, returns list of related .lua files. -- On error returns nil and "I/O", "syntax", or "runtime" and error message. local function expand_rockspec(rockspec_path) local rockspec, err_type, err_msg = utils.load_config(rockspec_path) if not rockspec then return nil, err_type, err_msg end return extract_lua_files(rockspec_path, rockspec) end return expand_rockspec