Skip to content

Commit

Permalink
fix(pl.path): make expanduser more sturdy
Browse files Browse the repository at this point in the history
  • Loading branch information
Tieske committed Apr 2, 2024
1 parent 675a0c2 commit 64c2e8b
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 9 deletions.
32 changes: 25 additions & 7 deletions lua/pl/path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -493,17 +493,35 @@ end
-- In windows, if HOME isn't set, then USERPROFILE is used in preference to
-- HOMEDRIVE HOMEPATH. This is guaranteed to be writeable on all versions of Windows.
-- @string P A file path
-- @treturn[1] string The file path with the `~` prefix substituted, or the input path if it had no prefix.
-- @treturn[2] nil
-- @treturn[2] string Error message if the environment variables were unavailable.
function path.expanduser(P)
assert_string(1,P)
if at(P,1) == '~' then
local home = getenv('HOME')
if not home then -- has to be Windows
home = getenv 'USERPROFILE' or (getenv 'HOMEDRIVE' .. getenv 'HOMEPATH')
end
return home..sub(P,2)
else
if P:sub(1,1) ~= '~' then
return P
end

local home = getenv('HOME')
if (not home) and (not path.is_windows) then
-- no more options to try on Nix
return nil, "failed to expand '~' (HOME not set)"
end

if (not home) then
-- try alternatives on Windows
home = getenv 'USERPROFILE'
if not home then
local hd = getenv 'HOMEDRIVE'
local hp = getenv 'HOMEPATH'
if not (hd and hp) then
return nil, "failed to expand '~' (HOME, USERPROFILE, and HOMEDRIVE and/or HOMEPATH not set)"
end
home = hd..hp
end
end

return home..sub(P,2)
end


Expand Down
106 changes: 106 additions & 0 deletions spec/path_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

-- conditional it/pending blocks per platform
local function nix_it(desc, ...)
if package.path:sub(1,1) == "\\" then
pending("Skip test on Windows: " .. desc, ...)
else
it(desc, ...)
end
end
local function win_it(desc, ...)
if package.path:sub(1,1) == "\\" then
it(desc, ...)
else
pending("Skip test on Unix: " .. desc, ...)
end
end



describe("pl.path", function()

local path
local mock_envs
local old_get_env

before_each(function()
mock_envs = {}
old_get_env = os.getenv
os.getenv = function(name) -- luacheck: ignore
return mock_envs[name]
end
package.loaded["pl.path"] = nil
path = require "pl.path"
end)

after_each(function()
package.loaded["pl.path"] = nil
os.getenv = old_get_env -- luacheck: ignore
end)



describe("expanduser()", function()

it("should expand ~ to the user's home directory", function()
mock_envs = {
HOME = "/home/user",
}
assert.equal("/home/user/file", path.expanduser("~/file"))
end)


nix_it("returns an error if expansion fails: HOME not set", function()
mock_envs = {}
assert.same(
{ nil, "failed to expand '~' (HOME not set)" },
{ path.expanduser("~/file")}
)
end)


win_it("returns an error if expansion fails: all Windows vars", function()
mock_envs = {}
assert.same(
{ nil, "failed to expand '~' (HOME, USERPROFILE, and HOMEDRIVE and/or HOMEPATH not set)" },
{ path.expanduser("~/file")}
)
end)


win_it("HOME is first in line", function()
mock_envs = {
HOME = "\\home\\user1",
USERPROFILE = "\\home\\user2",
HOMEDRIVE = "C:",
HOMEPATH = "\\Users\\user3",
}
assert.equal("\\home\\user1\\file", path.expanduser("~\\file"))
end)


win_it("USERPROFILE is second in line", function()
mock_envs = {
--HOME = "\\home\\user1",
USERPROFILE = "\\home\\user2",
HOMEDRIVE = "C:",
HOMEPATH = "\\Users\\user3",
}
assert.equal("\\home\\user2\\file", path.expanduser("~\\file"))
end)


win_it("HOMEDRIVE/PATH is third in line", function()
mock_envs = {
-- HOME = "\\home\\user1",
-- USERPROFILE = "\\home\\user2",
HOMEDRIVE = "C:",
HOMEPATH = "\\Users\\user3",
}
assert.equal("\\home\\user3\\file", path.expanduser("~\\file"))
end)

end)

end)

2 changes: 0 additions & 2 deletions tests/test-path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,6 @@ do -- path.relpath
end


-- TODO: path.expanduser

-- TODO: path.tmpname


Expand Down

0 comments on commit 64c2e8b

Please sign in to comment.