ExperimentalGear/scripts/core/platform/filesys.lua

144 lines
3.9 KiB
Lua
Raw Normal View History

---@diagnostic disable: duplicate-set-field
require "common.globals"
2024-02-02 02:27:05 +01:00
require "api.logging"
require("core.string")
---@class filesys
filesys = {
__name = "filesys",
sep = "/"
}
---Return a normalized absolutized version of `path`
---@param path string
---@return string
function filesys.abspath(path)
return filesys.normpath(filesys.join(filesys.getcwd(), path))
end
---Return the base name of `path`
---@param path string
---@return string
function filesys.basename(path)
return string.sub(path, string.rfind(path, filesys.sep, 1, true) + 1)
end
---Return the directory name of `path`
---@param path string
---@return string
function filesys.dirname(path)
return filesys.split(path)[1]
end
---Return true if `path` refers to an existing path
---@param path string
---@return boolean, string?
function filesys.exists(path)
local ok, err, code = os.rename(path, path)
if not ok then
2024-02-02 02:27:05 +01:00
DetailedLog("err: "..err..", code: "..code, game.LOGGER_DEBUG)
if code == 13 then
-- Permission denied, but it exists
return true
end
end
return ok, err
end
2024-02-02 02:27:05 +01:00
---Returns a path relative to the current working directory from a texture path
---@param path string # must be a path accepted by game.CreateSkinImage and such
---@return string
function FileSys.fromTexturePath(path)
--skins/<skin>/textures/<path>
local relpath = FileSys.join("skins", game.GetSkin(), "textures", FileSys.normpath(path))
if not FileSys.exists(FileSys.join(FileSys.getcwd(), relpath)) then
DetailedLog("'"..relpath.."' does not exist", game.LOGGER_ERROR)
end
return relpath
end
---Return a string representing the current working directory
---@return string
function filesys.getcwd()
assert(false, filesys.__name .. ".getcwd() : Not Implemented")
return ""
end
---Join one or more path components with the platform specific separator
---@param path string
---@param ... string
---@return string
function filesys.join(path, ...)
local vargs = { select(1, ...) }
local joinedpath = path
for _, value in ipairs(vargs) do
joinedpath = joinedpath .. filesys.sep .. value
end
return joinedpath
end
---Normalize `path`, collapse redundant separators and up references
---@param path string
2024-02-02 02:27:05 +01:00
---@param overrideSep? string
---@return string
function filesys.normpath(path, overrideSep)
local sep = overrideSep or filesys.sep
--remove multiple slashes
path = path:gsub("("..sep..")"..sep.."+", "%1")
--remove './'
path = path:gsub("%."..sep, "")
--remove all up references
local count = 0
local upRefPattern = "%w+"..sep.."%.%."..sep
repeat
path, count = path:gsub(upRefPattern, "")
2024-02-02 02:27:05 +01:00
until count == 0
--remove last slash
path = path:gsub("(.-)"..sep.."$", "%1")
return path
end
---Return a relative filepath to `path`, optionally relative to `relativeTo`
---@param path string
---@param relativeTo? string
---@return string
function filesys.relpath(path, relativeTo)
relativeTo = relativeTo or filesys.getcwd()
path = path:sub(path:find(relativeTo, 1, true)[2] + 1)
return path
end
---Return a list of files and directory names in `path`
---@param path string
---@return string[]
function filesys.scandir(path)
assert(false, filesys.__name .. ".scandir() : Not Implemented")
return {}
end
---Split `path` to (head, tail), tail is the last component, head is everything else
---@param path string
---@return string, string
function filesys.split(path)
local lastSep = path:rfind(filesys.sep, 1, true)
return path:sub(1, lastSep), path:sub(lastSep + 1)
end
---Split `path` to (root, ext), such that `root + ext == path`, ext is either empty or starts with a '.'
---@param path string
---@return string, string
function filesys.splitext(path)
local lastSep = path:rfind(".", 1, true)
return path:sub(1, lastSep - 1), path:sub(lastSep)
end