From 091c6a54952f1d67400a5c3b4da5ee2f469e0484 Mon Sep 17 00:00:00 2001 From: V1K1NGbg Date: Thu, 22 Aug 2024 17:48:57 -0300 Subject: Teal: convert luarocks.pack --- src/luarocks/pack.lua | 184 ------------------------------------------------ src/luarocks/pack.tl | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 184 deletions(-) delete mode 100644 src/luarocks/pack.lua create mode 100644 src/luarocks/pack.tl (limited to 'src') diff --git a/src/luarocks/pack.lua b/src/luarocks/pack.lua deleted file mode 100644 index 731f49dd..00000000 --- a/src/luarocks/pack.lua +++ /dev/null @@ -1,184 +0,0 @@ - --- Create rock files, packing sources or binaries. -local pack = {} - -local unpack = unpack or table.unpack - -local queries = require("luarocks.queries") -local path = require("luarocks.path") -local repos = require("luarocks.repos") -local fetch = require("luarocks.fetch") -local fs = require("luarocks.fs") -local cfg = require("luarocks.core.cfg") -local util = require("luarocks.util") -local dir = require("luarocks.dir") -local manif = require("luarocks.manif") -local search = require("luarocks.search") -local signing = require("luarocks.signing") - ---- Create a source rock. --- Packages a rockspec and its required source files in a rock --- file with the .src.rock extension, which can later be built and --- installed with the "build" command. --- @param rockspec_file string: An URL or pathname for a rockspec file. --- @return string or (nil, string): The filename of the resulting --- .src.rock file; or nil and an error message. -function pack.pack_source_rock(rockspec_file) - assert(type(rockspec_file) == "string") - - local rockspec, err = fetch.load_rockspec(rockspec_file) - if err then - return nil, "Error loading rockspec: "..err - end - rockspec_file = rockspec.local_abs_filename - - local name_version = rockspec.name .. "-" .. rockspec.version - local rock_file = fs.absolute_name(name_version .. ".src.rock") - - local temp_dir, err = fs.make_temp_dir("pack-"..name_version) - if not temp_dir then - return nil, "Failed creating temporary directory: "..err - end - util.schedule_function(fs.delete, temp_dir) - - local source_file, source_dir = fetch.fetch_sources(rockspec, true, temp_dir) - if not source_file then - return nil, source_dir - end - local ok, err = fs.change_dir(source_dir) - if not ok then return nil, err end - - fs.delete(rock_file) - fs.copy(rockspec_file, source_dir, "read") - ok, err = fs.zip(rock_file, dir.base_name(rockspec_file), dir.base_name(source_file)) - if not ok then - return nil, "Failed packing "..rock_file.." - "..err - end - fs.pop_dir() - - return rock_file -end - -local function copy_back_files(name, version, file_tree, deploy_dir, pack_dir, perms) - local ok, err = fs.make_dir(pack_dir) - if not ok then return nil, err end - for file, sub in pairs(file_tree) do - local source = dir.path(deploy_dir, file) - local target = dir.path(pack_dir, file) - if type(sub) == "table" then - local ok, err = copy_back_files(name, version, sub, source, target) - if not ok then return nil, err end - else - local versioned = path.versioned_name(source, deploy_dir, name, version) - if fs.exists(versioned) then - fs.copy(versioned, target, perms) - else - fs.copy(source, target, perms) - end - end - end - return true -end - --- @param name string: Name of package to pack. --- @param version string or nil: A version number may also be passed. --- @param tree string or nil: An optional tree to pick the package from. --- @return string or (nil, string): The filename of the resulting --- .src.rock file; or nil and an error message. -function pack.pack_installed_rock(query, tree) - - local name, version, repo, repo_url = search.pick_installed_rock(query, tree) - if not name then - return nil, version - end - - local root = path.root_from_rocks_dir(repo_url) - local prefix = path.install_dir(name, version, root) - if not fs.exists(prefix) then - return nil, "'"..name.." "..version.."' does not seem to be an installed rock." - end - - local rock_manifest, err = manif.load_rock_manifest(name, version, root) - if not rock_manifest then return nil, err end - - local name_version = name .. "-" .. version - local rock_file = fs.absolute_name(name_version .. "."..cfg.arch..".rock") - - local temp_dir = fs.make_temp_dir("pack") - fs.copy_contents(prefix, temp_dir) - - local is_binary = false - if rock_manifest.lib then - local ok, err = copy_back_files(name, version, rock_manifest.lib, path.deploy_lib_dir(repo), dir.path(temp_dir, "lib"), "exec") - if not ok then return nil, "Failed copying back files: " .. err end - is_binary = true - end - if rock_manifest.lua then - local ok, err = copy_back_files(name, version, rock_manifest.lua, path.deploy_lua_dir(repo), dir.path(temp_dir, "lua"), "read") - if not ok then return nil, "Failed copying back files: " .. err end - end - - local ok, err = fs.change_dir(temp_dir) - if not ok then return nil, err end - if not is_binary and not repos.has_binaries(name, version) then - rock_file = rock_file:gsub("%."..cfg.arch:gsub("%-","%%-").."%.", ".all.") - end - fs.delete(rock_file) - ok, err = fs.zip(rock_file, unpack(fs.list_dir())) - if not ok then - return nil, "Failed packing " .. rock_file .. " - " .. err - end - fs.pop_dir() - fs.delete(temp_dir) - return rock_file -end - -function pack.report_and_sign_local_file(file, err, sign) - if err then - return nil, err - end - local sigfile - if sign then - sigfile, err = signing.sign_file(file) - util.printout() - end - util.printout("Packed: "..file) - if sigfile then - util.printout("Signature stored in: "..sigfile) - end - if err then - return nil, err - end - return true -end - -function pack.pack_binary_rock(name, namespace, version, sign, cmd) - - -- The --pack-binary-rock option for "luarocks build" basically performs - -- "luarocks build" on a temporary tree and then "luarocks pack". The - -- alternative would require refactoring parts of luarocks.build and - -- luarocks.pack, which would save a few file operations: the idea would be - -- to shave off the final deploy steps from the build phase and the initial - -- collect steps from the pack phase. - - local temp_dir, err = fs.make_temp_dir("luarocks-build-pack-"..dir.base_name(name)) - if not temp_dir then - return nil, "Failed creating temporary directory: "..err - end - util.schedule_function(fs.delete, temp_dir) - - path.use_tree(temp_dir) - local ok, err = cmd() - if not ok then - return nil, err - end - local rname, rversion = path.parse_name(name) - if not rname then - rname, rversion = name, version - end - local query = queries.new(rname, namespace, rversion) - local file, err = pack.pack_installed_rock(query, temp_dir) - return pack.report_and_sign_local_file(file, err, sign) -end - -return pack diff --git a/src/luarocks/pack.tl b/src/luarocks/pack.tl new file mode 100644 index 00000000..8bb284f7 --- /dev/null +++ b/src/luarocks/pack.tl @@ -0,0 +1,188 @@ + +-- Create rock files, packing sources or binaries. +local record pack +end + +local queries = require("luarocks.queries") +local path = require("luarocks.path") +local repos = require("luarocks.repos") +local fetch = require("luarocks.fetch") +local fs = require("luarocks.fs") +local cfg = require("luarocks.core.cfg") +local util = require("luarocks.util") +local dir = require("luarocks.dir") +local manif = require("luarocks.manif") +local search = require("luarocks.search") +local signing = require("luarocks.signing") + +local type Tree = require("luarocks.core.types.tree").Tree + +local type Query = require("luarocks.core.types.query").Query + +local type Entry = require("luarocks.core.types.rockmanifest").RockManifest.Entry + +--- Create a source rock. +-- Packages a rockspec and its required source files in a rock +-- file with the .src.rock extension, which can later be built and +-- installed with the "build" command. +-- @param rockspec_file string: An URL or pathname for a rockspec file. +-- @return string or (nil, string): The filename of the resulting +-- .src.rock file; or nil and an error message. +function pack.pack_source_rock(rockspec_file: string): string, string + + local rockspec, errload = fetch.load_rockspec(rockspec_file) + if errload then + return nil, "Error loading rockspec: "..errload + end + rockspec_file = rockspec.local_abs_filename + + local name_version = rockspec.name .. "-" .. rockspec.version + local rock_file = fs.absolute_name(name_version .. ".src.rock") + + local temp_dir, err = fs.make_temp_dir("pack-"..name_version) + if not temp_dir then + return nil, "Failed creating temporary directory: "..err + end + util.schedule_function(fs.delete, temp_dir) + + local source_file, source_dir = fetch.fetch_sources(rockspec, true, temp_dir) + if not source_file then + return nil, source_dir + end + local ok, errchange = fs.change_dir(source_dir) + if not ok then return nil, errchange end + + fs.delete(rock_file) + fs.copy(rockspec_file, source_dir, "read") + ok, err = fs.zip(rock_file, dir.base_name(rockspec_file), dir.base_name(source_file)) + if not ok then + return nil, "Failed packing "..rock_file.." - "..err + end + fs.pop_dir() + + return rock_file +end + +local function copy_back_files(name: string, version: string, file_tree: {string: any}, deploy_dir: string, pack_dir: string, perms?: string): boolean, string + local ok, err = fs.make_dir(pack_dir) + if not ok then return nil, err end + for file, sub in pairs(file_tree) do + local source = dir.path(deploy_dir, file) + local target = dir.path(pack_dir, file) + if sub is {string: any} then + ok, err = copy_back_files(name, version, sub, source, target) + if not ok then return nil, err end + else + local versioned = path.versioned_name(source, deploy_dir, name, version) + if fs.exists(versioned) then + fs.copy(versioned, target, perms) + else + fs.copy(source, target, perms) + end + end + end + return true +end + +-- @param name string: Name of package to pack. +-- @param version string or nil: A version number may also be passed. +-- @param tree string or nil: An optional tree to pick the package from. +-- @return string or (nil, string): The filename of the resulting +-- .src.rock file; or nil and an error message. +function pack.pack_installed_rock(query: Query, tree: string | Tree): string, string + + local name, version, repo, repo_url = search.pick_installed_rock(query, tree) + if not name then + return nil, version + end + + local root = path.root_from_rocks_dir(repo_url) + local prefix = path.install_dir(name, version, root) + if not fs.exists(prefix) then + return nil, "'"..name.." "..version.."' does not seem to be an installed rock." + end + + local rock_manifest, err = manif.load_rock_manifest(name, version, root) + if not rock_manifest then return nil, err end + + local name_version = name .. "-" .. version + local rock_file = fs.absolute_name(name_version .. "."..cfg.arch..".rock") + + local temp_dir = fs.make_temp_dir("pack") + fs.copy_contents(prefix, temp_dir) + + local is_binary = false + if rock_manifest.lib then + local ok, err = copy_back_files(name, version, (rock_manifest.lib as {string: Entry}), path.deploy_lib_dir(repo), dir.path(temp_dir, "lib"), "exec") + if not ok then return nil, "Failed copying back files: " .. err end + is_binary = true + end + if rock_manifest.lua then + local ok, err = copy_back_files(name, version, (rock_manifest.lua as {string: Entry}), path.deploy_lua_dir(repo), dir.path(temp_dir, "lua"), "read") + if not ok then return nil, "Failed copying back files: " .. err end + end + + local ok, err = fs.change_dir(temp_dir) + if not ok then return nil, err end + if not is_binary and not repos.has_binaries(name, version) then + rock_file = rock_file:gsub("%."..cfg.arch:gsub("%-","%%-").."%.", ".all.") + end + fs.delete(rock_file) + ok, err = fs.zip(rock_file, table.unpack(fs.list_dir())) + if not ok then + return nil, "Failed packing " .. rock_file .. " - " .. err + end + fs.pop_dir() + fs.delete(temp_dir) + return rock_file +end + +function pack.report_and_sign_local_file(file: string, err: string, sign: boolean): boolean, string + if err then + return nil, err + end + local sigfile: string + if sign then + sigfile, err = signing.sign_file(file) + util.printout() + end + util.printout("Packed: "..file) + if sigfile then + util.printout("Signature stored in: "..sigfile) + end + if err then + return nil, err + end + return true +end + +function pack.pack_binary_rock(name: string, namespace: string, version: string, sign: boolean, cmd: function(): (string, string)): boolean, string + + -- The --pack-binary-rock option for "luarocks build" basically performs + -- "luarocks build" on a temporary tree and then "luarocks pack". The + -- alternative would require refactoring parts of luarocks.build and + -- luarocks.pack, which would save a few file operations: the idea would be + -- to shave off the final deploy steps from the build phase and the initial + -- collect steps from the pack phase. + + local temp_dir, err = fs.make_temp_dir("luarocks-build-pack-"..dir.base_name(name)) + if not temp_dir then + return nil, "Failed creating temporary directory: "..err + end + util.schedule_function(fs.delete, temp_dir) + + path.use_tree(temp_dir) + local ok, err = cmd() + if not ok then + return nil, err + end + local rname, rversion = path.parse_name(name) + if not rname then + rname, rversion = name, version + end + local query = queries.new(rname, namespace, rversion) + local file, err = pack.pack_installed_rock(query, temp_dir) + return pack.report_and_sign_local_file(file, err, sign) +end + +return pack -- cgit v1.2.3-55-g6feb