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.
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_urlset to the origin people use, in[server]in the configuration file. The metadata’s import prefix is that origin’s host name; withoutpublic_urlVole 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:8443can 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