Diff
1diff --git a/server/backend/repo.go b/server/backend/repo.go
2index 5f07e61f175140795062d954ce67e04897d6e06f..ebd846f4e9328ea71fa10ca1b56d592f5a62b2b4 100644
3--- a/server/backend/repo.go
4+++ b/server/backend/repo.go
5@@ -5,6 +5,7 @@ import (
6 "context"
7 "errors"
8 "fmt"
9+ "io/fs"
10 "os"
11 "path/filepath"
12 "time"
13@@ -53,6 +54,18 @@ func (d *Backend) CreateRepository(ctx context.Context, name string, opts proto.
14 return err
15 }
16
17+ if err := os.WriteFile(filepath.Join(rp, "description"), []byte(opts.Description), fs.ModePerm); err != nil {
18+ d.logger.Error("failed to write description", "repo", name, "err", err)
19+ return err
20+ }
21+
22+ if !opts.Private {
23+ if err := os.WriteFile(filepath.Join(rp, "git-daemon-export-ok"), []byte{}, fs.ModePerm); err != nil {
24+ d.logger.Error("failed to write git-daemon-export-ok", "repo", name, "err", err)
25+ return err
26+ }
27+ }
28+
29 return hooks.GenerateHooks(ctx, d.cfg, repo)
30 }); err != nil {
31 d.logger.Debug("failed to create repository in database", "err", err)
32@@ -341,29 +354,51 @@ func (d *Backend) SetHidden(ctx context.Context, name string, hidden bool) error
33 // SetDescription sets the description of a repository.
34 //
35 // It implements backend.Backend.
36-func (d *Backend) SetDescription(ctx context.Context, repo string, desc string) error {
37- repo = utils.SanitizeRepo(repo)
38+func (d *Backend) SetDescription(ctx context.Context, name string, desc string) error {
39+ name = utils.SanitizeRepo(name)
40+ rp := filepath.Join(d.reposPath(), name+".git")
41
42 // Delete cache
43- d.cache.Delete(repo)
44+ d.cache.Delete(name)
45
46 return d.db.TransactionContext(ctx, func(tx *db.Tx) error {
47- return d.store.SetRepoDescriptionByName(ctx, tx, repo, desc)
48+ if err := os.WriteFile(filepath.Join(rp, "description"), []byte(desc), fs.ModePerm); err != nil {
49+ d.logger.Error("failed to write description", "repo", name, "err", err)
50+ return err
51+ }
52+
53+ return d.store.SetRepoDescriptionByName(ctx, tx, name, desc)
54 })
55 }
56
57 // SetPrivate sets the private flag of a repository.
58 //
59 // It implements backend.Backend.
60-func (d *Backend) SetPrivate(ctx context.Context, repo string, private bool) error {
61- repo = utils.SanitizeRepo(repo)
62+func (d *Backend) SetPrivate(ctx context.Context, name string, private bool) error {
63+ name = utils.SanitizeRepo(name)
64+ rp := filepath.Join(d.reposPath(), name+".git")
65
66 // Delete cache
67- d.cache.Delete(repo)
68+ d.cache.Delete(name)
69
70 return db.WrapError(
71 d.db.TransactionContext(ctx, func(tx *db.Tx) error {
72- return d.store.SetRepoIsPrivateByName(ctx, tx, repo, private)
73+ fp := filepath.Join(rp, "git-daemon-export-ok")
74+ if !private {
75+ if err := os.WriteFile(fp, []byte{}, fs.ModePerm); err != nil {
76+ d.logger.Error("failed to write git-daemon-export-ok", "repo", name, "err", err)
77+ return err
78+ }
79+ } else {
80+ if _, err := os.Stat(fp); err == nil {
81+ if err := os.Remove(fp); err != nil {
82+ d.logger.Error("failed to remove git-daemon-export-ok", "repo", name, "err", err)
83+ return err
84+ }
85+ }
86+ }
87+
88+ return d.store.SetRepoIsPrivateByName(ctx, tx, name, private)
89 }),
90 )
91 }
92diff --git a/testscript/script_test.go b/testscript/script_test.go
93index 032bd47eb2be04bb400925a9f589eac1766e429a..dbb8b956f53b173c38df509acfb379bb600bca23 100644
94--- a/testscript/script_test.go
95+++ b/testscript/script_test.go
96@@ -52,6 +52,7 @@ func TestScript(t *testing.T) {
97 "usoft": cmdSoft(user1.Signer()),
98 "git": cmdGit(key),
99 "mkfile": cmdMkfile,
100+ "readfile": cmdReadfile,
101 "dos2unix": cmdDos2Unix,
102 },
103 Setup: func(e *testscript.Env) error {
104@@ -67,6 +68,7 @@ func TestScript(t *testing.T) {
105 statsListen := fmt.Sprintf("localhost:%d", statsPort)
106 serverName := "Test Soft Serve"
107
108+ e.Setenv("DATA_PATH", data)
109 e.Setenv("SSH_PORT", fmt.Sprintf("%d", sshPort))
110 e.Setenv("ADMIN1_AUTHORIZED_KEY", admin1.AuthorizedKey())
111 e.Setenv("ADMIN2_AUTHORIZED_KEY", admin2.AuthorizedKey())
112@@ -250,3 +252,7 @@ func check(ts *testscript.TestScript, err error, neg bool) {
113 ts.Check(err)
114 }
115 }
116+
117+func cmdReadfile(ts *testscript.TestScript, neg bool, args []string) {
118+ ts.Stdout().Write([]byte(ts.ReadFile(args[0])))
119+}
120diff --git a/testscript/testdata/mirror.txtar b/testscript/testdata/mirror.txtar
121index 7dcdb6c59b40aa11edc15f6d7f90d1414f4aabc5..77b4bc281414c98620f0ba3b34cfc5e6447baa68 100644
122--- a/testscript/testdata/mirror.txtar
123+++ b/testscript/testdata/mirror.txtar
124@@ -6,6 +6,9 @@
125 # import a repo
126 soft repo import --mirror charmbracelet/catwalk https://github.com/charmbracelet/catwalk.git
127
128+# check empty description file
129+readfile $DATA_PATH/repos/charmbracelet/catwalk.git/description ''
130+
131 # check repo info
132 soft repo info charmbracelet/catwalk
133 cmp stdout info1.txt
134@@ -32,6 +35,7 @@ soft repo description charmbracelet/catwalk
135 soft repo description charmbracelet/catwalk "testing repo"
136 soft repo description charmbracelet/catwalk
137 stdout 'testing repo'
138+readfile $DATA_PATH/repos/charmbracelet/catwalk.git/description 'testing repo'
139
140 # rename
141 soft repo rename charmbracelet/catwalk charmbracelet/test
142@@ -41,11 +45,13 @@ stdout charmbracelet/test # TODO: shouldn't this still show the project-name?
143 # check its not private
144 soft repo private charmbracelet/test
145 stdout false
146+exists $DATA_PATH/repos/charmbracelet/test.git/git-daemon-export-ok
147
148 # make it private
149 soft repo private charmbracelet/test true
150 soft repo private charmbracelet/test
151 stdout true
152+! exists $DATA_PATH/repos/charmbracelet/test.git/git-daemon-export-ok
153
154 # check its not hidden
155 soft repo hidden charmbracelet/test
156diff --git a/testscript/testdata/repo-create.txtar b/testscript/testdata/repo-create.txtar
157index 633142202c19dae41e0878d1431a1a66027a4e31..31c7028b8faaea888e34fad9f2b6f2211b08dfbf 100644
158--- a/testscript/testdata/repo-create.txtar
159+++ b/testscript/testdata/repo-create.txtar
160@@ -9,8 +9,10 @@ soft repo hidden repo1
161 stdout true
162 soft repo private repo1
163 stdout true
164+! exists $DATA_PATH/repos/repo1.git/git-daemon-export-ok
165 soft repo description repo1
166 stdout 'description'
167+readfile $DATA_PATH/repos/repo1.git/description 'description'
168 soft repo project-name repo1
169 stdout 'repo1'
170