feat(lib): use different tool_storage structure, chmod on unix

* Fix for tools which don't already provide zips with binaries that have
  their executable bit set, by executing chmod before attempting to run.
* Uses a different tool_storage structure to prevent changing the tool
  name and causing confusion for tools which change their help menu
  binary name based on the current exe name.
This commit is contained in:
Erica Marigold 2024-11-28 16:08:15 +00:00
parent a8042ced44
commit 8cf8d8e916

View file

@ -73,6 +73,22 @@ local function downloadAndDecompress(asset: {
end) :: Option<pathfs.Path> end) :: Option<pathfs.Path>
end end
-- NOTE: number must be an octal or a string mode
local function chmod(path: pathfs.Path, mode: number | string)
if process.os == "windows" then
return
end
local result = process.spawn(
"chmod",
{ if typeof(mode) == "string" then mode else string.format("%o", mode), path:toString() }
)
if not result.ok then
return error(result.stderr)
end
end
local function toolAliasOrDefault(tool: ToolId): string local function toolAliasOrDefault(tool: ToolId): string
return tool.alias:unwrapOr(string.split((tool :: ToolId).repo, "/")[2]) return tool.alias:unwrapOr(string.split((tool :: ToolId).repo, "/")[2])
end end
@ -201,6 +217,7 @@ function installTool(tool: ToolId, installPath: pathfs.Path)
-- Now we can use `path` to figure out the real tool to execute -- Now we can use `path` to figure out the real tool to execute
-- ... -- ...
]] ]]
chmod(installPath, 755)
runTool(installPath) runTool(installPath)
end end
@ -225,7 +242,7 @@ return setmetatable(
local ERROR_PREFIX = `{stdio.color("red")}{stdio.style("bold")}error{stdio.color("reset")}:` local ERROR_PREFIX = `{stdio.color("red")}{stdio.style("bold")}error{stdio.color("reset")}:`
local repo, version = string.match(tool, "([^@]+)@?(.*)") local repo, version = string.match(tool, "([^@]+)@?(.*)")
if repo == nil then if repo == nil or version == nil then
stdio.ewrite(`{ERROR_PREFIX} Invalid tool provided\n`) stdio.ewrite(`{ERROR_PREFIX} Invalid tool provided\n`)
return 1 return 1
end end
@ -251,11 +268,19 @@ return setmetatable(
return 0, manifest.version return 0, manifest.version
end end
local versionOrDefault = version
if versionOrDefault == "" then
local code, ver = manifestVersion()
if code ~= 0 then
return code
end
versionOrDefault = ver :: string
end
local toolId = string.gsub(repo :: string, "/", "+") local toolId = string.gsub(repo :: string, "/", "+")
local toolAlias = string.split(toolId, "+")[2] local toolAlias = string.split(toolId, "+")[2]
local toolInstallPath = TOOL_STORAGE_DIR:join(toolId):join( local toolInstallPath = TOOL_STORAGE_DIR:join(toolId):join(versionOrDefault):join(toolAlias)
`{toolAlias}-` .. if version ~= "" then version :: string else manifestVersion()
)
if pathfs.isFile(toolInstallPath) then if pathfs.isFile(toolInstallPath) then
return lib.runTool(toolInstallPath) return lib.runTool(toolInstallPath)