From 344bb5edcd28d580b9d7c7724d216744862e4e96 Mon Sep 17 00:00:00 2001 From: Gautier Ben Aim Date: Wed, 28 Jan 2026 23:26:28 +0100 Subject: [PATCH 1/4] feat: support yarn 6+ --- hooks/available.lua | 21 +++++++++ hooks/post_install.lua | 102 +++++++++++++++++++++++++++++++++++------ 2 files changed, 108 insertions(+), 15 deletions(-) diff --git a/hooks/available.lua b/hooks/available.lua index a75f25a..9056f3b 100644 --- a/hooks/available.lua +++ b/hooks/available.lua @@ -65,6 +65,27 @@ end function PLUGIN:Available(ctx) local versions = {} + + -- Get Yarn ZPM versions (v6.x+) + local zpm_tags = fetch_github_tags("https://github.com/yarnpkg/zpm.git") + local zpm_versions = {} + for _, tag in ipairs(zpm_tags) do + -- ZPM versions are prefixed with 'v' + local version = tag:match("^v(.+)$") + if version then + table.insert(zpm_versions, version) + end + end + + -- Sort ZPM versions in descending order + table.sort(zpm_versions, version_compare) + + -- Add ZPM versions to the list + for _, version in ipairs(zpm_versions) do + table.insert(versions, { + version = version + }) + end -- Get Yarn Berry versions (v2.x+) local berry_tags = fetch_github_tags("https://github.com/yarnpkg/berry.git") diff --git a/hooks/post_install.lua b/hooks/post_install.lua index 425efdb..71b81ea 100644 --- a/hooks/post_install.lua +++ b/hooks/post_install.lua @@ -22,17 +22,48 @@ local function download_file(url, output_path) return false end +local function get_target_platform() + -- Detect platform and architecture for Yarn v6+ binary downloads + local is_windows = package.config:sub(1,1) == '\\' + + if is_windows then + -- Windows detection + local arch = os.getenv("PROCESSOR_ARCHITECTURE") or "x86_64" + if arch:match("ARM64") then + return "aarch64-pc-windows-gnu" + else + return "x86_64-pc-windows-gnu" + end + else + -- Unix-like systems (Linux, macOS, etc.) + local handle = io.popen("uname -ms 2>/dev/null") + local result = handle and handle:read("*a") or "" + if handle then handle:close() end + + if result:match("Darwin arm64") or result:match("Darwin aarch64") then + return "aarch64-apple-darwin" + elseif result:match("Darwin") then + return "x86_64-apple-darwin" + elseif result:match("Linux aarch64") or result:match("Linux arm64") then + return "aarch64-unknown-linux-musl" + else + -- Default to x86_64 Linux + return "x86_64-unknown-linux-musl" + end + end +end + function PLUGIN:PostInstall(ctx) -- Get install path - it should be in sdkInfo local install_path = nil local version = nil - + -- Try to get path from sdkInfo if ctx.sdkInfo and ctx.sdkInfo.yarn then install_path = ctx.sdkInfo.yarn.path version = ctx.sdkInfo.yarn.version end - + -- Fallback to environment variable if not install_path then install_path = os.getenv("MISE_INSTALL_PATH") @@ -40,21 +71,62 @@ function PLUGIN:PostInstall(ctx) if not version then version = os.getenv("MISE_INSTALL_VERSION") or ctx.version end - + if not install_path or not version then -- For v1, mise handles everything, so this is OK return {} end - + local major_version = string.sub(version, 1, 1) - - if major_version ~= "1" then + local is_windows = package.config:sub(1,1) == '\\' + + if major_version == "6" or (tonumber(major_version) and tonumber(major_version) >= 6) then + -- Yarn ZPM (v6+) - download pre-compiled Rust binary + local target = get_target_platform() + local yarn_url = "https://repo.yarnpkg.com/releases/" .. version .. "/" .. target + + -- Create bin directory (cross-platform) + local bin_dir = install_path .. "/bin" + if is_windows then + os.execute('mkdir "' .. bin_dir .. '" 2>NUL') + else + os.execute("mkdir -p " .. bin_dir) + end + + -- Download and extract the binary + local archive_path = bin_dir .. "/yarn.zip" + if not download_file(yarn_url, archive_path) then + error("Failed to download Yarn v6+ from " .. yarn_url) + end + + -- Extract the zip file + if is_windows then + -- Use PowerShell to extract zip on Windows + local ps_cmd = 'powershell -Command "Expand-Archive -Path ' .. archive_path .. ' -DestinationPath ' .. bin_dir .. ' -Force" 2>NUL' + if not exec_success(os.execute(ps_cmd)) then + -- Fallback to unzip if available + os.execute("cd " .. bin_dir .. " && unzip -q yarn.zip 2>NUL") + end + else + -- Use unzip on Unix-like systems + os.execute("unzip -q " .. archive_path .. " -d " .. bin_dir) + end + + -- Clean up archive + if is_windows then + os.execute('del "' .. archive_path .. '" 2>NUL') + else + os.execute("rm -f " .. archive_path) + end + + -- Make the binary executable on Unix-like systems + if not is_windows then + os.execute("chmod +x " .. bin_dir .. "/yarn") + end + elseif major_version ~= "1" then -- Yarn Berry (v2.x+) - download single JS file local yarn_url = "https://repo.yarnpkg.com/" .. version .. "/packages/yarnpkg-cli/bin/yarn.js" - - -- Detect Windows - local is_windows = package.config:sub(1,1) == '\\' - + -- Create bin directory (cross-platform) local bin_dir = install_path .. "/bin" if is_windows then @@ -62,13 +134,13 @@ function PLUGIN:PostInstall(ctx) else os.execute("mkdir -p " .. bin_dir) end - + -- Download yarn.js local yarn_js_file = bin_dir .. "/yarn.js" if not download_file(yarn_url, yarn_js_file) then error("Failed to download Yarn v2+") end - + -- Create wrapper script if is_windows then -- Create yarn.cmd wrapper for Windows @@ -79,7 +151,7 @@ function PLUGIN:PostInstall(ctx) cmd_file:write('node "%~dp0yarn.js" %*\n') cmd_file:close() end - + -- Also create yarn without extension for Git Bash local yarn_sh = bin_dir .. "/yarn" local sh_file = io.open(yarn_sh, "w") @@ -101,8 +173,8 @@ function PLUGIN:PostInstall(ctx) os.execute("chmod +x " .. yarn_file) end end - + return {} end -return PLUGIN \ No newline at end of file +return PLUGIN From 5553c01bca888c326459b43c8a8421778b2b2691 Mon Sep 17 00:00:00 2001 From: Gautier Ben Aim Date: Wed, 28 Jan 2026 23:56:47 +0100 Subject: [PATCH 2/4] saner code --- hooks/post_install.lua | 94 +++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 57 deletions(-) diff --git a/hooks/post_install.lua b/hooks/post_install.lua index 71b81ea..15429c7 100644 --- a/hooks/post_install.lua +++ b/hooks/post_install.lua @@ -7,7 +7,7 @@ end local function download_file(url, output_path) -- Detect Windows - local is_windows = package.config:sub(1,1) == '\\' + local is_windows = package.config:sub(1, 1) == '\\' local stderr_redirect = is_windows and " 2>NUL" or " 2>/dev/null" -- Try curl first (more likely to be available on Windows via Git Bash) @@ -24,16 +24,12 @@ end local function get_target_platform() -- Detect platform and architecture for Yarn v6+ binary downloads - local is_windows = package.config:sub(1,1) == '\\' + -- Available targets: aarch64-apple-darwin, aarch64-unknown-linux-musl, + -- i686-unknown-linux-musl, x86_64-unknown-linux-musl + local is_windows = package.config:sub(1, 1) == '\\' if is_windows then - -- Windows detection - local arch = os.getenv("PROCESSOR_ARCHITECTURE") or "x86_64" - if arch:match("ARM64") then - return "aarch64-pc-windows-gnu" - else - return "x86_64-pc-windows-gnu" - end + error("Yarn v6+ does not support Windows binaries at this time.") else -- Unix-like systems (Linux, macOS, etc.) local handle = io.popen("uname -ms 2>/dev/null") @@ -43,12 +39,17 @@ local function get_target_platform() if result:match("Darwin arm64") or result:match("Darwin aarch64") then return "aarch64-apple-darwin" elseif result:match("Darwin") then - return "x86_64-apple-darwin" + -- Intel macOS is not supported in Yarn v6+ + error("Yarn v6+ only supports ARM64 (Apple Silicon) macOS. Your system is x86_64 Intel.") elseif result:match("Linux aarch64") or result:match("Linux arm64") then return "aarch64-unknown-linux-musl" - else - -- Default to x86_64 Linux + elseif result:match("Linux i686") or result:match("Linux i386") then + return "i686-unknown-linux-musl" + elseif result:match("Linux") then + -- Default to x86_64 for Linux if not explicitly detected as 32-bit return "x86_64-unknown-linux-musl" + else + error("Unsupported platform: " .. result) end end end @@ -78,52 +79,9 @@ function PLUGIN:PostInstall(ctx) end local major_version = string.sub(version, 1, 1) - local is_windows = package.config:sub(1,1) == '\\' - - if major_version == "6" or (tonumber(major_version) and tonumber(major_version) >= 6) then - -- Yarn ZPM (v6+) - download pre-compiled Rust binary - local target = get_target_platform() - local yarn_url = "https://repo.yarnpkg.com/releases/" .. version .. "/" .. target - - -- Create bin directory (cross-platform) - local bin_dir = install_path .. "/bin" - if is_windows then - os.execute('mkdir "' .. bin_dir .. '" 2>NUL') - else - os.execute("mkdir -p " .. bin_dir) - end - - -- Download and extract the binary - local archive_path = bin_dir .. "/yarn.zip" - if not download_file(yarn_url, archive_path) then - error("Failed to download Yarn v6+ from " .. yarn_url) - end - - -- Extract the zip file - if is_windows then - -- Use PowerShell to extract zip on Windows - local ps_cmd = 'powershell -Command "Expand-Archive -Path ' .. archive_path .. ' -DestinationPath ' .. bin_dir .. ' -Force" 2>NUL' - if not exec_success(os.execute(ps_cmd)) then - -- Fallback to unzip if available - os.execute("cd " .. bin_dir .. " && unzip -q yarn.zip 2>NUL") - end - else - -- Use unzip on Unix-like systems - os.execute("unzip -q " .. archive_path .. " -d " .. bin_dir) - end + local is_windows = package.config:sub(1, 1) == '\\' - -- Clean up archive - if is_windows then - os.execute('del "' .. archive_path .. '" 2>NUL') - else - os.execute("rm -f " .. archive_path) - end - - -- Make the binary executable on Unix-like systems - if not is_windows then - os.execute("chmod +x " .. bin_dir .. "/yarn") - end - elseif major_version ~= "1" then + if major_version == "2" or major_version == "3" or major_version == "4" or major_version == "5" then -- Yarn Berry (v2.x+) - download single JS file local yarn_url = "https://repo.yarnpkg.com/" .. version .. "/packages/yarnpkg-cli/bin/yarn.js" @@ -172,6 +130,28 @@ function PLUGIN:PostInstall(ctx) -- Make executable os.execute("chmod +x " .. yarn_file) end + elseif major_version ~= "1" then + -- Yarn ZPM (v6+) - download pre-compiled Rust binary from NPM + local target = get_target_platform() + local npm_url = "https://registry.npmjs.org/@yarnpkg/yarn-" .. + target .. "/-/yarn-" .. target .. "-" .. version .. ".tgz" + + -- Create bin directory + local bin_dir = install_path .. "/bin" + os.execute("mkdir -p " .. bin_dir) + + -- Download the binary tarball + local archive_path = bin_dir .. "/yarn.tar.gz" + if not download_file(npm_url, archive_path) then + error("Failed to download Yarn " .. version .. " from npm (" .. npm_url .. ")") + end + + -- Extract the tar.gz file + if not exec_success(os.execute("tar -xzf " .. archive_path .. " -C " .. bin_dir)) then + error("Failed to extract Yarn binary. Ensure tar is installed.") + end + + os.execute("rm -f " .. archive_path) end return {} From f72b7a4d1bfd49195ff7a331046996bad0d9297c Mon Sep 17 00:00:00 2001 From: Gautier Ben Aim Date: Thu, 29 Jan 2026 00:02:25 +0100 Subject: [PATCH 3/4] more logs --- hooks/post_install.lua | 46 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/hooks/post_install.lua b/hooks/post_install.lua index 15429c7..309fe10 100644 --- a/hooks/post_install.lua +++ b/hooks/post_install.lua @@ -134,13 +134,13 @@ function PLUGIN:PostInstall(ctx) -- Yarn ZPM (v6+) - download pre-compiled Rust binary from NPM local target = get_target_platform() local npm_url = "https://registry.npmjs.org/@yarnpkg/yarn-" .. - target .. "/-/yarn-" .. target .. "-" .. version .. ".tgz" + target .. "/-/yarn-" .. target .. "-" .. version .. ".tgz" -- Create bin directory local bin_dir = install_path .. "/bin" os.execute("mkdir -p " .. bin_dir) - -- Download the binary tarball + -- Download the binary (tar.gz from NPM or repo) local archive_path = bin_dir .. "/yarn.tar.gz" if not download_file(npm_url, archive_path) then error("Failed to download Yarn " .. version .. " from npm (" .. npm_url .. ")") @@ -152,6 +152,48 @@ function PLUGIN:PostInstall(ctx) end os.execute("rm -f " .. archive_path) + + -- NPM package structure: package/bin/yarn + -- Repo structure: {binary} in root + -- Handle both cases by finding and moving the yarn binary + local yarn_binary = bin_dir .. "/yarn" + local found_binary = false + + -- Check for NPM package structure (package/bin/yarn-bin) + if not is_windows then + local npm_path = bin_dir .. "/package/bin/yarn" + local check_npm = "test -f " .. npm_path + if exec_success(os.execute(check_npm)) then + os.execute("mv " .. npm_path .. " " .. yarn_binary) + os.execute("rm -rf " .. bin_dir .. "/package") + found_binary = true + end + end + + -- Check for direct binary + if not is_windows and not found_binary then + local check_cmd = "test -f " .. yarn_binary + if exec_success(os.execute(check_cmd)) then + found_binary = true + end + elseif is_windows then + -- On Windows, binary might be yarn.exe + local yarn_exe = bin_dir .. "/yarn.exe" + if exec_success(os.execute('test -f "' .. yarn_exe .. '" 2>NUL')) then + found_binary = true + end + end + + -- Verify binary exists before making it executable + if not is_windows then + if found_binary then + os.execute("chmod +x " .. yarn_binary) + else + error("Yarn binary not found at " .. yarn_binary .. " after extraction") + end + elseif not found_binary then + error("Yarn binary not found after extraction") + end end return {} From 635828ddcc16b38acf58eb62fc376fe6a7523876 Mon Sep 17 00:00:00 2001 From: Gautier Ben Aim Date: Thu, 29 Jan 2026 00:08:16 +0100 Subject: [PATCH 4/4] wip --- hooks/post_install.lua | 46 +++--------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/hooks/post_install.lua b/hooks/post_install.lua index 309fe10..5b714e6 100644 --- a/hooks/post_install.lua +++ b/hooks/post_install.lua @@ -151,49 +151,9 @@ function PLUGIN:PostInstall(ctx) error("Failed to extract Yarn binary. Ensure tar is installed.") end - os.execute("rm -f " .. archive_path) - - -- NPM package structure: package/bin/yarn - -- Repo structure: {binary} in root - -- Handle both cases by finding and moving the yarn binary - local yarn_binary = bin_dir .. "/yarn" - local found_binary = false - - -- Check for NPM package structure (package/bin/yarn-bin) - if not is_windows then - local npm_path = bin_dir .. "/package/bin/yarn" - local check_npm = "test -f " .. npm_path - if exec_success(os.execute(check_npm)) then - os.execute("mv " .. npm_path .. " " .. yarn_binary) - os.execute("rm -rf " .. bin_dir .. "/package") - found_binary = true - end - end - - -- Check for direct binary - if not is_windows and not found_binary then - local check_cmd = "test -f " .. yarn_binary - if exec_success(os.execute(check_cmd)) then - found_binary = true - end - elseif is_windows then - -- On Windows, binary might be yarn.exe - local yarn_exe = bin_dir .. "/yarn.exe" - if exec_success(os.execute('test -f "' .. yarn_exe .. '" 2>NUL')) then - found_binary = true - end - end - - -- Verify binary exists before making it executable - if not is_windows then - if found_binary then - os.execute("chmod +x " .. yarn_binary) - else - error("Yarn binary not found at " .. yarn_binary .. " after extraction") - end - elseif not found_binary then - error("Yarn binary not found after extraction") - end + -- Move /package/yarn to /bin/yarn and clean up + os.execute("mv " .. bin_dir .. "/package/yarn " .. bin_dir .. "/yarn") + os.execute("rm -rf " .. bin_dir .. "/package " .. archive_path) end return {}