Skip to content

Commit d6f326a

Browse files
authored
the-unarchiver: init at 4.3.8 (#371773)
2 parents 2ea7851 + 5b3170b commit d6f326a

File tree

4 files changed

+158
-0
lines changed

4 files changed

+158
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"version": "4.3.8",
3+
"url": "https://dl.devmate.com/com.macpaw.site.theunarchiver/146/1715865652/TheUnarchiver-146.zip",
4+
"hash": "sha256-VcgNT7z7KtdAZxya8DS4Kuk323AAh3Mv/2L7LpUS2NU="
5+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
lib,
3+
stdenvNoCC,
4+
fetchurl,
5+
unzip,
6+
}:
7+
let
8+
info = lib.importJSON ./info.json;
9+
in
10+
stdenvNoCC.mkDerivation (finalAttrs: {
11+
pname = "the-unarchiver";
12+
inherit (info) version;
13+
14+
src = fetchurl { inherit (info) url hash; };
15+
16+
sourceRoot = ".";
17+
nativeBuildInputs = [ unzip ];
18+
19+
installPhase = ''
20+
runHook preInstall
21+
22+
mkdir -p $out/Applications
23+
mv "The Unarchiver.app" $out/Applications
24+
25+
runHook postInstall
26+
'';
27+
28+
passthru.updateScript = ./update/update.mjs;
29+
30+
meta = {
31+
description = "Unpacks archive files";
32+
homepage = "https://theunarchiver.com/";
33+
license = lib.licenses.unfree;
34+
maintainers = with lib.maintainers; [ xiaoxiangmoe ];
35+
platforms = [
36+
"aarch64-darwin"
37+
"x86_64-darwin"
38+
];
39+
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
40+
};
41+
})
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"allowJs": true,
4+
"checkJs": true,
5+
"module": "NodeNext",
6+
"noEmit": true,
7+
"strict": true
8+
}
9+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/env nix-shell
2+
/*
3+
#!nix-shell -i node --pure --packages cacert nodejs yq-go nix
4+
*/
5+
import * as assert from "node:assert/strict";
6+
import * as child_process from "node:child_process";
7+
import * as fsPromises from "node:fs/promises";
8+
import * as path from "node:path";
9+
10+
const __dirname = import.meta.dirname;
11+
12+
/** @typedef {{
13+
rss: {
14+
channel: {
15+
item: Array<{
16+
pubDate: string;
17+
enclosure: {
18+
"+@url": string;
19+
"+@length": string;
20+
"+@type": string;
21+
"+@sparkle:version": string;
22+
"+@sparkle:shortVersionString": string;
23+
};
24+
}>
25+
}
26+
}
27+
}} UpdatesXmlInfo */
28+
29+
/** @typedef {{
30+
version: string;
31+
url: string;
32+
hash: string;
33+
}} Info */
34+
35+
const UPDATE_URL =
36+
"https://updateinfo.devmate.com/com.macpaw.site.theunarchiver/updates.xml";
37+
38+
async function main() {
39+
const filePath = path.join(__dirname, "../info.json");
40+
/** @type {Info} */
41+
const oldInfo = JSON.parse(
42+
await fsPromises.readFile(filePath, { encoding: "utf-8" })
43+
);
44+
45+
const response = await fetch(UPDATE_URL);
46+
assert.ok(response.ok, `Failed to fetch ${UPDATE_URL}`);
47+
/** @type {UpdatesXmlInfo} */
48+
const updatesXmlInfo = JSON.parse(
49+
child_process
50+
.execSync(`yq eval --input-format=xml --output-format=json`, {
51+
input: Buffer.from(await response.arrayBuffer()),
52+
})
53+
.toString()
54+
);
55+
const items = updatesXmlInfo?.rss?.channel?.item;
56+
assert.ok(Array.isArray(items), "items is required");
57+
const item = items.sort(
58+
(a, b) => new Date(b.pubDate).getTime() - new Date(a.pubDate).getTime()
59+
)[0];
60+
const {
61+
"+@url": url,
62+
"+@sparkle:shortVersionString": version,
63+
"+@length": fileSize,
64+
} = item.enclosure;
65+
assert.ok(url, "url is required");
66+
assert.ok(version, "version is required");
67+
assert.ok(fileSize, "fileSize is required");
68+
69+
if (oldInfo.url === url && oldInfo.version === version) {
70+
console.log("[update] No updates found");
71+
return;
72+
}
73+
74+
const [prefetchHash, prefetchStorePath] = child_process
75+
.execSync(`nix-prefetch-url --print-path ${url}`)
76+
.toString()
77+
.split("\n");
78+
79+
const downloadedFileSize = (await fsPromises.stat(prefetchStorePath)).size;
80+
if (Number(fileSize) !== downloadedFileSize) {
81+
console.error(
82+
`File size mismatch: expected ${fileSize}, got ${downloadedFileSize}`
83+
);
84+
process.exit(1);
85+
}
86+
const hash = child_process
87+
.execSync(`nix hash convert --hash-algo sha256 --to sri ${prefetchHash}`)
88+
.toString()
89+
.trim();
90+
/** @type {Info} */
91+
const info = {
92+
version,
93+
url,
94+
hash,
95+
};
96+
console.log(`[update] Updating Notion ${oldInfo.version} -> ${info.version}`);
97+
await fsPromises.writeFile(filePath, JSON.stringify(info, null, 2) + "\n", {
98+
encoding: "utf-8",
99+
});
100+
console.log("[update] Updating Notion complete");
101+
}
102+
103+
main();

0 commit comments

Comments
 (0)