Veroeffentlichung ueber Gitea, BOM-Toleranz, Tests fuer den YAML-Leser
Das Repo ist jetzt oeffentlich, die Pakete haengen an der Veroeffentlichung `latest`. Damit funktioniert `abdulive update` ohne Token. - config.example.yaml traegt die gepruefte Update-Adresse - .gitea/workflows/release.yml baut beim Tag und ersetzt `latest` - Byte Order Mark: Notepad und `Set-Content -Encoding utf8` schreiben eines, und ohne Behandlung hiess der erste Schluessel in der config.yaml "\ufeffchannel" - die Einstellung waere stillschweigend ignoriert worden - Der YAML-Leser hatte gar keine Tests; er liest die Konfiguration, an der alles haengt. Jetzt acht. Der Updater ist einmal komplett durchgelaufen: 0.4.0 erkannt, 119 MB geladen, Pruefsumme geprueft, bereitgelegt, von launcher.ps1 getauscht. 93 Tests, Typpruefung sauber. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AhVSfMFdWnXKCv5JfLnArZ
This commit is contained in:
1 parent
5f6301268a
commit
08f7c21450
8 files changed
+165
-33
No files matched your search
+10
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { isNewer, looksLikeLogin } from './update.ts';
|
||||
import { isNewer, looksLikeLogin, parseJsonLoose } from './update.ts';
|
||||
|
||||
test('vergleicht Versionen als Zahlen, nicht als Text', () => {
|
||||
// Der Fall, der bei Zeichenkettenvergleich falsch herauskaeme
|
||||
@@ -42,3 +42,12 @@ test('haelt ein echtes Manifest nicht faelschlich fuer HTML', () => {
|
||||
}));
|
||||
assert.equal(looksLikeLogin(null, manifest), false);
|
||||
});
|
||||
|
||||
test('ein Byte Order Mark macht das Manifest nicht unlesbar', () => {
|
||||
// Windows PowerShell 5.1 schreibt bei `Set-Content -Encoding utf8` eines,
|
||||
// und Notepad ebenso. JSON.parse verschluckt sich daran.
|
||||
const mitBom = '{"version":"0.5.0"}';
|
||||
assert.throws(() => JSON.parse(mitBom));
|
||||
assert.deepEqual(parseJsonLoose(mitBom), { version: '0.5.0' });
|
||||
assert.deepEqual(parseJsonLoose('{"a":1}'), { a: 1 });
|
||||
});
|
||||
+8
-2
@@ -56,10 +56,15 @@ export function looksLikeLogin(contentType: string | null, body: Buffer): boolea
|
||||
head.includes('/user/login');
|
||||
}
|
||||
|
||||
/** JSON.parse verschluckt sich an einem Byte Order Mark - Windows schreibt eines. */
|
||||
export function parseJsonLoose(text: string): unknown {
|
||||
return JSON.parse(text.replace(/^/, ''));
|
||||
}
|
||||
|
||||
async function localVersion(): Promise<string> {
|
||||
const raw = await fs.readFile(path.join(installRoot, 'version.json'), 'utf8').catch(() => null);
|
||||
if (!raw) return '0';
|
||||
return (JSON.parse(raw) as { version?: string }).version ?? '0';
|
||||
return (parseJsonLoose(raw) as { version?: string }).version ?? '0';
|
||||
}
|
||||
|
||||
/** Adresse und - falls hinterlegt - der Zugriffstoken. */
|
||||
@@ -114,7 +119,8 @@ export async function checkForUpdate(opts: { force?: boolean } = {}): Promise<vo
|
||||
console.log(`Quelle: ${url}`);
|
||||
console.log(`Installiert: ${current}`);
|
||||
|
||||
const manifest = JSON.parse((await hole(`${url}/abdulive.json`, headers)).toString('utf8')) as Manifest;
|
||||
const manifest = parseJsonLoose(
|
||||
(await hole(`${url}/abdulive.json`, headers)).toString('utf8')) as Manifest;
|
||||
console.log(`Angeboten: ${manifest.version}`);
|
||||
|
||||
if (!opts.force && !isNewer(manifest.version, current)) {
|
||||
|
||||
Reference in new issue
Block a user