From 757539bac6ed6271d9f125a36c77dcd7366e7f50 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Thu, 9 Jan 2014 20:42:25 -0200 Subject: Performance improvements --- src/bin/luarocks | 36 ++++++++++--------- src/luarocks/build/builtin.lua | 3 +- src/luarocks/command_line.lua | 3 +- src/luarocks/deps.lua | 2 +- src/luarocks/dir.lua | 14 +++----- src/luarocks/fetch.lua | 18 ++++++---- src/luarocks/help.lua | 19 +++++----- src/luarocks/index.lua | 11 +++--- src/luarocks/manif.lua | 79 +++++++++++++++++++++++++++--------------- src/luarocks/search.lua | 7 ++-- 10 files changed, 108 insertions(+), 84 deletions(-) diff --git a/src/bin/luarocks b/src/bin/luarocks index 6ab27fa3..e9cfc349 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks @@ -5,22 +5,24 @@ local command_line = require("luarocks.command_line") program_description = "LuaRocks main command-line interface" -commands = {} -commands.help = require("luarocks.help") -commands.pack = require("luarocks.pack") -commands.unpack = require("luarocks.unpack") -commands.build = require("luarocks.build") -commands.install = require("luarocks.install") -commands.search = require("luarocks.search") -commands.list = require("luarocks.list") -commands.remove = require("luarocks.remove") -commands.make = require("luarocks.make") -commands.download = require("luarocks.download") -commands.path = require("luarocks.path") -commands.show = require("luarocks.show") -commands.new_version = require("luarocks.new_version") -commands.lint = require("luarocks.lint") -commands.write_rockspec = require("luarocks.write_rockspec") -commands.purge = require("luarocks.purge") +commands = { + help = "luarocks.help", + pack = "luarocks.pack", + unpack = "luarocks.unpack", + build = "luarocks.build", + install = "luarocks.install", + search = "luarocks.search", + list = "luarocks.list", + remove = "luarocks.remove", + make = "luarocks.make", + download = "luarocks.download", + path = "luarocks.path", + show = "luarocks.show", + new_version = "luarocks.new_version", + lint = "luarocks.lint", + write_rockspec = "luarocks.write_rockspec", + purge = "luarocks.purge", + doc = "luarocks.doc", +} command_line.run_command(...) diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua index f9ef4c44..5c58265a 100644 --- a/src/luarocks/build/builtin.lua +++ b/src/luarocks/build/builtin.lua @@ -235,8 +235,9 @@ function run(rockspec) table.insert(objects, object) end if not ok then break end - local module_name = dir.path(moddir, name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension)):gsub("//", "/") + local module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension) if moddir ~= "" then + module_name = dir.path(moddir, module_name) local ok, err = fs.make_dir(moddir) if not ok then return nil, err end end diff --git a/src/luarocks/command_line.lua b/src/luarocks/command_line.lua index e79b1442..19d04290 100644 --- a/src/luarocks/command_line.lua +++ b/src/luarocks/command_line.lua @@ -185,7 +185,8 @@ function run_command(...) -- I'm not changing this now to avoid messing with the run() -- interface, which I know some people use (even though -- I never published it as a public API...) - local xp, ok, err, exitcode = xpcall(function() return commands[command].run(unpack(args)) end, function(err) + local cmd = require(commands[command]) + local xp, ok, err, exitcode = xpcall(function() return cmd.run(unpack(args)) end, function(err) die(debug.traceback("LuaRocks "..cfg.program_version .." bug (please report at luarocks-developers@lists.sourceforge.net).\n" ..err, 2)) diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 116b4bbb..0adb5834 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -689,7 +689,7 @@ function scan_deps(results, missing, manifest, name, version, deps_mode) local deplist = dependencies_name[version] local rockspec, err if not deplist then - rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version)) + rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version), false) if err then missing[name.." "..version] = err return results, missing diff --git a/src/luarocks/dir.lua b/src/luarocks/dir.lua index e8cd746e..1f3b5c3d 100644 --- a/src/luarocks/dir.lua +++ b/src/luarocks/dir.lua @@ -35,17 +35,11 @@ end -- @return string: a string with a platform-specific representation -- of the path. function path(...) - local items = {...} - local i = 1 - while items[i] do - items[i] = items[i]:gsub("(.+)/+$", "%1") - if items[i] == "" then - table.remove(items, i) - else - i = i + 1 - end + local t = {...} + while t[1] == "" do + table.remove(t, 1) end - return (table.concat(items, "/"):gsub("(.+)/+$", "%1")) + return (table.concat(t, "/"):gsub("([^:])/+", "%1/"):gsub("^/+", "/"):gsub("/*$", "")) end --- Split protocol and path from an URL or local pathname. diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua index 53c9d748..83ab6fa9 100644 --- a/src/luarocks/fetch.lua +++ b/src/luarocks/fetch.lua @@ -137,9 +137,11 @@ end --- Back-end function that actually loads the local rockspec. -- Performs some validation and postprocessing of the rockspec contents. -- @param filename string: The local filename of the rockspec file. +-- @param quick boolean: if true, skips some steps when loading +-- rockspec. -- @return table or (nil, string): A table representing the rockspec -- or nil followed by an error message. -function load_local_rockspec(filename) +function load_local_rockspec(filename, quick) assert(type(filename) == "string") filename = fs.absolute_name(filename) local rockspec, err = persist.load_into_table(filename) @@ -147,9 +149,12 @@ function load_local_rockspec(filename) return nil, "Could not load rockspec file "..filename.." ("..err..")" end - local ok, err = type_check.type_check_rockspec(rockspec) - if not ok then - return nil, filename..": "..err + local ok, err = true, nil + if not quick then + ok, err = type_check.type_check_rockspec(rockspec) + if not ok then + return nil, filename..": "..err + end end if rockspec.rockspec_format then @@ -207,9 +212,8 @@ function load_local_rockspec(filename) else rockspec.dependencies = {} end - local ok, err = path.configure_paths(rockspec) - if err then - return nil, "Error verifying paths: "..err + if not quick then + path.configure_paths(rockspec) end return rockspec diff --git a/src/luarocks/help.lua b/src/luarocks/help.lua index 2774dc41..2136f5da 100644 --- a/src/luarocks/help.lua +++ b/src/luarocks/help.lua @@ -71,14 +71,10 @@ function run(...) can be overriden with VAR=VALUE assignments.]]) print_section("COMMANDS") local names = {} - for name, command in pairs(commands) do - table.insert(names, name) - end - table.sort(names) - for _, name in ipairs(names) do - local command = commands[name] + for name, command in util.sortedpairs(commands) do + local cmd = require(command) util.printout("", name) - util.printout("\t", command.help_summary) + util.printout("\t", cmd.help_summary) end print_section("CONFIGURATION") util.printout("\tLua version: " .. cfg.lua_version) @@ -100,15 +96,16 @@ function run(...) end else command = command:gsub("-", "_") - if commands[command] then - local arguments = commands[command].help_arguments or "" + local cmd = require(commands[command]) + if cmd then + local arguments = cmd.help_arguments or "" print_banner() print_section("NAME") - util.printout("\t"..program.." "..command.." - "..commands[command].help_summary) + util.printout("\t"..program.." "..command.." - "..cmd.help_summary) print_section("SYNOPSIS") util.printout("\t"..program.." "..command.." "..arguments) print_section("DESCRIPTION") - util.printout("",(commands[command].help:gsub("\n","\n\t"):gsub("\n\t$",""))) + util.printout("",(cmd.help:gsub("\n","\n\t"):gsub("\n\t$",""))) print_section("SEE ALSO") util.printout("","'"..program.." help' for general options and configuration.\n") else diff --git a/src/luarocks/index.lua b/src/luarocks/index.lua index e0785d9c..1ce66f70 100644 --- a/src/luarocks/index.lua +++ b/src/luarocks/index.lua @@ -139,15 +139,14 @@ function make_index(repo) output = output..version..': ' table.sort(data, function(a,b) return a.arch < b.arch end) for _, item in ipairs(data) do - local link = ''..item.arch..'' + local file if item.arch == 'rockspec' then - local rs = ("%s-%s.rockspec"):format(package, version) - if not latest_rockspec then latest_rockspec = rs end - link = link:gsub("$url", rs) + file = ("%s-%s.rockspec"):format(package, version) + if not latest_rockspec then latest_rockspec = file end else - link = link:gsub("$url", ("%s-%s.%s.rock"):format(package, version, item.arch)) + file = ("%s-%s.%s.rock"):format(package, version, item.arch) end - table.insert(versions, link) + table.insert(versions, ''..item.arch..'') end output = output .. table.concat(versions, ', ') .. '
' end diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index 238c4056..ed1780b3 100644 --- a/src/luarocks/manif.lua +++ b/src/luarocks/manif.lua @@ -231,18 +231,11 @@ end -- @param deps_mode string: Dependency mode: "one" for the current default tree, -- "all" for all trees, "order" for all trees with priority >= the current default, -- "none" for no trees. --- @param repodir string: directory of repository being scanned --- @param filter_lua string or nil: filter by Lua version --- @param cache table: temporary rockspec cache table -local function update_dependencies(manifest, deps_mode, repodir, filter_lua, cache) +local function update_dependencies(manifest, deps_mode) assert(type(manifest) == "table") assert(type(deps_mode) == "string") - cache = cache or {} - local lua_version = filter_lua and deps.parse_version(filter_lua) - for pkg, versions in pairs(manifest.repository) do - local to_remove = {} for version, repositories in pairs(versions) do local current = pkg.." "..version for _, repo in ipairs(repositories) do @@ -259,11 +252,34 @@ local function update_dependencies(manifest, deps_mode, repodir, filter_lua, cac end end end - elseif filter_lua and repo.arch == "rockspec" then + end + end + end + end +end + +--- Filter manifest table by Lua version, removing rockspecs whose Lua version +-- does not match. +-- @param manifest table: a manifest table. +-- @param lua_version string or nil: filter by Lua version +-- @param repodir string: directory of repository being scanned +-- @param cache table: temporary rockspec cache table +local function filter_by_lua_version(manifest, lua_version, repodir, cache) + assert(type(manifest) == "table") + assert(type(repodir) == "string") + assert((not cache) or type(cache) == "table") + + cache = cache or {} + lua_version = deps.parse_version(lua_version) + for pkg, versions in pairs(manifest.repository) do + local to_remove = {} + for version, repositories in pairs(versions) do + for _, repo in ipairs(repositories) do + if repo.arch == "rockspec" then local pathname = dir.path(repodir, pkg.."-"..version..".rockspec") local rockspec, err = cache[pathname] if not rockspec then - rockspec, err = fetch.load_local_rockspec(pathname) + rockspec, err = fetch.load_local_rockspec(pathname, true) end if rockspec then cache[pathname] = rockspec @@ -283,9 +299,9 @@ local function update_dependencies(manifest, deps_mode, repodir, filter_lua, cac end if next(to_remove) then for _, incompat in ipairs(to_remove) do - manifest.repository[pkg][incompat] = nil + versions[incompat] = nil end - if not next(manifest.repository[pkg]) then + if not next(versions) then manifest.repository[pkg] = nil end end @@ -296,17 +312,12 @@ end -- @param results table: The search results as returned by search.disk_search. -- @param manifest table: A manifest table (must contain repository, modules, commands tables). -- It will be altered to include the search results. --- @param deps_mode string: Dependency mode: "one" for the current default tree, --- "all" for all trees, "order" for all trees with priority >= the current default, --- "none" for no trees. --- @param repo string: directory of repository --- @param filter_lua string or nil: filter by Lua version --- @param cache table: temporary rockspec cache table +-- @param dep_handler: dependency handler function -- @return boolean or (nil, string): true in case of success, or nil followed by an error message. -local function store_results(results, manifest, deps_mode, repo, filter_lua, cache) +local function store_results(results, manifest, dep_handler) assert(type(results) == "table") assert(type(manifest) == "table") - assert(type(deps_mode) == "string") + assert((not dep_handler) or type(dep_handler) == "function") for name, versions in pairs(results) do local pkgtable = manifest.repository[name] or {} @@ -329,7 +340,9 @@ local function store_results(results, manifest, deps_mode, repo, filter_lua, cac end manifest.repository[name] = pkgtable end - update_dependencies(manifest, deps_mode, repo, filter_lua, cache) + if dep_handler then + dep_handler(manifest) + end sort_package_matching_table(manifest.modules) sort_package_matching_table(manifest.commands) return true @@ -345,7 +358,7 @@ end -- @param versioned boolean: if versioned versions of the manifest should be created. -- @return boolean or (nil, string): True if manifest was generated, -- or nil and an error message. -function make_manifest(repo, deps_mode, versioned) +function make_manifest(repo, deps_mode, remote) assert(type(repo) == "string") assert(type(deps_mode) == "string") @@ -363,14 +376,23 @@ function make_manifest(repo, deps_mode, versioned) manif_core.manifest_cache[repo] = manifest - local cache = {} - local ok, err = store_results(results, manifest, deps_mode, repo, nil, cache) + local dep_handler = nil + if not remote then + dep_handler = function(manifest) + update_dependencies(manifest, deps_mode) + end + end + local ok, err = store_results(results, manifest, dep_handler) if not ok then return nil, err end - if versioned then + if remote then + local cache = {} for luaver in util.lua_versions() do local vmanifest = { repository = {}, modules = {}, commands = {} } - local ok, err = store_results(results, vmanifest, deps_mode, repo, luaver, cache) + local dep_handler = function(manifest) + filter_by_lua_version(manifest, luaver, repo, cache) + end + local ok, err = store_results(results, vmanifest, dep_handler) save_table(repo, "manifest-"..luaver, vmanifest) end end @@ -416,7 +438,10 @@ function update_manifest(name, version, repo, deps_mode) local results = {[name] = {[version] = {{arch = "installed", repo = repo}}}} - local ok, err = store_results(results, manifest, deps_mode, repo) + local dep_handler = function(manifest) + update_dependencies(manifest, deps_mode) + end + local ok, err = store_results(results, manifest, dep_handler) if not ok then return nil, err end return save_table(repo, "manifest", manifest) diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua index 76ea6815..ad205d6a 100644 --- a/src/luarocks/search.lua +++ b/src/luarocks/search.lua @@ -139,14 +139,15 @@ function disk_search(repo, query, results) for _, name in pairs(fs.list_dir(repo)) do local pathname = dir.path(repo, name) local rname, rversion, rarch = path.parse_name(name) - if fs.is_dir(pathname) then + + if rname and (pathname:match(".rockspec$") or pathname:match(".rock$")) then + store_if_match(results, repo, rname, rversion, rarch, query) + elseif fs.is_dir(pathname) then for _, version in pairs(fs.list_dir(pathname)) do if version:match("-%d+$") then store_if_match(results, repo, name, version, "installed", query) end end - elseif rname then - store_if_match(results, repo, rname, rversion, rarch, query) end end return results -- cgit v1.2.3-55-g6feb