summaryrefslogtreecommitdiff
path: root/src/luarocks/fs.lua
diff options
context:
space:
mode:
authorMike Vink <mike@pionative.com>2025-02-03 21:29:42 +0100
committerMike Vink <mike@pionative.com>2025-02-03 21:29:42 +0100
commit5155816b7b925dec5d5feb1568b1d7ceb00938b9 (patch)
treedeca28ea15e79f6f804c3d90d2ba757881638af5 /src/luarocks/fs.lua
fetch tarballHEADmaster
Diffstat (limited to 'src/luarocks/fs.lua')
-rw-r--r--src/luarocks/fs.lua148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/luarocks/fs.lua b/src/luarocks/fs.lua
new file mode 100644
index 0000000..a8156a2
--- /dev/null
+++ b/src/luarocks/fs.lua
@@ -0,0 +1,148 @@
+
+--- Proxy module for filesystem and platform abstractions.
+-- All code using "fs" code should require "luarocks.fs",
+-- and not the various platform-specific implementations.
+-- However, see the documentation of the implementation
+-- for the API reference.
+
+local pairs = pairs
+
+local fs = {}
+-- To avoid a loop when loading the other fs modules.
+package.loaded["luarocks.fs"] = fs
+
+local cfg = require("luarocks.core.cfg")
+
+local pack = table.pack or function(...) return { n = select("#", ...), ... } end
+
+math.randomseed(os.time())
+
+local fs_is_verbose = false
+
+do
+ local old_popen, old_execute
+
+ -- patch io.popen and os.execute to display commands in verbose mode
+ function fs.verbose()
+ fs_is_verbose = true
+
+ if old_popen or old_execute then return end
+ old_popen = io.popen
+ -- luacheck: push globals io os
+ io.popen = function(one, two)
+ if two == nil then
+ print("\nio.popen: ", one)
+ else
+ print("\nio.popen: ", one, "Mode:", two)
+ end
+ return old_popen(one, two)
+ end
+
+ old_execute = os.execute
+ os.execute = function(cmd)
+ -- redact api keys if present
+ print("\nos.execute: ", (cmd:gsub("(/api/[^/]+/)([^/]+)/", function(cap, key) return cap.."<redacted>/" end)) )
+ local a, b, c = old_execute(cmd)
+ if type(a) == "boolean" then
+ print((a and ".........." or "##########") .. ": " .. tostring(c) .. (b == "exit" and "" or " (" .. tostring(b) .. ")"))
+ elseif type(a) == "number" then
+ print(((a == 0) and ".........." or "##########") .. ": " .. tostring(a))
+ end
+ return a, b, c
+ end
+ -- luacheck: pop
+ end
+end
+
+do
+ local skip_verbose_wrap = {
+ ["current_dir"] = true,
+ }
+
+ local function load_fns(fs_table, inits)
+ for name, fn in pairs(fs_table) do
+ if name ~= "init" and not fs[name] then
+ if skip_verbose_wrap[name] then
+ fs[name] = fn
+ else
+ fs[name] = function(...)
+ if fs_is_verbose then
+ local args = pack(...)
+ for i=1, args.n do
+ local arg = args[i]
+ local pok, v = pcall(string.format, "%q", arg)
+ args[i] = pok and v or tostring(arg)
+ end
+ print("fs." .. name .. "(" .. table.concat(args, ", ") .. ")")
+ end
+ return fn(...)
+ end
+ end
+ end
+ end
+ if fs_table.init then
+ table.insert(inits, fs_table.init)
+ end
+ end
+
+ local function load_platform_fns(patt, inits)
+ local each_platform = cfg.each_platform
+
+ -- FIXME A quick hack for the experimental Windows build
+ if os.getenv("LUAROCKS_CROSS_COMPILING") then
+ each_platform = function()
+ local i = 0
+ local plats = { "linux", "unix" }
+ return function()
+ i = i + 1
+ return plats[i]
+ end
+ end
+ end
+
+ for platform in each_platform("most-specific-first") do
+ local ok, fs_plat = pcall(require, patt:format(platform))
+ if ok and fs_plat then
+ load_fns(fs_plat, inits)
+ end
+ end
+ end
+
+ function fs.init()
+ local inits = {}
+
+ if fs.current_dir then
+ -- unload luarocks fs so it can be reloaded using all modules
+ -- providing extra functionality in the current package paths
+ for k, _ in pairs(fs) do
+ if k ~= "init" and k ~= "verbose" then
+ fs[k] = nil
+ end
+ end
+ for m, _ in pairs(package.loaded) do
+ if m:match("luarocks%.fs%.") then
+ package.loaded[m] = nil
+ end
+ end
+ end
+
+ -- Load platform-specific functions
+ load_platform_fns("luarocks.fs.%s", inits)
+
+ -- Load platform-independent pure-Lua functionality
+ load_fns(require("luarocks.fs.lua"), inits)
+
+ -- Load platform-specific fallbacks for missing Lua modules
+ load_platform_fns("luarocks.fs.%s.tools", inits)
+
+ -- Load platform-independent external tool functionality
+ load_fns(require("luarocks.fs.tools"), inits)
+
+ -- Run platform-specific initializations after everything is loaded
+ for _, init in ipairs(inits) do
+ init()
+ end
+ end
+end
+
+return fs