Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

396 commit(s) on main

Turn off the disk reserve for test-spawned runners Keenan Nemetz · 35m ago c284cb2c
source preview history blame raw 3.8 KiB

Go modules

A public repository on a Vole instance is a Go module. The import path is the instance’s host and the repository name:

https://<host>/<repository>

Vole serves the metadata the go command looks for, so an import path needs no vanity service, no redirect, and no separate web host in front of the forge. Vole itself is published this way: rodent.software/vole.

How the lookup works

go get cannot clone an arbitrary URL from an import path, so it first asks the path for directions: it fetches https://<host>/<repository>?go-get=1 and reads the <meta name="go-import"> tag in the answer. Vole answers for a public repository with that repository’s Git transport:

$ curl -s 'https://rodent.software/vole?go-get=1'
<!doctype html>
...
<meta name="go-import" content="rodent.software/vole git https://rodent.software/vole.git">

Then go clones the repository over the smart-HTTP transport and resolves the package from the tag it finds there, exactly as it would for a module on any other forge. The transport lives beside the pages: /<repository> is the repository and /<repository>.git is its Git URL, so the tag’s clone URL and the page a person opens are the same name.

A package inside the module (rodent.software/vole/server/web) resolves from the same tag: the go command asks the full path first, and the tag it gets names the repository prefix. That path is not a page, and it does not need to be — the probe is answered before the router, for any path whose first segment names a public repository.

Add the repository to a project as usual:

$ go get rodent.software/vole
$ go doc rodent.software/vole/server/web

What the instance must have

  • public_url set to the origin people use, in [server] in the configuration file. The metadata’s import prefix is that origin’s host name; without public_url Vole falls back to the request’s host, which is not something the go command’s discovery can rely on.
  • The host in the import path is the host name alone. A module path cannot carry a port, so an instance reached only at https://forge.example.com:8443 can still serve its pages, but its repositories are not importable paths; clone them by URL instead.

Which repositories answer

Only a repository an anonymous reader may read, which is the same rule that makes its pages public. The tag is fetched without credentials — that is the discovery protocol — so answering for a private repository would confirm to anyone who guessed the name that it exists. Vole answers 404 for those, like every other private path.

A private repository is therefore not resolvable from its import path. Clone it where the build runs and point a replace at that checkout, or mirror the code in a repository that is public.

Naming

The import path is <host>/<repository>, so the repository name is also the last element of every import path inside the module. Every name is available for this except the four the forge keeps at the root for reasons a URL cannot avoid: static (assets), and robots.txt, sitemap.xml, and sitemap-pages.xml (crawlers only look for those at the root). The forge’s own pages live under /-/, a prefix no repository name can start with, so admin, login, activity and the rest are ordinary repository names.

Because the name is the import path, renaming a repository that other modules import breaks them: there is no forwarding layer in front of the forge. Rename the pages, or keep the name a published module depends on.

Vole’s own module

The Vole repository is rodent.software/vole, so fetching the source is:

$ go get rodent.software/vole

and building from a checkout uses the same path:

go build -tags libsqlite3,sqlite_fts5 -o vole rodent.software/vole/cmd/vole