From 3e1876ad438b3d244aeeb02fdfdf95bb1583561f Mon Sep 17 00:00:00 2001 From: Luka <47296785+lukadev-0@users.noreply.github.com> Date: Thu, 16 Jan 2025 08:38:06 +0100 Subject: [PATCH] feat(lib): switch to `luau-unzip` (#3) * chore(bins): bump `asphalt` to v0.8.4 * chore(bins): bump `selene` to v0.28.0 * feat(lib): use luau-unzip * chore(CHANGELOG): add luau-unzip * chore: switch back to CRLF * fix(lib): extracting wrong binary * refactor(lib): use extractEntry function * refactor(lib): make checks explicit and add comments to zip decompressor * chore(lib): remove unused exec util * chore(CHANGELOG): remove trailing full-stop --------- Co-authored-by: Erica Marigold --- CHANGELOG.md | 2 + bins/argon/pesde.lock | 25 +++ bins/asphalt/pesde.lock | 27 +++- bins/asphalt/pesde.toml | 2 +- bins/blink/pesde.lock | 25 +++ bins/darklua/pesde.lock | 25 +++ bins/luau-lsp/pesde.lock | 25 +++ bins/rojo/pesde.lock | 25 +++ bins/selene/pesde.lock | 27 +++- bins/selene/pesde.toml | 2 +- bins/stylua/pesde.lock | 25 +++ bins/zap/pesde.lock | 25 +++ toolchainlib/pesde.lock | 24 +++ toolchainlib/pesde.toml | 1 + toolchainlib/src/compression.luau | 119 +++++++------- toolchainlib/src/init.luau | 56 +++---- toolchainlib/src/platform/descriptor.luau | 6 +- toolchainlib/src/utils/exec.luau | 186 ---------------------- 18 files changed, 343 insertions(+), 284 deletions(-) delete mode 100644 toolchainlib/src/utils/exec.luau diff --git a/CHANGELOG.md b/CHANGELOG.md index e7b355e..65eca94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Use [`luau-unzip`](https://github.com/0x5eal/luau-unzip) to extract archives instead of using an external program ## [0.1.7] - 2024-12-28 ### Added diff --git a/bins/argon/pesde.lock b/bins/argon/pesde.lock index ba15055..23e3819 100644 --- a/bins/argon/pesde.lock +++ b/bins/argon/pesde.lock @@ -2,6 +2,29 @@ name = "pesde/argon" version = "2.0.21" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/asphalt/pesde.lock b/bins/asphalt/pesde.lock index 5f82e05..fa3e515 100644 --- a/bins/asphalt/pesde.lock +++ b/bins/asphalt/pesde.lock @@ -1,7 +1,30 @@ name = "pesde/asphalt" -version = "0.8.3" +version = "0.8.4" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/asphalt/pesde.toml b/bins/asphalt/pesde.toml index 7e4ae46..387e1ef 100644 --- a/bins/asphalt/pesde.toml +++ b/bins/asphalt/pesde.toml @@ -1,5 +1,5 @@ name = "pesde/asphalt" -version = "0.8.3" +version = "0.8.4" description = "Upload and reference Roblox assets in code" authors = ["CompeyDev ", "Jack T "] repository = "https://github.com/pesde-pkg/tooling/tree/main/bins/asphalt" diff --git a/bins/blink/pesde.lock b/bins/blink/pesde.lock index 665e74b..0aa8888 100644 --- a/bins/blink/pesde.lock +++ b/bins/blink/pesde.lock @@ -2,6 +2,29 @@ name = "pesde/blink" version = "0.15.1" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/darklua/pesde.lock b/bins/darklua/pesde.lock index 059c0d0..b59b090 100644 --- a/bins/darklua/pesde.lock +++ b/bins/darklua/pesde.lock @@ -2,6 +2,29 @@ name = "pesde/darklua" version = "0.15.0" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/luau-lsp/pesde.lock b/bins/luau-lsp/pesde.lock index e1ed2f0..63f54b6 100644 --- a/bins/luau-lsp/pesde.lock +++ b/bins/luau-lsp/pesde.lock @@ -2,6 +2,29 @@ name = "pesde/luau_lsp" version = "1.38.1" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/rojo/pesde.lock b/bins/rojo/pesde.lock index 43e17c5..da45bb9 100644 --- a/bins/rojo/pesde.lock +++ b/bins/rojo/pesde.lock @@ -2,6 +2,29 @@ name = "pesde/rojo" version = "7.4.4" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/selene/pesde.lock b/bins/selene/pesde.lock index 23bf727..dca640e 100644 --- a/bins/selene/pesde.lock +++ b/bins/selene/pesde.lock @@ -1,7 +1,30 @@ name = "pesde/selene" -version = "0.27.1" +version = "0.28.0" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/selene/pesde.toml b/bins/selene/pesde.toml index 957b809..65759cc 100644 --- a/bins/selene/pesde.toml +++ b/bins/selene/pesde.toml @@ -1,5 +1,5 @@ name = "pesde/selene" -version = "0.27.1" +version = "0.28.0" description = "A blazing-fast modern Lua linter written in Rust" authors = ["CompeyDev ", "Kampfkarren "] repository = "https://github.com/pesde-pkg/tooling/tree/main/bins/selene" diff --git a/bins/stylua/pesde.lock b/bins/stylua/pesde.lock index 3ca23f2..d574ab1 100644 --- a/bins/stylua/pesde.lock +++ b/bins/stylua/pesde.lock @@ -2,6 +2,29 @@ name = "pesde/stylua" version = "2.0.2" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/bins/zap/pesde.lock b/bins/zap/pesde.lock index c2f7d58..9c653d2 100644 --- a/bins/zap/pesde.lock +++ b/bins/zap/pesde.lock @@ -2,6 +2,29 @@ name = "pesde/zap" version = "0.6.16" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] resolved_ty = "standard" @@ -87,6 +110,7 @@ environment = "lune" lib = "src/init.luau" [graph."pesde/toolchainlib"."0.1.7 lune".dependencies] +"0x5eal/unzip" = ["0.1.0 luau", "unzip"] "jiwonz/dirs" = ["0.1.2 lune", "dirs"] "jiwonz/pathfs" = ["0.1.0 lune", "pathfs"] "lukadev_0/option" = ["1.2.0 lune", "option"] @@ -101,6 +125,7 @@ dirs = [{ name = "jiwonz/dirs", version = "^0.1.1", index = "https://github.com/ option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] pathfs = [{ name = "jiwonz/pathfs", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index" }, "standard"] result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "peer"] +unzip = [{ name = "0x5eal/unzip", version = "^0.1.0", index = "https://github.com/daimond113/pesde-index", target = "luau" }, "standard"] [graph."pesde/toolchainlib"."0.1.7 lune".pkg_ref.target] environment = "lune" diff --git a/toolchainlib/pesde.lock b/toolchainlib/pesde.lock index 46538b7..b0401ef 100644 --- a/toolchainlib/pesde.lock +++ b/toolchainlib/pesde.lock @@ -2,6 +2,30 @@ name = "pesde/toolchainlib" version = "0.1.7" target = "lune" +[graph."0x5eal/unzip"."0.1.0 luau"] +direct = ["unzip", { name = "0x5eal/unzip", version = "^0.1.0", target = "luau" }, "standard"] +resolved_ty = "standard" + +[graph."0x5eal/unzip"."0.1.0 luau".target] +environment = "luau" +lib = "lib/init.luau" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref] +ref_ty = "pesde" +name = "0x5eal/unzip" +version = "0.1.0" +index_url = "https://github.com/daimond113/pesde-index" + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.dependencies] +asciitable = [{ name = "kimpure/asciitable", version = "^0.1.4", index = "https://github.com/pesde-pkg/index" }, "dev"] +frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +luau-lsp = [{ name = "pesde/luau_lsp", version = "^1.38.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] +stylua = [{ name = "pesde/stylua", version = "^2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"] + +[graph."0x5eal/unzip"."0.1.0 luau".pkg_ref.target] +environment = "luau" +lib = "lib/init.luau" + [graph."jiwonz/dirs"."0.1.2 lune"] direct = ["dirs", { name = "jiwonz/dirs", version = "^0.1.1" }, "standard"] resolved_ty = "standard" diff --git a/toolchainlib/pesde.toml b/toolchainlib/pesde.toml index cfca9ca..965a334 100644 --- a/toolchainlib/pesde.toml +++ b/toolchainlib/pesde.toml @@ -12,6 +12,7 @@ lib = "src/init.luau" [dependencies] pathfs = { name = "jiwonz/pathfs", version = "^0.1.0" } dirs = { name = "jiwonz/dirs", version = "^0.1.1" } +unzip = { name = "0x5eal/unzip", version = "^0.1.0", target = "luau" } [peer_dependencies] result = { name = "lukadev_0/result", version = "^1.2.0" } diff --git a/toolchainlib/src/compression.luau b/toolchainlib/src/compression.luau index 6d4ffd6..eac01d2 100644 --- a/toolchainlib/src/compression.luau +++ b/toolchainlib/src/compression.luau @@ -1,8 +1,4 @@ -local serde = require("@lune/serde") -local process = require("@lune/process") - -local dirs = require("../lune_packages/dirs") -local pathfs = require("../lune_packages/pathfs") +local unzip = require("../luau_packages/unzip") local Result = require("../lune_packages/result") local Option = require("../lune_packages/option") @@ -10,7 +6,8 @@ type Result = Result.Result type Option = Option.Option local revTable = require("./utils/rev_table") -local CommandBuilder = require("./utils/exec") +local eq = require("./utils/eq") +local PlatformDescriptor = require("./platform/descriptor") export type CompressionFormat = "TarGz" | "TarXz" | "Zip" @@ -36,70 +33,66 @@ local function detectFormat(fileName: string): Option end -- TODO: Use a type function to make all CompressionFormat lowercase -local decompress: { [CompressionFormat]: (compressed: buffer) -> Result } = { - Zip = function(compressed: buffer) - return (Option.from(dirs.cacheDir()):map(function(cacheDir) - local progCacheDir = cacheDir:join("pesde-bin") - if not pathfs.isDir(progCacheDir) then - pathfs.writeDir(progCacheDir) +local extractBinary: { + [CompressionFormat]: ( + compressed: buffer, + binaryName: string, + targetPlatform: PlatformDescriptor.PlatformDescriptor + ) -> Result, +} = + { + Zip = function(compressed, binaryName, targetPlatform) + -- Load the compressed data into a `ZipReader` + local reader = unzip.load(compressed) + local binaryContents: buffer? + + --- Extracts a specific entry from the ZIP and validates that its `PlatformDescriptor` + --- matches the expected one + local function extractEntry(entry: unzip.ZipEntry): buffer? + local contents = reader:extract(entry, { type = "binary" }) :: buffer + local executablePlatform = PlatformDescriptor.fromExecutable(contents) + + if executablePlatform:isOk() and eq(executablePlatform:unwrap(), targetPlatform) then + return contents + end end - return progCacheDir :: pathfs.Path - end)):match({ - Some = function(dir: pathfs.Path) - -- Generate a unique file name and write the contents to the temporary file - local tmpFile = dir:join(`{serde.hash("blake3", compressed)}.zip`) - local tmpFilePath = tmpFile:toString() - pathfs.writeFile(tmpFile, compressed) - -- Create the directory to decompress into - local decompressedDir = pathfs.Path.from(tmpFile):withExtension("") - pathfs.writeDir(decompressedDir) + -- Find the entry and attempt to extract it + local binaryEntry = reader:findEntry(binaryName) + if binaryEntry then + binaryContents = extractEntry(binaryEntry) + end - -- Run unzip to decompress the file - local child = (if process.os == "windows" - -- Thanks windows :) - then CommandBuilder.new("powershell"):withArgs({ - "-ExecutionPolicy RemoteSigned", - `-c \`"Import-Module Microsoft.PowerShell.Archive; Expand-Archive -LiteralPath '{tmpFilePath}' -DestinationPath '{decompressedDir:toString()}'\`"`, - }) - else CommandBuilder.new("unzip"):withArgs({ tmpFilePath, "-d", decompressedDir:toString() })) - :withStdioStrategy({ - -- Powershell on Windows writes errors to stdout. Bruh - stdout = Option.Some( - if process.os == "windows" and process.env.PESDE_LOG == "debug" - then "forward" - else "pipe" :: CommandBuilder.StdioStrategy - ), - stderr = Option.Some( - if process.env.PESDE_LOG == "debug" - then "forward" - else "pipe" :: CommandBuilder.StdioStrategy - ), - } :: CommandBuilder.IoStrategyMapping) - :intoChildProcess() + -- Fallback for if we cannot find the `ZipEntry` + if binaryContents == nil then + -- Walk through the entries to find an executable + reader:walk(function(entry) + if binaryContents ~= nil then + -- If we successfully extracted the binary on a previous iteration, + -- we skip this entry + return + end - child:start() - local status = child:waitForChild() + if entry.isDirectory then + -- Ignore directories + return + end - -- Cleanup temporary file and handle errors - pathfs.removeFile(tmpFile) - if not status.ok then - return Result.Err( - `DecompressError::CommandFailed(exitCode={status.code})` - ) :: Result - end + binaryContents = extractEntry(entry) + end) + end - return Result.Ok(decompressedDir) :: Result - end, + if binaryContents == nil then + -- If both the fallback and the initial attempts did not yield an extracted binary, + -- we return an error + return Result.Err("ExtractBinaryError::BinaryNotFound" :: string) + end - None = function() - return Result.Err("DecompressError::NoCacheDir") :: Result - end, - }) - end, + return Result.Ok(binaryContents) + end, - -- TODO: Other formats -} + -- TODO: Other formats + } -return { decompress = decompress, detectFormat = detectFormat } +return { extractBinary = extractBinary, detectFormat = detectFormat } diff --git a/toolchainlib/src/init.luau b/toolchainlib/src/init.luau index 681e99f..e84c576 100644 --- a/toolchainlib/src/init.luau +++ b/toolchainlib/src/init.luau @@ -45,12 +45,16 @@ local function warn(...) stdio.ewrite(`{WARN_PREFIX} {stdio.format(...)}\n`) end -local function downloadAndDecompress(asset: { - name: string, - browser_download_url: string, - size: number, - content_type: string, -}): Option +local function downloadAndExtractBinary( + binaryName: string, + targetPlatform: PlatformDescriptor.PlatformDescriptor, + asset: { + name: string, + browser_download_url: string, + size: number, + content_type: string, + } +): Option return compression .detectFormat(asset.name) :andThen(function(format: compression.CompressionFormat) @@ -59,8 +63,10 @@ local function downloadAndDecompress(asset: { return error(`Failed to download asset {asset.name}: HTTP Code {contentsResp.statusCode}`) end - return ResultExt.ok(compression.decompress[format](buffer.fromstring(contentsResp.body))) - end) :: Option + return ResultExt.ok( + compression.extractBinary[format](buffer.fromstring(contentsResp.body), binaryName, targetPlatform) + ) + end) :: Option end local function chmod(path: pathfs.Path, mode: number | string) @@ -195,6 +201,7 @@ function installTool(tool: ToolId, installPath: pathfs.Path): number local currentDesc = PlatformDescriptor.currentSystem() local aliasPath = pathfs.Path.from(toolAlias):withExtension(if currentDesc.os == "windows" then "exe" else "") + local aliasName = aliasPath:toString() for _, asset in assets do local desc = PlatformDescriptor.fromString(asset.name) @@ -210,33 +217,28 @@ function installTool(tool: ToolId, installPath: pathfs.Path): number barFns.next(bar) -- download - local binaryPath: pathfs.Path + local binaryContents: buffer if matchingAsset == nil then stdio.write("\x1b[2K\x1b[0G") warn("Pesde could not find a matching binary for your system") warn("Will now attempt to download all binaries and find a matching one") for _, asset in assets do - local decompressedPath = downloadAndDecompress(asset) - if decompressedPath:isSome() then - local path = decompressedPath:unwrap() - for _, file in pathfs.readDir(path) do - local filePath = path:join(file) - local nativeDesc = PlatformDescriptor.fromExecutable(filePath:toString()) - - if nativeDesc:isOk() and eq(currentDesc, nativeDesc:unwrap()) then - binaryPath = filePath - break - end - end + local contents = downloadAndExtractBinary(aliasName, currentDesc, asset) + if contents:isSome() then + binaryContents = contents:unwrap() + break end end else - local decompressedPath = downloadAndDecompress(matchingAsset):unwrap() - binaryPath = decompressedPath:join(aliasPath) - if not pathfs.isFile(binaryPath) then - error(`No matching binary found in {decompressedPath}`) - end + downloadAndExtractBinary(aliasName, currentDesc, matchingAsset):match({ + Some = function(contents: buffer) + binaryContents = contents + end, + None = function() + error(`No matching binary found`) + end, + }) end barFns.next(bar) -- install @@ -248,7 +250,7 @@ function installTool(tool: ToolId, installPath: pathfs.Path): number pathfs.writeDir(toolDir) end - pathfs.move(binaryPath, installPath) + pathfs.writeFile(installPath, binaryContents) -- IDEA: 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, diff --git a/toolchainlib/src/platform/descriptor.luau b/toolchainlib/src/platform/descriptor.luau index b35f9cb..6d4e4f0 100644 --- a/toolchainlib/src/platform/descriptor.luau +++ b/toolchainlib/src/platform/descriptor.luau @@ -1,5 +1,4 @@ local process = require("@lune/process") -local fs = require("@lune/fs") local os = require("./os") local arch = require("./arch") @@ -45,9 +44,8 @@ function PlatformDescriptor.fromString(str: string) } :: PlatformDescriptor) end -function PlatformDescriptor.fromExecutable(path: string): result.PlatformResult - local binaryContents = fs.readFile(path) - local detected = Option.from(detectFromExecutable(buffer.fromstring(binaryContents))) +function PlatformDescriptor.fromExecutable(contents: buffer): result.PlatformResult + local detected = Option.from(detectFromExecutable(contents)) :map(function(inner: detectFromExecutable.ExecutableDetectionResult): ExecutableDetectionResult return { os = Option.from(inner.os) :: Option, diff --git a/toolchainlib/src/utils/exec.luau b/toolchainlib/src/utils/exec.luau deleted file mode 100644 index 308ae2d..0000000 --- a/toolchainlib/src/utils/exec.luau +++ /dev/null @@ -1,186 +0,0 @@ ---> Builder pattern class to spawn, manage and kill child processes - -local process = require("@lune/process") -local task = require("@lune/task") - -local Option = require("../../lune_packages/option") -type Option = Option.Option - -local CommandBuilder = {} -type CommandBuilderFields = { - program: string, - args: { string }, - retries: Option, - ignoreErrors: Option, - stdioStrategy: Option, -} -export type CommandBuilder = typeof(setmetatable({} :: CommandBuilderFields, { __index = CommandBuilder })) -export type StdioStrategy = "pipe" | "forward" | "none" -export type IoStrategyMapping = { - stdout: Option, - stderr: Option, -} -export type ChildProcess = { - _thread: thread, - _pid: string, - _status: ChildStatus, - start: (self: ChildProcess) -> (), - waitForChild: (self: ChildProcess) -> ChildStatus, - kill: (self: ChildProcess) -> (), -} -export type ChildStatus = { ok: boolean, code: number, io: { - stdout: string, - stderr: string, -} } - -local DEFAULT_STDIO_STRATEGY: IoStrategyMapping = { - stdout = Option.Some("pipe" :: StdioStrategy), - stderr = Option.Some("pipe" :: StdioStrategy), -} -local DEFAULT_RETRIES = 0 -local DEFAULT_IGNORE_ERRORS = false - -function CommandBuilder.new(program: string) - return setmetatable( - { - program = program, - args = {}, - retries = Option.None, - ignoreErrors = Option.None, - stdioStrategy = Option.None :: Option, - } :: CommandBuilderFields, - { - __index = CommandBuilder, - } - ) -end - -function CommandBuilder.withArg(self: CommandBuilder, arg: string): CommandBuilder - table.insert(self.args, arg) - return self -end - -function CommandBuilder.withArgs(self: CommandBuilder, args: { string }): CommandBuilder - for _, arg in args do - self:withArg(arg) - end - - return self -end - -function CommandBuilder.withMaxRetries(self: CommandBuilder, retries: number): CommandBuilder - self.retries = Option.Some(retries) :: Option - return self -end - -function CommandBuilder.withIgnoreErrors(self: CommandBuilder, yes: boolean): CommandBuilder - self.ignoreErrors = Option.Some(yes) :: Option - return self -end - -function CommandBuilder.withStdioStrategy( - self: CommandBuilder, - strategy: StdioStrategy | IoStrategyMapping -): CommandBuilder - self.stdioStrategy = Option.Some(if typeof(strategy) == "string" - then { - stdout = Option.Some(strategy), - stderr = Option.Some(strategy), - } - else strategy) :: Option - return self -end - -local function intoSpawnOptionsStdioKind(strategy: StdioStrategy): process.SpawnOptionsStdioKind - if strategy == "pipe" then - return "default" - end - - if strategy == "forward" then - return "forward" - end - - if strategy == "none" then - return "none" - end - - error(`Non-strategy provided: {strategy}`) -end - -function CommandBuilder.intoChildProcess(self: CommandBuilder): ChildProcess - local child = { - _thread = coroutine.create(function(this: ChildProcess) - local retries = self.retries:unwrapOr(DEFAULT_RETRIES) - local ignoreErrors = self.ignoreErrors:unwrapOr(DEFAULT_IGNORE_ERRORS) - local argsList = table.concat(self.args, " ") - - for _ = 0, retries do - local spawned = process.spawn( - if process.os == "windows" - then `(Start-Process {self.program} -Passthru -Wait -NoNewWindow -ArgumentList \"{argsList}\").Id` - else `{self.program} {argsList} & echo $!`, - {}, - { - stdio = self.stdioStrategy - :orOpt(Option.Some(DEFAULT_STDIO_STRATEGY)) - :map(function(mappings: IoStrategyMapping) - local translatedMappings: process.SpawnOptionsStdio = {} - for field, value in mappings do - translatedMappings[field] = - intoSpawnOptionsStdioKind((value :: Option):unwrap()) - end - - return translatedMappings - end) - :unwrap(), - shell = true, - } - ) - - if spawned.ok then - local lines = spawned.stdout:split("\n") - - -- TODO: Abstract upvalues here into a channels primitive - this._pid = assert(table.remove(lines, 1), "Failed to get PID") - this._status = { - code = spawned.code, - ok = spawned.code == 0 and not ignoreErrors, - io = { - stdout = table.concat(lines, "\n"), - stderr = spawned.stderr, - }, - } - break - end - end - end), - - start = function(self: ChildProcess) - coroutine.resume(self._thread, self) - end, - - waitForChild = function(self: ChildProcess): ChildStatus - while coroutine.status(self._thread) ~= "dead" or self._status == nil do - task.wait(0.1) - end - - return self._status - end, - - kill = function(self: ChildProcess) - coroutine.close(self._thread) - local killResult = process.spawn( - if process.os == "windows" then `Stop-Process -Id {self._pid} -Force` else `kill {self._pid}`, - { - shell = true, - } - ) - - assert(killResult.ok, `Failed to kill process with PID {self._pid}`) - end, - } :: ChildProcess - - return child -end - -return CommandBuilder