From 59be57e5478b657b826e4a2865e58481ccb5a474 Mon Sep 17 00:00:00 2001 From: V1K1NGbg Date: Thu, 22 Aug 2024 17:49:01 -0300 Subject: Teal: convert luarocks.cmd.new_version --- src/luarocks/cmd/new_version.lua | 228 ------------------------------------- src/luarocks/cmd/new_version.tl | 237 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 237 insertions(+), 228 deletions(-) delete mode 100644 src/luarocks/cmd/new_version.lua create mode 100644 src/luarocks/cmd/new_version.tl diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua deleted file mode 100644 index ccba9335..00000000 --- a/src/luarocks/cmd/new_version.lua +++ /dev/null @@ -1,228 +0,0 @@ - ---- Module implementing the LuaRocks "new_version" command. --- Utility function that writes a new rockspec, updating data from a previous one. -local new_version = {} - -local util = require("luarocks.util") -local download = require("luarocks.download") -local fetch = require("luarocks.fetch") -local persist = require("luarocks.persist") -local fs = require("luarocks.fs") -local dir = require("luarocks.dir") -local type_rockspec = require("luarocks.type.rockspec") - -function new_version.add_to_parser(parser) - local cmd = parser:command("new_version", [[ -This is a utility function that writes a new rockspec, updating data from a -previous one. - -If a package name is given, it downloads the latest rockspec from the default -server. If a rockspec is given, it uses it instead. If no argument is given, it -looks for a rockspec same way 'luarocks make' does. - -If the version number is not given and tag is passed using --tag, it is used as -the version, with 'v' removed from beginning. Otherwise, it only increments the -revision number of the given (or downloaded) rockspec. - -If a URL is given, it replaces the one from the old rockspec with the given URL. -If a URL is not given and a new version is given, it tries to guess the new URL -by replacing occurrences of the version number in the URL or tag; if the guessed -URL is invalid, the old URL is restored. It also tries to download the new URL -to determine the new MD5 checksum. - -If a tag is given, it replaces the one from the old rockspec. If there is an old -tag but no new one passed, it is guessed in the same way URL is. - -If a directory is not given, it defaults to the current directory. - -WARNING: it writes the new rockspec to the given directory, overwriting the file -if it already exists.]], util.see_also()) - :summary("Auto-write a rockspec for a new version of a rock.") - - cmd:argument("rock", "Package name or rockspec.") - :args("?") - cmd:argument("new_version", "New version of the rock.") - :args("?") - cmd:argument("new_url", "New URL of the rock.") - :args("?") - - cmd:option("--dir", "Output directory for the new rockspec.") - cmd:option("--tag", "New SCM tag.") -end - - -local function try_replace(tbl, field, old, new) - if not tbl[field] then - return false - end - local old_field = tbl[field] - local new_field = tbl[field]:gsub(old, new) - if new_field ~= old_field then - util.printout("Guessing new '"..field.."' field as "..new_field) - tbl[field] = new_field - return true - end - return false -end - --- Try to download source file using URL from a rockspec. --- If it specified MD5, update it. --- @return (true, false) if MD5 was not specified or it stayed same, --- (true, true) if MD5 changed, (nil, string) on error. -local function check_url_and_update_md5(out_rs, invalid_is_error) - local file, temp_dir = fetch.fetch_url_at_temp_dir(out_rs.source.url, "luarocks-new-version-"..out_rs.package) - if not file then - if invalid_is_error then - return nil, "invalid URL - "..temp_dir - end - util.warning("invalid URL - "..temp_dir) - return true, false - end - do - local inferred_dir, found_dir = fetch.find_base_dir(file, temp_dir, out_rs.source.url, out_rs.source.dir) - if not inferred_dir then - return nil, found_dir - end - - if found_dir and found_dir ~= inferred_dir then - out_rs.source.dir = found_dir - end - end - if file then - if out_rs.source.md5 then - util.printout("File successfully downloaded. Updating MD5 checksum...") - local new_md5, err = fs.get_md5(file) - if not new_md5 then - return nil, err - end - local old_md5 = out_rs.source.md5 - out_rs.source.md5 = new_md5 - return true, new_md5 ~= old_md5 - else - util.printout("File successfully downloaded.") - return true, false - end - end -end - -local function update_source_section(out_rs, url, tag, old_ver, new_ver) - if tag then - out_rs.source.tag = tag - end - if url then - out_rs.source.url = url - return check_url_and_update_md5(out_rs) - end - if new_ver == old_ver then - return true - end - if out_rs.source.dir then - try_replace(out_rs.source, "dir", old_ver, new_ver) - end - if out_rs.source.file then - try_replace(out_rs.source, "file", old_ver, new_ver) - end - - local old_url = out_rs.source.url - if try_replace(out_rs.source, "url", old_ver, new_ver) then - local ok, md5_changed = check_url_and_update_md5(out_rs, true) - if ok then - return ok, md5_changed - end - out_rs.source.url = old_url - end - if tag or try_replace(out_rs.source, "tag", old_ver, new_ver) then - return true - end - -- Couldn't replace anything significant, use the old URL. - local ok, md5_changed = check_url_and_update_md5(out_rs) - if not ok then - return nil, md5_changed - end - if md5_changed then - util.warning("URL is the same, but MD5 has changed. Old rockspec is broken.") - end - return true -end - -function new_version.command(args) - if not args.rock then - local err - args.rock, err = util.get_default_rockspec() - if not args.rock then - return nil, err - end - end - - local filename, err - if args.rock:match("rockspec$") then - filename, err = fetch.fetch_url(args.rock) - if not filename then - return nil, err - end - else - filename, err = download.download("rockspec", args.rock:lower()) - if not filename then - return nil, err - end - end - - local valid_rs, err = fetch.load_rockspec(filename) - if not valid_rs then - return nil, err - end - - local old_ver, old_rev = valid_rs.version:match("(.*)%-(%d+)$") - local new_ver, new_rev - - if args.tag and not args.new_version then - args.new_version = args.tag:gsub("^v", "") - end - - local out_dir - if args.dir then - out_dir = dir.normalize(args.dir) - end - - if args.new_version then - new_ver, new_rev = args.new_version:match("(.*)%-(%d+)$") - new_rev = tonumber(new_rev) - if not new_rev then - new_ver = args.new_version - new_rev = 1 - end - else - new_ver = old_ver - new_rev = tonumber(old_rev) + 1 - end - local new_rockver = new_ver:gsub("-", "") - - local out_rs, err = persist.load_into_table(filename) - local out_name = out_rs.package:lower() - out_rs.version = new_rockver.."-"..new_rev - - local ok, err = update_source_section(out_rs, args.new_url, args.tag, old_ver, new_ver) - if not ok then return nil, err end - - if out_rs.build and out_rs.build.type == "module" then - out_rs.build.type = "builtin" - end - - local out_filename = out_name.."-"..new_rockver.."-"..new_rev..".rockspec" - if out_dir then - out_filename = dir.path(out_dir, out_filename) - fs.make_dir(out_dir) - end - persist.save_from_table(out_filename, out_rs, type_rockspec.order) - - util.printout("Wrote "..out_filename) - - local valid_out_rs, err = fetch.load_local_rockspec(out_filename) - if not valid_out_rs then - return nil, "Failed loading generated rockspec: "..err - end - - return true -end - -return new_version diff --git a/src/luarocks/cmd/new_version.tl b/src/luarocks/cmd/new_version.tl new file mode 100644 index 00000000..d5da0e86 --- /dev/null +++ b/src/luarocks/cmd/new_version.tl @@ -0,0 +1,237 @@ + +--- Module implementing the LuaRocks "new_version" command. +-- Utility function that writes a new rockspec, updating data from a previous one. +local record new_version +end + +local util = require("luarocks.util") +local download = require("luarocks.download") +local fetch = require("luarocks.fetch") +local persist = require("luarocks.persist") +local fs = require("luarocks.fs") +local dir = require("luarocks.dir") +local type_rockspec = require("luarocks.type.rockspec") + +local type Parser = require("luarocks.vendor.argparse").Parser + +local type Args = require("luarocks.core.types.args").Args + +local type PersistableTable = require("luarocks.core.types.persist").PersistableTable + +local type Rockspec = require("luarocks.core.types.rockspec").Rockspec + +function new_version.add_to_parser(parser: Parser) + local cmd = parser:command("new_version", [[ +This is a utility function that writes a new rockspec, updating data from a +previous one. + +If a package name is given, it downloads the latest rockspec from the default +server. If a rockspec is given, it uses it instead. If no argument is given, it +looks for a rockspec same way 'luarocks make' does. + +If the version number is not given and tag is passed using --tag, it is used as +the version, with 'v' removed from beginning. Otherwise, it only increments the +revision number of the given (or downloaded) rockspec. + +If a URL is given, it replaces the one from the old rockspec with the given URL. +If a URL is not given and a new version is given, it tries to guess the new URL +by replacing occurrences of the version number in the URL or tag; if the guessed +URL is invalid, the old URL is restored. It also tries to download the new URL +to determine the new MD5 checksum. + +If a tag is given, it replaces the one from the old rockspec. If there is an old +tag but no new one passed, it is guessed in the same way URL is. + +If a directory is not given, it defaults to the current directory. + +WARNING: it writes the new rockspec to the given directory, overwriting the file +if it already exists.]], util.see_also()) + :summary("Auto-write a rockspec for a new version of a rock.") + + cmd:argument("rock", "Package name or rockspec.") + :args("?") + cmd:argument("new_version", "New version of the rock.") + :args("?") + cmd:argument("new_url", "New URL of the rock.") + :args("?") + + cmd:option("--dir", "Output directory for the new rockspec.") + cmd:option("--tag", "New SCM tag.") +end + + +local function try_replace(tbl: {string: string}, field: string, old: string, new: string): boolean + if not tbl[field] then + return false + end + local old_field = tbl[field] + local new_field = tbl[field]:gsub(old, new) + if new_field ~= old_field then + util.printout("Guessing new '"..field.."' field as "..new_field) + tbl[field] = new_field + return true + end + return false +end + +-- Try to download source file using URL from a rockspec. +-- If it specified MD5, update it. +-- @return (true, false) if MD5 was not specified or it stayed same, +-- (true, true) if MD5 changed, (nil, string) on error. +local function check_url_and_update_md5(out_rs: Rockspec, invalid_is_error?: boolean): boolean, string | boolean --! + local file, temp_dir = fetch.fetch_url_at_temp_dir(out_rs.source.url, "luarocks-new-version-"..out_rs.package) + if not file then + if invalid_is_error then + return nil, "invalid URL - "..temp_dir + end + util.warning("invalid URL - "..temp_dir) + return true, false + end + do + local inferred_dir, found_dir = fetch.find_base_dir(file, temp_dir, out_rs.source.url, out_rs.source.dir) + if not inferred_dir then + return nil, found_dir + end + + if found_dir and found_dir ~= inferred_dir then + out_rs.source.dir = found_dir + end + end + if file then + if out_rs.source.md5 then + util.printout("File successfully downloaded. Updating MD5 checksum...") + local new_md5, err = fs.get_md5(file) + if not new_md5 then + return nil, err + end + local old_md5 = out_rs.source.md5 + out_rs.source.md5 = new_md5 + return true, new_md5 ~= old_md5 + else + util.printout("File successfully downloaded.") + return true, false + end + end +end + +local function update_source_section(out_rs: Rockspec, url: string, tag: string, old_ver: string, new_ver: string): boolean, string | boolean + if tag then + out_rs.source.tag = tag + end + if url then + out_rs.source.url = url + return check_url_and_update_md5(out_rs) + end + if new_ver == old_ver then + return true + end + if out_rs.source.dir then + try_replace(out_rs.source as {string: string}, "dir", old_ver, new_ver) + end + if out_rs.source.file then + try_replace(out_rs.source as {string: string}, "file", old_ver, new_ver) + end + + local old_url = out_rs.source.url + if try_replace(out_rs.source as {string: string}, "url", old_ver, new_ver) then + local ok, md5_changed = check_url_and_update_md5(out_rs, true) + if ok then + return ok, md5_changed + end + out_rs.source.url = old_url + end + if tag or try_replace(out_rs.source as {string: string}, "tag", old_ver, new_ver) then + return true + end + -- Couldn't replace anything significant, use the old URL. + local ok, md5_changed = check_url_and_update_md5(out_rs) + if not ok then + return nil, md5_changed + end + if md5_changed then + util.warning("URL is the same, but MD5 has changed. Old rockspec is broken.") + end + return true +end + +function new_version.command(args: Args): boolean, string | boolean + if not args.rock then + local err: string + args.rock, err = util.get_default_rockspec() + if not args.rock then + return nil, err + end + end + + local filename, err: string, string + if args.rock:match("rockspec$") then + filename, err = fetch.fetch_url(args.rock) + if not filename then + return nil, err + end + else + filename, err = download.download_file("rockspec", args.rock:lower()) + if not filename then + return nil, err + end + end + + local valid_rs, err = fetch.load_rockspec(filename) + if not valid_rs then + return nil, err + end + + local old_ver, old_rev = valid_rs.version:match("(.*)%-(%d+)$") + local new_ver, new_rev_str, new_rev: string, string, integer + + if args.tag and not args.new_version then + args.new_version = args.tag:gsub("^v", "") + end + + local out_dir: string + if args.dir then + out_dir = dir.normalize(args.dir) + end + + if args.new_version then + new_ver, new_rev_str = args.new_version:match("(.*)%-(%d+)$") + new_rev = math.tointeger(new_rev_str) + if not new_rev then + new_ver = args.new_version + new_rev = 1 + end + else + new_ver = old_ver + new_rev = math.tointeger(old_rev) + 1 + end + local new_rockver = new_ver:gsub("-", "") + + local out_rs, err = persist.load_into_table(filename) as Rockspec, string + local out_name = out_rs.package:lower() + out_rs.version = new_rockver.."-"..tostring(new_rev) + + local ok, err = update_source_section(out_rs, args.new_url, args.tag, old_ver, new_ver) + if not ok then return nil, err end + + if out_rs.build and out_rs.build.type == "module" then + out_rs.build.type = "builtin" + end + + local out_filename = out_name.."-"..new_rockver.."-"..tostring(new_rev)..".rockspec" + if out_dir then + out_filename = dir.path(out_dir, out_filename) + fs.make_dir(out_dir) + end + persist.save_from_table(out_filename, out_rs as PersistableTable, type_rockspec.order) + + util.printout("Wrote "..out_filename) + + local valid_out_rs, err = fetch.load_local_rockspec(out_filename) + if not valid_out_rs then + return nil, "Failed loading generated rockspec: "..err + end + + return true +end + +return new_version -- cgit v1.2.3-55-g6feb