// Name: Install with Homebrew // Description: Install a package using Homebrew // Author: Nickolas Høyer-Larsen // Version: 1.0 import { exec as execRaw } from "node:child_process"; import { promisify } from "node:util"; import "@johnlindquist/kit"; const exec = promisify(execRaw); type InfoType = { name?: string; description?: string; version?: string; fromUrl?: string; projectUrl?: string; analytics?: string; artifacts?: string; installed?: boolean; }; const extractExtraDetails = (input) => ({ version: (input.match(/==> [\w\s]+: ([\d.]+)/i) || [null])[1] || null, fromUrl: (input.match(/From: (https?:\/\/[^\s]+)/i) || [null])[1] || null, projectUrl: (input.match(/https?:\/\/[^\s]+/i) || [])[0] || null, installed: !input.includes("Not installed") }); function parseToJSON(input): InfoType { const result = input.split("\n").reduce((acc, line) => { if (line.startsWith("==>")) { acc.currentKey = line.replace("==>", "").trim().toLowerCase(); acc[acc.currentKey] = ""; } else if (acc.currentKey) { acc[acc.currentKey] += ` ${line.trim()}`; } return acc; }, {}); Object.keys(result).forEach(key => { result[key] = result[key].trim(); }); return { ...result, ...extractExtraDetails(input) }; } const packageName = await arg("Package name", div(` <h1>Install a Homebrew Package</h1> <p class="text-sm font-normal">Enter the name of the package you want to install.<br> You will see package details and be asked for confirmation before the installation proceeds.</p> `, "p-4")); const { stdout: infoStdOut } = await exec( `PATH="/opt/homebrew/bin:$PATH" brew info ${packageName}`, ); const info = parseToJSON(infoStdOut); if (info.installed) { setTimeout(() => { exit(); }, 3000); await div(md(`## Package is already installed. Exiting in 3 seconds...`)); } const shouldInstall = await div( { html: ` ${info.name ? `<h1><strong>${info.name}</strong> (${info.version})</h1>` : ""} ${info.version ? `<a href="${info.projectUrl}">${info.projectUrl}</a>` : ""} ${info.description ? `<p>${info.description}</p>` : ""} ${info.fromUrl ? `<p><strong>From:</strong> ${info.fromUrl}</p>` : ""} ${md(`### Do you want to install this package? * [Yes](submit:yes) * [No](submit:no)`)} `.trim(), }, "p-8", ); if (shouldInstall === "yes") { await term( `PATH="/opt/homebrew/bin:$PATH" brew install ${packageName} && exit`, ); setTimeout(() => { exit(); }, 3000); await div(md(`## Package has been succesfully installed! Exiting in 3 seconds...`)); }