chadtmiller.com/knotless
git that lives in your Atmosphere account
A revision's files download as one tar.gz or zip archive
MergedThis adds /<owner>/<repo>/archive/<rev>.tar.gz and .zip, streamed from git archive. It reads as the viewer, so private repositories work, and the Code menu and tags page link to it. The route, auth and caching look right, read::rev leaves the revision unchanged so ending is sliced correctly, and the docs are updated. All checks were still queued when I looked, so I haven't seen any result.
Shots-moved:line missing. The Code menu is inside every code page's HTML, and the tags page now showszipandtar.gzlinks. AGENTS.md says theshotscheck fails a moved page that the body doesn't name on aShots-moved:line. Once the check reports which pages moved, add that line and rerunshots. The PR also says the menu-open state was drawn withjust look, but the pictures aren't attached as--images, which AGENTS.md asks for.- Slow clients hold the permits. The semaphore permit is released only when
gitexits (archive.rs:69-72).gitblocks writing to the pipe until the client reads, so four slow or stalled downloads keep all four permits and every other archive waits behind them. The "Shortcomings" section only covers popular tags, not this. A write timeout or a total time limit on the stream would fix it, or at least wait on a bounded deadline and kill the child.
crates/knotless-serve/src/web/archive.rslines 67 to 72Outdated
// The permit is held until git is done writing; kill_on_drop covers a | |
// client that hangs up first. | |
tokio::spawn(async move { | |
let _ = child.wait().await; | |
drop(permit); | |
}); |
The permit lasts as long as the client takes to read. A client that stalls leaves git blocked on the pipe and keeps its permit, so four of them stop all archives. Add a deadline for the whole stream, killing git when it passes.
The stalled-client problem is fixed. The permit is now held for at most ten minutes (archive.rs:63-66). When the timeout passes, child drops and kill_on_drop kills git. A client that hangs up closes the pipe, so git exits and the permit is freed sooner. I have nothing more to ask on that.
Still open from round 1: the pull body has no Shots-moved: line and no --image pictures. The body hasn't changed since round 1. The Code menu is in every code page's HTML, and the tags page gained links, so these pages have moved. AGENTS.md says the shots check fails a moved page the body doesn't name. shots was still queued when I looked, and so were check, web, e2e and docs. Once shots reports which pages moved, add the Shots-moved: line to the body, attach the pictures from just look, and rerun shots.
The "Shortcomings" section could also mention the ten-minute cut-off. A slow client on a large archive gets a truncated file with no error.
8 passed, 2 skipped
What changes
Archive downloads.
/<owner>/<repo>/archive/<rev>.tar.gzand.zipdownload a repository's files at a branch, tag or commit as one archive. The files sit in a folder<repo>-<rev>, with any/in a branch name made-.git archivewrites the archive from the mirror, and it is streamed as it is written. Like the raw route, it reads as the viewer, so a private repository's archive goes to its members only and isn't cached. One at a commit's full hash is immutable, and anything else isno-cache. Another ending, or a revision that names no commit, is 404.On the pages. The Code menu has "Download zip" and "Download tar.gz" for the revision shown. On the tags page, each tag has
zipandtar.gzlinks beside its commit.Why
This is the first easy item on Basic forge features missing, from archive downloads to webhooks. Until now there was no way to get a repository's files without git and the knotless helper.
Each archive reads the whole tree and compresses it, so at most four are written at once and the rest wait, as blame already does. Writing into a cache was the other option. I left it out because a commit's archive is immutable, so browsers and any proxy in front can keep it.
How it was checked
browsing_a_repository(tests/web.rs) cover:main: its headers, and its contents un-gzipped, both the paths and the text./: the file name and folder..rar, no ending, an unknown ref, a tag of a tree, and-x.private, no-storeand varies by cookie, and with no cookie it is 404.just look repositorywith the Code menu open, desktop light and phone dark.just lookof the tags page with three tags, one with a long name.checkandtestchecks.Shortcomings
git archiveagain, bounded by the four-at-once limit. A popular tag downloaded by many people could keep those four busy.🤖 Generated with Claude Code