From 3c7c4722a5ab6aa32f62622643a5b68fa1e5a7d2 Mon Sep 17 00:00:00 2001 From: mpeterv Date: Thu, 19 Mar 2015 12:22:02 +0300 Subject: Refactor persist.load_into_table * Add docstring for run_file helper function; * Do not read file twice on Lua > 5.1, use load instead of loadfile; * Update docstring for persist.load_into_table. --- src/luarocks/persist.lua | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index 9a40785c..8162c662 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua @@ -9,8 +9,14 @@ package.loaded["luarocks.persist"] = persist local util = require("luarocks.util") +--- Load and run a Lua file in an environment. +-- @param filename string: the name of the file. +-- @param env table: the environment table. +-- @return (true, any) or (nil, string, string): true and the return value +-- of the file, or nil, an error message and an error code ("open", "load" +-- or "run") in case of errors. local function run_file(filename, env) - local fd, err, errno = io.open(filename) + local fd, err = io.open(filename) if not fd then return nil, err, "open" end @@ -28,7 +34,7 @@ local function run_file(filename, env) ran, err = pcall(chunk) end else -- Lua 5.2 - chunk, err = loadfile(filename, "t", env) + chunk, err = load(str, filename, "t", env) if chunk then ran, err = pcall(chunk) end @@ -47,9 +53,10 @@ end -- @param filename string: the name of the file. -- @param tbl table or nil: if given, this table is used to store -- loaded values. --- @return table or (nil, string, string): a table with the file's assignments --- as fields, or nil, an error message and an error code ("load" or "run") --- in case of errors. +-- @return (table, table) or (nil, string, string): a table with the file's +-- assignments as fields and set of undefined globals accessed in file, +-- or nil, an error message and an error code ("open", "load" or "run") in +-- case of errors. function persist.load_into_table(filename, tbl) assert(type(filename) == "string") assert(type(tbl) == "table" or not tbl) @@ -57,9 +64,8 @@ function persist.load_into_table(filename, tbl) local result = tbl or {} local globals = {} local globals_mt = { - __index = function(t, n) - globals[n] = true - return rawget(t, n) + __index = function(t, k) + globals[k] = true end } local save_mt = getmetatable(result) -- cgit v1.2.3-55-g6feb From cf1917849bc2e35a125c1d0142343c64da776fdf Mon Sep 17 00:00:00 2001 From: mpeterv Date: Thu, 19 Mar 2015 13:20:38 +0300 Subject: Refactor persist.save_from_table * Update docstrings; * Improve string quoting (don't produce broken code for strings with backslashes); * Use same function for writing keys and values; * Don't use same name (write_table) for two different functions. --- src/luarocks/persist.lua | 70 +++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index 8162c662..04440670 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua @@ -83,10 +83,10 @@ end local write_table ---- Write a value as Lua code, invoking write_table. --- This function handles only numbers, strings and tables --- are keys (tables are handled recursively). --- @param out userdata: a file object, open for writing. +--- Write a value as Lua code. +-- This function handles only numbers and strings, invoking write_table +-- to write tables. +-- @param out table or userdata: a writer object supporting :write() method. -- @param v: the value to be written. -- @param level number: the indentation level -- @param sub_order table: optional prioritization table @@ -95,28 +95,27 @@ local function write_value(out, v, level, sub_order) if type(v) == "table" then write_table(out, v, level + 1, sub_order) elseif type(v) == "string" then - if v:match("\n") then + if v:match("[\r\n]") then local open, close = "[[", "]]" local equals = 0 - while v:find(open,1,true) or v:find(close,1,true) do + while v:find(close, 1, true) do equals = equals + 1 local eqs = ("="):rep(equals) open, close = "["..eqs.."[", "]"..eqs.."]" end out:write(open.."\n"..v..close) else - out:write("\""..v:gsub("\"", "\\\"").."\"") + out:write("\""..v:gsub("\\", "\\\\"):gsub("\"", "\\\"").."\"") end else out:write(tostring(v)) end end ---- Write a table as Lua code representing a table to disk --- (that is, in curly brackets notation). --- This function handles only numbers, strings and tables --- are keys (tables are handled recursively). --- @param out userdata: a file object, open for writing. +--- Write a table as Lua code in curly brackets notation to a writer object. +-- Only numbers, strings and tables (containing numbers, strings +-- or other recursively processed tables) are supported. +-- @param out table or userdata: a writer object supporting :write() method. -- @param tbl table: the table to be written. -- @param level number: the indentation level -- @param field_order table: optional prioritization table @@ -131,28 +130,29 @@ write_table = function(out, tbl, level, field_order) if indent then for n = 1,level do out:write(indentation) end end - sep = ",\n" - indent = true - if type(k) == "number" then - if k ~= i then - out:write("["..tostring(k).."]=") - else - i = i + 1 - end - indent = false - sep = ", " - elseif type(k) == "table" then - out:write("[") - write_table(out, k, level + 1) - out:write("] = ") + + if k == i then + i = i + 1 else - if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then - out:write(k.." = ") + if type(k) == "string" and k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then + out:write(k) else - out:write("['"..k:gsub("'", "\\'").."'] = ") + out:write("[") + write_value(out, k, level) + out:write("]") end + + out:write(" = ") end + write_value(out, v, level, sub_order) + if type(k) == "number" then + sep = ", " + indent = false + else + sep = ",\n" + indent = true + end end if sep ~= "\n" then out:write("\n") @@ -161,18 +161,16 @@ write_table = function(out, tbl, level, field_order) out:write("}") end ---- Writes a table to an io-like object. --- @param out userdata: a file object, open for writing. +--- Write a table as series of assignments to a writer object. +-- @param out table or userdata: a writer object supporting :write() method. -- @param tbl table: the table to be written. -- @param field_order table: optional prioritization table --- @return userdata The file object originally passed in as the `out` parameter. -local function write_table(out, tbl, field_order) +local function write_table_as_assignments(out, tbl, field_order) for k, v, sub_order in util.sortedpairs(tbl, field_order) do out:write(k.." = ") write_value(out, v, 0, sub_order) out:write("\n") end - return out end --- Save the contents of a table to a string. @@ -185,7 +183,7 @@ end function persist.save_from_table_to_string(tbl, field_order) local out = {buffer = {}} function out:write(data) table.insert(self.buffer, data) end - write_table(out, tbl, field_order) + write_table_as_assignments(out, tbl, field_order) return table.concat(out.buffer) end @@ -203,7 +201,7 @@ function persist.save_from_table(filename, tbl, field_order) if not out then return nil, "Cannot create file at "..filename end - write_table(out, tbl, field_order) + write_table_as_assignments(out, tbl, field_order) out:close() return true end -- cgit v1.2.3-55-g6feb From 20eb94723f142f2bba420a05046157a3e115a3f0 Mon Sep 17 00:00:00 2001 From: mpeterv Date: Thu, 19 Mar 2015 16:02:25 +0300 Subject: Improve hg support * Allow fetching from remote hg repos using hg+http, hg+https and hg+ssh protocols; * Fix incorrect branch cloning. --- Makefile.setup.inc | 3 ++- src/luarocks/fetch/hg.lua | 2 +- src/luarocks/fetch/hg_http.lua | 24 ++++++++++++++++++++++++ src/luarocks/fetch/hg_https.lua | 8 ++++++++ src/luarocks/fetch/hg_ssh.lua | 8 ++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/luarocks/fetch/hg_http.lua create mode 100644 src/luarocks/fetch/hg_https.lua create mode 100644 src/luarocks/fetch/hg_ssh.lua (limited to 'src') diff --git a/Makefile.setup.inc b/Makefile.setup.inc index eb51ba5e..ef498e9b 100644 --- a/Makefile.setup.inc +++ b/Makefile.setup.inc @@ -15,5 +15,6 @@ manif_core.lua fetch.lua unpack.lua validate.lua cfg.lua download.lua \ help.lua util.lua index.lua cache.lua refresh_cache.lua loader.lua \ admin_remove.lua fetch/hg.lua fetch/git_file.lua new_version.lua lint.lua \ purge.lua path.lua path_cmd.lua write_rockspec.lua doc.lua upload.lua \ -upload/api.lua upload/multipart.lua fetch/git_http.lua +upload/api.lua upload/multipart.lua fetch/git_http.lua fetch/hg_http.lua \ +fetch/hg_https.lua fetch/hg_ssh.lua diff --git a/src/luarocks/fetch/hg.lua b/src/luarocks/fetch/hg.lua index b2ba56e9..e736a071 100644 --- a/src/luarocks/fetch/hg.lua +++ b/src/luarocks/fetch/hg.lua @@ -30,7 +30,7 @@ function hg.get_sources(rockspec, extract, dest_dir) local command = {hg_cmd, "clone", url, module} local tag_or_branch = rockspec.source.tag or rockspec.source.branch if tag_or_branch then - command = {hg_cmd, "clone", "--rev", url, module} + command = {hg_cmd, "clone", "--rev", tag_or_branch, url, module} end local store_dir if not dest_dir then diff --git a/src/luarocks/fetch/hg_http.lua b/src/luarocks/fetch/hg_http.lua new file mode 100644 index 00000000..8f506daf --- /dev/null +++ b/src/luarocks/fetch/hg_http.lua @@ -0,0 +1,24 @@ + +--- Fetch back-end for retrieving sources from hg repositories +-- that use http:// transport. For example, for fetching a repository +-- that requires the following command line: +-- `hg clone http://example.com/foo` +-- you can use this in the rockspec: +-- source = { url = "hg+http://example.com/foo" } +local hg_http = {} + +local hg = require("luarocks.fetch.hg") + +--- Download sources for building a rock, using hg over http. +-- @param rockspec table: The rockspec table +-- @param extract boolean: Unused in this module (required for API purposes.) +-- @param dest_dir string or nil: If set, will extract to the given directory. +-- @return (string, string) or (nil, string): The absolute pathname of +-- the fetched source tarball and the temporary directory created to +-- store it; or nil and an error message. +function hg_http.get_sources(rockspec, extract, dest_dir) + rockspec.source.url = rockspec.source.url:gsub("^hg.", "") + return hg.get_sources(rockspec, extract, dest_dir) +end + +return hg_http diff --git a/src/luarocks/fetch/hg_https.lua b/src/luarocks/fetch/hg_https.lua new file mode 100644 index 00000000..e67417fe --- /dev/null +++ b/src/luarocks/fetch/hg_https.lua @@ -0,0 +1,8 @@ + +--- Fetch back-end for retrieving sources from hg repositories +-- that use https:// transport. For example, for fetching a repository +-- that requires the following command line: +-- `hg clone https://example.com/foo` +-- you can use this in the rockspec: +-- source = { url = "hg+https://example.com/foo" } +return require "luarocks.fetch.hg_http" diff --git a/src/luarocks/fetch/hg_ssh.lua b/src/luarocks/fetch/hg_ssh.lua new file mode 100644 index 00000000..0c365fab --- /dev/null +++ b/src/luarocks/fetch/hg_ssh.lua @@ -0,0 +1,8 @@ + +--- Fetch back-end for retrieving sources from hg repositories +-- that use ssh:// transport. For example, for fetching a repository +-- that requires the following command line: +-- `hg clone ssh://example.com/foo` +-- you can use this in the rockspec: +-- source = { url = "hg+ssh://example.com/foo" } +return require "luarocks.fetch.hg_http" -- cgit v1.2.3-55-g6feb