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.
Simplify the home page around the instance introduction
ff9870f1a26a17d54c21d411000a6c7d58ab5c0d · Keenan Nemetz · 1d ago · parent 6ce635a8
Simplify the home page around the instance introduction Drop the page header and its hero actions. The instance name and sign-in links already live in the top bar, and the introduction is the place to say what the forge is. Move New repository into the Repositories heading, where it sits with the list it creates. Remove the introduction card header and its in-page editor. The introduction is profile/README.md in the instance repository, so it is read and pushed like every other customization. The POST / handler and its editor code go with it; an instance admin without an instance repository still gets the setup hint.
server/instance_repo_test.go +5−51
| @@ -32,6 +32,11 @@ func TestInstanceRepoSuppliesThePage(t *testing.T) { | |||
| 32 | 32 | t.Fatalf("home is missing %q:\n%s", want, body) | |
| 33 | 33 | } | |
| 34 | 34 | } | |
| 35 | for _, unwanted := range []string{`name="intro"`, `href="/?edit=1`, `class="readme-head"`} { | ||
| 36 | if strings.Contains(body, unwanted) { | ||
| 37 | t.Fatalf("the home introduction still has %q:\n%s", unwanted, body) | ||
| 38 | } | ||
| 39 | } | ||
| 35 | 40 | if strings.Contains(body, "Members only") { | |
| 36 | 41 | t.Fatalf("the private README leaked to an anonymous viewer:\n%s", body) | |
| 37 | 42 | } | |
| @@ -108,54 +113,3 @@ func TestAdminCreatesTheInstanceRepository(t *testing.T) { | |||
| 108 | 113 | t.Fatalf("home does not read the scaffolded introduction:\n%s", home) | |
| 109 | 114 | } | |
| 110 | 115 | } | |
| 111 | |||
| 112 | func TestHomeHasNoIntroEditorWithoutTheInstanceRepo(t *testing.T) { | ||
| 113 | t.Parallel() | ||
| 114 | f := browserFixture(t) | ||
| 115 | if _, err := f.srv.Identity.SetAdmin(f.ownerID, true, "test"); err != nil { | ||
| 116 | t.Fatal(err) | ||
| 117 | } | ||
| 118 | _, cookie := f.browserSession(t, f.ownerID) | ||
| 119 | _, body := f.browserGet(t, "/?edit=1", cookie) | ||
| 120 | if strings.Contains(body, `name="intro"`) || strings.Contains(body, `href="/?edit=1#readme"`) { | ||
| 121 | t.Fatalf("an editor appeared without an instance repository:\n%s", body) | ||
| 122 | } | ||
| 123 | if !strings.Contains(body, "Admin Configuration") { | ||
| 124 | t.Fatalf("home does not say where to set up customization:\n%s", body) | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | // The in-page editor always writes the public README, even when a signed-in | ||
| 129 | // admin is looking at the private one. Saving the private text into the public | ||
| 130 | // file would publish it. | ||
| 131 | func TestHomeEditorWritesThePublicReadme(t *testing.T) { | ||
| 132 | t.Parallel() | ||
| 133 | f := browserFixture(t) | ||
| 134 | f.instanceRepo(t, map[string][]byte{ | ||
| 135 | "profile/README.md": []byte("# Public"), | ||
| 136 | "profile/private/README.md": []byte("# Members only"), | ||
| 137 | }) | ||
| 138 | if _, err := f.srv.Identity.SetAdmin(f.ownerID, true, "test"); err != nil { | ||
| 139 | t.Fatal(err) | ||
| 140 | } | ||
| 141 | sess, cookie := f.browserSession(t, f.ownerID) | ||
| 142 | |||
| 143 | _, body := f.browserGet(t, "/?edit=1", cookie) | ||
| 144 | if !strings.Contains(body, "# Public") || strings.Contains(body, "# Members only") { | ||
| 145 | t.Fatalf("the editor did not open the public README:\n%s", body) | ||
| 146 | } | ||
| 147 | form := url.Values{"csrf": {sess.CSRF}, "intro": {"# New public"}} | ||
| 148 | if resp, _ := f.browserPost(t, "/", cookie, form); resp.StatusCode != 303 { | ||
| 149 | t.Fatalf("save = %d", resp.StatusCode) | ||
| 150 | } | ||
| 151 | // Signed-in viewers still see the private README; anonymous viewers see the | ||
| 152 | // public one that was just written. | ||
| 153 | _, signed := f.browserGet(t, "/", cookie) | ||
| 154 | if !strings.Contains(signed, "Members only") || strings.Contains(signed, "New public") { | ||
| 155 | t.Fatalf("signed-in home = %s", signed) | ||
| 156 | } | ||
| 157 | _, anon := f.get("/") | ||
| 158 | if !strings.Contains(anon, "New public") { | ||
| 159 | t.Fatalf("anonymous home did not show the public README:\n%s", anon) | ||
| 160 | } | ||
| 161 | } | ||