Fix unpack quickstart docs and hash verification
This commit is contained in:
+10
-6
@@ -6,21 +6,25 @@ the giant blob you get back from `POST /v1/clones` or
|
||||
|
||||
Zero dependencies. Needs Node >= 20.
|
||||
|
||||
This workspace is currently private and repo-local. Run these commands from the
|
||||
repository root after `npm install`; do not use `npx ditto` until the package is
|
||||
published.
|
||||
|
||||
## Unpack
|
||||
|
||||
```bash
|
||||
# from a saved file
|
||||
ditto unpack clone.json ./out
|
||||
npm run unpack -- clone.json ./out
|
||||
|
||||
# straight from curl, no temp file
|
||||
curl -sS -X POST "$DITTO_API_URL/v1/clones" \
|
||||
-H "authorization: Bearer $DITTO_API_KEY" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{"url":"https://example.com/","options":{"mode":"single"}}' \
|
||||
| ditto unpack - ./out
|
||||
| npm run --silent unpack -- - ./out
|
||||
```
|
||||
|
||||
`ditto unpack <clone.json|-> <out-dir>`:
|
||||
`npm run unpack -- <clone.json|-> <out-dir>`:
|
||||
|
||||
- writes every text file from its inline `content`,
|
||||
- materializes binary assets from inline base64 when present, otherwise fetches
|
||||
@@ -31,8 +35,8 @@ curl -sS -X POST "$DITTO_API_URL/v1/clones" \
|
||||
### Binary assets
|
||||
|
||||
Clone results return binaries by reference (`{ "type": "binary", "url": ... }`)
|
||||
rather than inlining megabytes of base64. To fetch them, `ditto` needs to know
|
||||
where the API lives:
|
||||
rather than inlining megabytes of base64. To fetch them, the unpacker needs to
|
||||
know where the API lives:
|
||||
|
||||
| Source | Flag | Env |
|
||||
| --- | --- | --- |
|
||||
@@ -43,4 +47,4 @@ Use `--no-fetch` to write only the text tree and list the binaries as skipped.
|
||||
To grab everything in one shot instead, download the archive directly:
|
||||
`GET /v1/clones/<id>/bundle?format=tgz`.
|
||||
|
||||
Run `ditto --help` for the full option list.
|
||||
Run `npm run unpack -- --help` for the full option list.
|
||||
|
||||
@@ -32,13 +32,14 @@ Options:
|
||||
-h, --help Show this help.
|
||||
|
||||
Examples:
|
||||
npm run unpack -- clone.json ./out
|
||||
|
||||
curl -sS -X POST "$DITTO_API_URL/v1/clones" \\
|
||||
-H "authorization: Bearer $DITTO_API_KEY" \\
|
||||
-H "content-type: application/json" \\
|
||||
-d '{"url":"https://example.com/","options":{"mode":"single"}}' \\
|
||||
| ditto unpack - ./out
|
||||
| npm run --silent unpack -- - ./out
|
||||
|
||||
ditto unpack clone.json ./out
|
||||
`;
|
||||
|
||||
/** Print to stderr and exit non-zero. */
|
||||
@@ -166,7 +167,6 @@ async function unpack(positionals, flags) {
|
||||
|
||||
let written = 0;
|
||||
let bytes = 0;
|
||||
let hashMismatch = 0;
|
||||
const skipped = [];
|
||||
|
||||
for (const [path, entry] of Object.entries(files)) {
|
||||
@@ -199,18 +199,17 @@ async function unpack(positionals, flags) {
|
||||
buf = Buffer.from(typeof entry.content === "string" ? entry.content : "", "utf8");
|
||||
}
|
||||
|
||||
if (typeof entry.sha256 === "string" && entry.sha256 && sha256(buf) !== entry.sha256) {
|
||||
log(` ! ${path}: sha256 mismatch`);
|
||||
fail(`${path} failed sha256 integrity check`);
|
||||
}
|
||||
|
||||
const dest = safeJoin(outAbs, path);
|
||||
await mkdir(dirname(dest), { recursive: true });
|
||||
await writeFile(dest, buf);
|
||||
written++;
|
||||
bytes += buf.length;
|
||||
|
||||
if (typeof entry.sha256 === "string" && entry.sha256 && sha256(buf) !== entry.sha256) {
|
||||
hashMismatch++;
|
||||
log(` ! ${path}: sha256 mismatch`);
|
||||
} else {
|
||||
log(` + ${path}`);
|
||||
}
|
||||
log(` + ${path}`);
|
||||
}
|
||||
|
||||
const kb = (bytes / 1024).toFixed(1);
|
||||
@@ -229,7 +228,6 @@ async function unpack(positionals, flags) {
|
||||
);
|
||||
}
|
||||
}
|
||||
if (hashMismatch) fail(`${hashMismatch} file(s) failed sha256 integrity check`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
|
||||
@@ -175,6 +175,7 @@ test("unpack: reports sha256 mismatch as a failure", async () => {
|
||||
const res = await run(["unpack", "-", out], { stdin: JSON.stringify(doc) });
|
||||
assert.notEqual(res.code, 0);
|
||||
assert.match(res.err, /integrity check/);
|
||||
await assert.rejects(stat(join(out, "a.txt")));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user