eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1#!/usr/bin/env python3
2# Embed release-notes HTML as an inline <description> on the appcast item whose
3# sparkle:shortVersionString matches, and drop any sparkle:releaseNotesLink.
4#
5# Why inline rather than a <sparkle:releaseNotesLink>: Sparkle renders an inline
6# <description> straight in the updater with no extra network fetch, so it
7# doesn't depend on the notes host's content-type (GitHub serves release assets
8# as application/octet-stream) and never 404s the way GitHub's /latest/download/
9# link does once a newer release becomes "latest". The HTML is XML-escaped here,
10# which Sparkle's parser decodes back to markup before rendering — functionally
11# identical to a CDATA block. The signed <enclosure> is left untouched.
12#
13# Usage: embed-release-notes.py <appcast.xml> <short-version> <notes.html>
14import sys, xml.etree.ElementTree as ET
15
16appcast, version, notes_path = sys.argv[1], sys.argv[2], sys.argv[3]
17SPARKLE = "http://www.andymatuschak.org/xml-namespaces/sparkle"
18ET.register_namespace("sparkle", SPARKLE)
19
20with open(notes_path, encoding="utf-8") as f:
21 notes = f.read()
22
23tree = ET.parse(appcast)
24matched = False
25for item in tree.getroot().iter("item"):
26 sv = item.find(f"{{{SPARKLE}}}shortVersionString")
27 if sv is None or sv.text != version:
28 continue
29 for tag in (f"{{{SPARKLE}}}releaseNotesLink", "description"):
30 for el in item.findall(tag):
31 item.remove(el)
32 ET.SubElement(item, "description").text = notes
33 matched = True
34
35if not matched:
36 sys.exit(f"embed-release-notes: no appcast item with shortVersionString {version}")
37
38tree.write(appcast, encoding="UTF-8", xml_declaration=True)
39