From 5b3170b1c8bcb5c5f96c460d38433ff4d15b403a Mon Sep 17 00:00:00 2001 From: ZHAO Jin-Xiang Date: Tue, 7 Jan 2025 20:32:02 +0800 Subject: [PATCH] the-unarchiver: init at 4.3.8 --- pkgs/by-name/th/the-unarchiver/info.json | 5 + pkgs/by-name/th/the-unarchiver/package.nix | 41 +++++++ .../th/the-unarchiver/update/jsconfig.json | 9 ++ .../th/the-unarchiver/update/update.mjs | 103 ++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 pkgs/by-name/th/the-unarchiver/info.json create mode 100644 pkgs/by-name/th/the-unarchiver/package.nix create mode 100644 pkgs/by-name/th/the-unarchiver/update/jsconfig.json create mode 100755 pkgs/by-name/th/the-unarchiver/update/update.mjs diff --git a/pkgs/by-name/th/the-unarchiver/info.json b/pkgs/by-name/th/the-unarchiver/info.json new file mode 100644 index 0000000000000..068fe7a3f44b6 --- /dev/null +++ b/pkgs/by-name/th/the-unarchiver/info.json @@ -0,0 +1,5 @@ +{ + "version": "4.3.8", + "url": "https://dl.devmate.com/com.macpaw.site.theunarchiver/146/1715865652/TheUnarchiver-146.zip", + "hash": "sha256-VcgNT7z7KtdAZxya8DS4Kuk323AAh3Mv/2L7LpUS2NU=" +} diff --git a/pkgs/by-name/th/the-unarchiver/package.nix b/pkgs/by-name/th/the-unarchiver/package.nix new file mode 100644 index 0000000000000..0cafcea1eddd1 --- /dev/null +++ b/pkgs/by-name/th/the-unarchiver/package.nix @@ -0,0 +1,41 @@ +{ + lib, + stdenvNoCC, + fetchurl, + unzip, +}: +let + info = lib.importJSON ./info.json; +in +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "the-unarchiver"; + inherit (info) version; + + src = fetchurl { inherit (info) url hash; }; + + sourceRoot = "."; + nativeBuildInputs = [ unzip ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/Applications + mv "The Unarchiver.app" $out/Applications + + runHook postInstall + ''; + + passthru.updateScript = ./update/update.mjs; + + meta = { + description = "Unpacks archive files"; + homepage = "https://theunarchiver.com/"; + license = lib.licenses.unfree; + maintainers = with lib.maintainers; [ xiaoxiangmoe ]; + platforms = [ + "aarch64-darwin" + "x86_64-darwin" + ]; + sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; + }; +}) diff --git a/pkgs/by-name/th/the-unarchiver/update/jsconfig.json b/pkgs/by-name/th/the-unarchiver/update/jsconfig.json new file mode 100644 index 0000000000000..347a07fb3e232 --- /dev/null +++ b/pkgs/by-name/th/the-unarchiver/update/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "module": "NodeNext", + "noEmit": true, + "strict": true + } +} diff --git a/pkgs/by-name/th/the-unarchiver/update/update.mjs b/pkgs/by-name/th/the-unarchiver/update/update.mjs new file mode 100755 index 0000000000000..5ec4d67749eb8 --- /dev/null +++ b/pkgs/by-name/th/the-unarchiver/update/update.mjs @@ -0,0 +1,103 @@ +#!/usr/bin/env nix-shell +/* +#!nix-shell -i node --pure --packages cacert nodejs yq-go nix +*/ +import * as assert from "node:assert/strict"; +import * as child_process from "node:child_process"; +import * as fsPromises from "node:fs/promises"; +import * as path from "node:path"; + +const __dirname = import.meta.dirname; + +/** @typedef {{ + rss: { + channel: { + item: Array<{ + pubDate: string; + enclosure: { + "+@url": string; + "+@length": string; + "+@type": string; + "+@sparkle:version": string; + "+@sparkle:shortVersionString": string; + }; + }> + } + } +}} UpdatesXmlInfo */ + +/** @typedef {{ + version: string; + url: string; + hash: string; +}} Info */ + +const UPDATE_URL = + "https://updateinfo.devmate.com/com.macpaw.site.theunarchiver/updates.xml"; + +async function main() { + const filePath = path.join(__dirname, "../info.json"); + /** @type {Info} */ + const oldInfo = JSON.parse( + await fsPromises.readFile(filePath, { encoding: "utf-8" }) + ); + + const response = await fetch(UPDATE_URL); + assert.ok(response.ok, `Failed to fetch ${UPDATE_URL}`); + /** @type {UpdatesXmlInfo} */ + const updatesXmlInfo = JSON.parse( + child_process + .execSync(`yq eval --input-format=xml --output-format=json`, { + input: Buffer.from(await response.arrayBuffer()), + }) + .toString() + ); + const items = updatesXmlInfo?.rss?.channel?.item; + assert.ok(Array.isArray(items), "items is required"); + const item = items.sort( + (a, b) => new Date(b.pubDate).getTime() - new Date(a.pubDate).getTime() + )[0]; + const { + "+@url": url, + "+@sparkle:shortVersionString": version, + "+@length": fileSize, + } = item.enclosure; + assert.ok(url, "url is required"); + assert.ok(version, "version is required"); + assert.ok(fileSize, "fileSize is required"); + + if (oldInfo.url === url && oldInfo.version === version) { + console.log("[update] No updates found"); + return; + } + + const [prefetchHash, prefetchStorePath] = child_process + .execSync(`nix-prefetch-url --print-path ${url}`) + .toString() + .split("\n"); + + const downloadedFileSize = (await fsPromises.stat(prefetchStorePath)).size; + if (Number(fileSize) !== downloadedFileSize) { + console.error( + `File size mismatch: expected ${fileSize}, got ${downloadedFileSize}` + ); + process.exit(1); + } + const hash = child_process + .execSync(`nix hash convert --hash-algo sha256 --to sri ${prefetchHash}`) + .toString() + .trim(); + /** @type {Info} */ + const info = { + version, + url, + hash, + }; + console.log(`[update] Updating Notion ${oldInfo.version} -> ${info.version}`); + await fsPromises.writeFile(filePath, JSON.stringify(info, null, 2) + "\n", { + encoding: "utf-8", + }); + console.log("[update] Updating Notion complete"); +} + +main();