A repository now owns the root of the URL space. /<name> is its page,
/<name>/issues/12 its tabs, and /<name>.git its Git transport, so the URL a
person opens, the URL a clone copies, and the Go module path are the same name
with no owner segment and no /r/ prefix in the way. The forge’s own pages moved
under /-/.
This is stacked on #253 (module path + go-import). The last two commits are
this change; landing #253 first makes this a clean two-commit diff. The go-import
probe is moved to the new pre-router here, because with a repository at /<name>
it can no longer be served by the catch-all.
The two spaces
- Repositories:
/<name>,/<name>.git. Repository names are[a-z0-9][a-z0-9._-]*and cannot start with-, so/-/can never be a repository and the router needs no reserved-name list to keep the spaces apart. - Forge:
/-/admin,/-/u/<account>,/-/users/...,/-/activity,/-/login,/-/register,/-/invite,/-/account,/-/search/palette,/-/status,/-/runners,/-/healthz,/-/repos/new,/-/auth/...,/-/logout,/-/dev/login. - Kept at the root because a URL cannot move them:
/,/robots.txt,/sitemap.xml,/sitemap-pages.xml, and assets at/-/static/.
Consequences worth reviewing:
- Assets moved to
/-/static/. A subtree pattern likeGET /static/cannot coexist with one-segment-wildcard repository routes: for/static/counts, Go’s mux seesGET /{name}/countsandGET /static/as overlapping with neither more specific and panics at registration./-/static/makes the conflict impossible instead of special-casing one route. - The transport is recognised before the router. A wildcard fills a whole
path segment, so
/<name>.gitcannot be a route.server/forgepaths.gohands such requests to the Git proxy;githttp.Routenow parses/<name>.git/<rest>directly (no internal/git/prefix), and LFS stays on the mux at/<name>.git/info/lfs/.... Unclean paths are left to the mux so its redirect still applies to them. - No aliases.
/r/...,/git/...,/static/...,/u/...,/admin,/loginare 404. A test pins that so the old shapes cannot creep back. - Reserved names shrink to four.
repo.ValidateNamerefusesstatic,robots.txt,sitemap.xml,sitemap-pages.xml. A repository calledadmin,u,r, oractivityis now ordinary and tested to render at its own path. - Robots and sitemaps describe the new surface; per-repository entries are
/<name>/sitemap.xmland<loc>values are the new pages.
Scope of the diff
Route table (server/routes.go), URL construction across handlers, templates,
activity events, sitemaps, robots, the instance repository’s starter README,
CLI-printed links (client.Actor.Page), the theme/asset URLs, and the static
asset paths in CSS. Tests and docs follow. 169 files before the docs commit; the
second commit is documentation only.
Verification
./vole workflow checkand./vole workflow run verifypass (format, vet, build, licenses, govulncheck, packages, deployment files, markdown links, race tests).- New
TestRepositoryOwnsTheRootOfTheURLSpacecovers/<name>, the clone advertisement at/<name>.git/info/refs, bare/<name>.git,/-/healthz,/-/static/, and that the old paths are 404. TestRepositoryNameNeedNotAvoidTheForgecreates a repository namedadminand checks its page is the repository while/-/u/<account>remains the forge’s.TestGitTransportIsAbsentWhenGitHTTPIsOffcovers the disabled transport.TestValidateNameReservesOnlyTheForgeRootcovers the four reserved names and thatadmin,u,r,activity,login,users,gitare allowed.- Existing clone, push-over-HTTP, LFS, go-import, robots, sitemap and page tests were updated and pass.