pantry/scripts/upload.ts

70 lines
2.2 KiB
TypeScript
Raw Normal View History

2022-08-01 22:43:40 +03:00
#!/usr/bin/env -S tea -E
/*---
args:
- deno
- run
- --allow-net
- --allow-read=/opt
- --allow-env=AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_S3
- --import-map={{ srcroot }}/import-map.json
---*/
import { S3 } from "s3"
import { crypto } from "deno/crypto/mod.ts"
import useCache from "hooks/useCache.ts"
import useCellar from "hooks/useCellar.ts"
import { encodeToString } from "encodeToString"
import { Package, parsePackageRequirement, SemVer, semver } from "types"
if (Deno.args.length === 0) throw new Error("no args supplied")
const s3 = new S3({
accessKeyID: Deno.env.get("AWS_ACCESS_KEY_ID")!,
secretKey: Deno.env.get("AWS_SECRET_ACCESS_KEY")!,
region: "us-east-1",
})
const bucket = s3.getBucket(Deno.env.get("AWS_S3")!)
const cellar = useCellar()
for (const rq of Deno.args.map(parsePackageRequirement)) {
const {pkg} = await cellar.resolve(rq)
const key = useCache().s3Key(pkg)
const bottle = useCache().bottle(pkg)
console.log({ key });
//FIXME stream it to S3
const bottle_contents = await Deno.readFile(bottle.string)
const encode = (() => { const e = new TextEncoder(); return e.encode.bind(e) })()
const [basename, dirname] = (split => [split.pop(), split.join("/")])(key.split("/"))
const checksum = encodeToString(new Uint8Array(await crypto.subtle.digest("SHA-256", bottle_contents)))
const versions = await get_versions(pkg)
await bucket.putObject(key, bottle_contents)
await bucket.putObject(`${key}.sha256sum`, encode(`${checksum} ${basename}`))
await bucket.putObject(`${dirname}/versions.txt`, encode(versions.join("\n")))
console.log({ uploaded: key })
}
2022-08-04 18:28:23 +03:00
import { dirname, basename } from "deno/path/mod.ts"
2022-08-01 22:43:40 +03:00
async function get_versions(pkg: Package): Promise<SemVer[]> {
2022-08-04 18:28:23 +03:00
const prefix = dirname(useCache().s3Key(pkg))
2022-08-01 22:43:40 +03:00
const rsp = await bucket.listObjects({ prefix })
//FIXME? API isnt clear if these nulls indicate failure or not
//NOTE if this is a new package then some empty results is expected
2022-08-02 05:50:33 +03:00
const got = rsp
2022-08-01 22:43:40 +03:00
?.contents
2022-08-04 18:28:23 +03:00
?.compactMap(x => x.key)
.map(x => basename(x))
2022-08-01 22:43:40 +03:00
.compactMap(semver.coerce) //FIXME coerce is too loose
2022-08-02 05:50:33 +03:00
?? []
// have to add pkg.version as put and get are not atomic
return [...new Set([...got, pkg.version])].sort()
2022-08-01 22:43:40 +03:00
}