feat: use lune linker scripts for binaries

This commit is contained in:
Erica Marigold 2024-11-23 12:51:22 +00:00
parent 42c64c0c51
commit 7e78d73854
5 changed files with 124 additions and 54 deletions

2
.gitignore vendored
View file

@ -1,3 +1,3 @@
lune_packages/
luau_packages/
# core/pesde.lock
core/pesde.lock

View file

@ -63,49 +63,41 @@ local function downloadAndDecompress(asset: {
return decompressedPath
end
local function runTool(path: pathfs.Path)
-- TODO: Fixup our wrapper and use that instead in the future
process.spawn(path:toString(), process.args, {
stdio = "forward",
shell = true,
})
local function chmod(path: pathfs.Path, mode: number)
if process.os ~= "windows" then
local child = process.spawn("chmod", { string.format("%o", mode), path:toString() })
if not child.ok then
error(`chmod failed: {path} - {child.stderr}`)
end
end
end
local TOOL_INSTALL_DIR = (dirs.homeDir() or error("Couldn't get home dir :("))
:join(".pesde")
:join("bin")
:join("tool_storage")
local function toolAliasOrDefault(tool: ToolId): string
return tool.alias:unwrapOr(string.split((tool :: ToolId).repo, "/")[2])
end
-- if not pathfs.isDir(TOOL_INSTALL_DIR) then
-- pathfs.writeDir(TOOL_INSTALL_DIR)
-- end
local LINK_INSTALL_DIR = (dirs.homeDir() or error("Couldn't get home dir :(")):join(".pesde"):join("bin")
local TOOL_STORAGE_DIR = LINK_INSTALL_DIR:join("tool_storage")
function runTool(tool: ToolId | pathfs.Path): number
-- FIXME: `process.spawn` has a bug where interactive features don't
-- forward properly
local toolId = tool :: ToolId
local path = if toolId.alias ~= nil then LINK_INSTALL_DIR:join(toolAliasOrDefault(toolId)) else tool :: pathfs.Path
return process.spawn(path:toString(), process.args, {
cwd = process.cwd,
env = process.env,
stdio = "forward",
}).code
end
function installTool(tool: ToolId)
local toolAlias = tool.alias:unwrapOr(string.split(tool.repo, "/")[2])
local toolAlias = toolAliasOrDefault(tool)
local toolId = string.gsub(tool.repo, "/", "+")
local toolInstallPath = TOOL_INSTALL_DIR:join(toolId)
local toolInstallPath = TOOL_STORAGE_DIR:join(toolId)
:join(`{toolAlias}-` .. tostring(tool.version:map(tostring):unwrapOr("latest")))
-- TODO: In order to eliminate fs read overhead on startup and to disallow
-- the use of the tool binary when outside a package where it is installed,
-- we can improve this by following what rokit does, where we symlink
-- the tool's path to this script, and check the file that we are being
-- invoked as, in order to figure out what tool to execute
-- We can create "linker" scripts for each tool at ~/.pesde/bins with
-- contents like so:
--[[
#!/bin/env -S lune run
-- First off, we check whether the tool is installed in pesde.toml
-- if we're being run as a symlink, and not a `pesde x` bin
local pathInfo = debug.info(1, "s")
local path = string.sub(pathInfo, 10, #pathInfo - 2))
-- Now we can use `path` to figure out the real tool to execute
-- ...
]]
if pathfs.isFile(toolInstallPath) then
runTool(toolInstallPath)
return
@ -187,10 +179,85 @@ function installTool(tool: ToolId)
end
pathfs.move(binaryPath, toolInstallPath)
runTool(toolInstallPath)
-- In order to eliminate fs read overhead on startup and to disallow
-- the use of the tool binary when outside a package where it is installed,
-- we can improve this by following what rokit does, where we symlink
-- the tool's path to this script, and check the file that we are being
-- invoked as, in order to figure out what tool to execute
-- We can create "linker" scripts for each tool at ~/.pesde/bins with
-- contents like so:
--[[
#!/bin/env -S lune run
-- First off, we check whether the tool is installed in pesde.toml
-- if we're being run as a symlink, and not a `pesde x` bin
local pathInfo = debug.info(1, "s")
local path = string.sub(pathInfo, 10, #pathInfo - 2))
-- Now we can use `path` to figure out the real tool to execute
-- ...
]]
local linkPath = LINK_INSTALL_DIR:join(toolAlias)
pathfs.writeFile(
linkPath,
string.format(
[[#!/bin/env -S lune run
local serde = require("@lune/serde")
local process = require("@lune/process")
local fs = require("@lune/fs")
local TOOL_NAME = "%s"
--TOOL_PATH_BEGIN--
local TOOL_PATH = "%s"
--TOOL_PATH_END--
local IS_DEV = true
local PLATFORM_SEP = if process.platform == "windows" then "\\" else "/"
-- TODO: Check whether we are being run as `pesde x` and skip this check
-- That would involve getting the file path like this, probably:
local selfPathInfo = debug.info(1, "s")
local selfPath = string.sub(selfPathInfo, 10, #selfPathInfo - 2)
-- FIXME: Does the CWD have a trailing slash on all platforms?
local manifestContents = fs.readFile(`{process.cwd}{PLATFORM_SEP}pesde.toml`)
local ok, manifest = pcall(serde.decode, "toml", manifestContents)
if not ok then
error(`Failed to parse pesde.toml: {tostring(manifest)}`)
end
local isInstalled = IS_DEV
if manifest.dev_dependencies ~= nil then
for package, _ in manifest.dev_dependencies do
if package == TOOL_NAME then
isInstalled = true
break
end
end
end
if not isInstalled then
error(`Tool {TOOL_NAME} in any pesde manifest file!`)
end
process.exit(process.spawn(TOOL_PATH, process.args, {
stdio = "forward",
cwd = process.cwd,
env = process.env,
}).code)]],
string.split(toolId, "+")[2],
toolInstallPath:toString()
)
)
chmod(linkPath, 0b111101101)
end
return {
installTool = installTool,
runTool = runTool,
installTool = installTool,
}

View file

@ -3,7 +3,7 @@ local Semver = require("./luau_packages/semver")
local Option = require("./lune_packages/option")
type Option<T> = Option.Option<T>
-- TODO: Use _G._PESDE_ROOT to get the install directory, then decode the
-- TODO: Use _G.PESDE_ROOT to get the install directory, then decode the
-- pesde manifest to get the version of the tool dynamically
core.installTool({
alias = Option.Some("lune"),

View file

@ -1,10 +1,10 @@
name = "compeydev/lune"
version = "0.1.0"
version = "0.8.9"
target = "lune"
[graph."0x5eal/semver"."0.1.1 luau"]
direct = ["semver", { name = "0x5eal/semver", version = "^0.1.1", target = "luau" }]
ty = "standard"
direct = ["semver", { name = "0x5eal/semver", version = "^0.1.1", target = "luau" }, "standard"]
resolved_ty = "standard"
[graph."0x5eal/semver"."0.1.1 luau".target]
environment = "luau"
@ -30,8 +30,8 @@ environment = "luau"
lib = "lib/init.luau"
[graph."compeydev/binlib"."0.1.0 lune"]
direct = ["core", { workspace = "compeydev/binlib", version = "^" }]
ty = "standard"
direct = ["core", { workspace = "compeydev/binlib", version = "^" }, "standard"]
resolved_ty = "standard"
[graph."compeydev/binlib"."0.1.0 lune".target]
environment = "lune"
@ -60,7 +60,7 @@ environment = "lune"
lib = "src/init.luau"
[graph."jiwonz/dirs"."0.1.2 lune"]
ty = "standard"
resolved_ty = "standard"
[graph."jiwonz/dirs"."0.1.2 lune".target]
environment = "lune"
@ -83,7 +83,7 @@ environment = "lune"
lib = "src/init.luau"
[graph."jiwonz/pathfs"."0.1.0 lune"]
ty = "standard"
resolved_ty = "standard"
[graph."jiwonz/pathfs"."0.1.0 lune".target]
environment = "lune"
@ -100,8 +100,8 @@ environment = "lune"
lib = "init.luau"
[graph."lukadev_0/option"."1.2.0 lune"]
direct = ["option", { name = "lukadev_0/option", version = "^1.2.0" }]
ty = "standard"
direct = ["option", { name = "lukadev_0/option", version = "^1.2.0" }, "standard"]
resolved_ty = "standard"
[graph."lukadev_0/option"."1.2.0 lune".target]
environment = "lune"
@ -118,7 +118,7 @@ environment = "lune"
lib = "lib/init.luau"
[graph."lukadev_0/option"."1.2.0 luau"]
ty = "peer"
resolved_ty = "peer"
[graph."lukadev_0/option"."1.2.0 luau".target]
environment = "luau"
@ -135,8 +135,8 @@ environment = "luau"
lib = "lib/init.luau"
[graph."lukadev_0/result"."1.2.0 lune"]
direct = ["result", { name = "lukadev_0/result", version = "^1.2.0" }]
ty = "standard"
direct = ["result", { name = "lukadev_0/result", version = "^1.2.0" }, "standard"]
resolved_ty = "standard"
[graph."lukadev_0/result"."1.2.0 lune".target]
environment = "lune"
@ -153,7 +153,7 @@ environment = "lune"
lib = "lib/init.luau"
[graph."lukadev_0/result"."1.2.0 luau"]
ty = "peer"
resolved_ty = "peer"
[graph."lukadev_0/result"."1.2.0 luau".target]
environment = "luau"

View file

@ -1,7 +1,10 @@
name = "compeydev/lune"
version = "0.1.0"
version = "0.8.9"
description = "A standalone Luau runtime"
authors = ["CompeyDev <hi@devcomp.xyz>", "Filip Tibell <filip.tibell@gmail.com>"]
authors = [
"CompeyDev <hi@devcomp.xyz>",
"Filip Tibell <filip.tibell@gmail.com>",
]
repository = "https://github.com/CompeyDev/pesde-tooling/blob/main/lune"
license = "MIT"