05916a2b7e91

read a file:// download in koh update, which is what a Kepr with a folder bucket hands out (3.0.87)

time
2026-09-27 14:05 UTC · 2 weeks ago
machine
Junes-MacBook-Pro.local
agent
deepseek/deepseek-flash
session
koh 3 phases 6-8
parent
416aa9fce19d
4 files VERSION+1 −1src/update/update.v+10 −0src/update/update_test.v+18 −0v.mod+1 −1
VERSION+1 −1
@@ -1 +1 @@1-3.0.861+3.0.87

view file

src/update/update.v+10 −0
@@ -15,6 +15,7 @@1515 pub const default_source = 'https://kepr.uk/koh/releases/latest.json'1616 pub const source_env = 'KOH_UPDATE_SOURCE'1717 pub const repo = 'koh'18+const file_scheme = 'file://'1819 1920 // One platform's file, in the shape Kepr answers with (§22.4).2021 struct PlatformFile {@@ -140,6 +141,15 @@140141 }141142 142143 fn download(url string) ![]u8 {144+	if url.starts_with(file_scheme) {145+		// A Kepr with a folder bucket hands out `file://` download URLs (dev and146+		// tests only), so updating from one is the same code path with the file147+		// read instead of fetched.148+		path := url[file_scheme.len..]149+		return os.read_file(path) or {150+			return error('could not read ${url}: ${err.msg()}')151+		}.bytes()152+	}143153 	response := http.get(url) or { return error('could not download ${url}: ${err.msg()}') }144154 	if response.status_code != 200 {145155 		return error('${url} answered ${response.status_code}')

view file

src/update/update_test.v+18 −0
@@ -85,3 +85,21 @@8585 	os.unsetenv(source_env)8686 	assert source() == default_source8787 }88+89+// A folder-bucket Kepr hands out file:// download URLs, so koh must read them.90+fn test_a_file_url_is_read_into_the_same_bytes() {91+	dir := scratch('download')!92+	defer {93+		os.rmdir_all(dir) or {}94+	}95+	path := os.join_path(dir, 'koh3')96+	os.write_file_array(path, 'the new binary'.bytes())!97+	body := download('file://${path}')!98+	assert body.bytestr() == 'the new binary'99+	assert blake3.sum256(body).hex() == '0e86a96ebd4c3d861a2e85c07544478573af7ab3745c1d4e7b5750fdbe7cc397'100+	if _ := download('file://${dir}/missing') {101+		assert false, 'a file URL that is not there must be refused'102+	} else {103+		assert err.msg().contains('could not read')104+	}105+}

view file

v.mod+1 −1
@@ -1,6 +1,6 @@11 Module {22 	name: 'koh3'3-	version: '3.0.86'3+	version: '3.0.87'44 	description: 'One SQLite file per repo, one line of history.'55 	license: 'MIT'66 }

view file