pantry/scripts/upload-sync.ts

59 lines
1.7 KiB
TypeScript
Raw Normal View History

2022-09-08 23:40:35 +03:00
#!/usr/bin/env -S tea -E
/*---
args:
- deno
- run
2022-09-13 19:46:10 +03:00
- --allow-read
2022-09-08 23:40:35 +03:00
- --allow-net
2022-09-13 19:46:10 +03:00
- --allow-env=AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_S3_BUCKET,TEA_PREFIX
2022-09-08 23:40:35 +03:00
- --import-map={{ srcroot }}/import-map.json
---*/
2022-09-20 14:53:40 +03:00
import { S3 } from "s3"
import { Sha256 } from "deno/hash/sha256.ts"
import { useCache } from "hooks"
import { readAll, readerFromStreamReader } from "deno/streams/mod.ts"
2022-09-08 23:40:35 +03:00
const s3 = new S3({
accessKeyID: Deno.env.get("AWS_ACCESS_KEY_ID")!,
secretKey: Deno.env.get("AWS_SECRET_ACCESS_KEY")!,
region: "us-east-1",
2022-09-20 14:53:40 +03:00
})
2022-09-08 23:40:35 +03:00
2022-09-20 14:53:40 +03:00
const bucket = s3.getBucket(Deno.env.get("AWS_S3_BUCKET")!)
2022-09-08 23:40:35 +03:00
for (const pkg of await useCache().ls()) {
const key = useCache().s3Key(pkg)
const bottle = useCache().bottle(pkg)
2022-09-20 14:53:40 +03:00
console.log({ checking: key })
2022-09-08 23:40:35 +03:00
const inRepo = await bucket.headObject(key)
const repoChecksum = inRepo ? await checksum(`https://dist.tea.xyz/${key}.sha256sum`) : undefined
// path.read() returns a string; this is easier to get a UInt8Array
2022-09-20 14:53:40 +03:00
const contents = await Deno.readFile(bottle.string)
const sha256sum = new Sha256().update(contents).toString()
2022-09-08 23:40:35 +03:00
if (!inRepo || repoChecksum !== sha256sum) {
const basename = key.split("/").pop()
const body = new TextEncoder().encode(`${sha256sum} ${basename}`)
2022-09-20 14:53:40 +03:00
console.log({ uploading: key })
2022-09-08 23:40:35 +03:00
2022-09-20 14:53:40 +03:00
await bucket.putObject(key, contents)
await bucket.putObject(`${key}.sha256sum`, body)
2022-09-08 23:40:35 +03:00
2022-09-20 14:53:40 +03:00
console.log({ uploaded: key })
2022-09-08 23:40:35 +03:00
}
}
async function checksum(url: string) {
const rsp = await fetch(url)
if (!rsp.ok) throw new Error(`404-not-found: ${url}`)
const rdr = rsp.body?.getReader()
if (!rdr) throw new Error(`Couldnt read: ${url}`)
const r = await readAll(readerFromStreamReader(rdr))
return new TextDecoder().decode(r).split(' ')[0]
}