afc0b575d06d62e763599205bb8fde5e4188f0ba
- Author
- Ayman Bagabas <ayman.bagabas@gmail.com>
- Committer
- Ayman Bagabas <ayman.bagabas@gmail.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/cmd/soft/migrate_config.go b/cmd/soft/migrate_config.go
2index 48edf556a010032b4b8a6b2827c8cb706e5b0ef4..a20cc9d41a51d71aaac9b4433150b52986892177 100644
3--- a/cmd/soft/migrate_config.go
4+++ b/cmd/soft/migrate_config.go
5@@ -7,6 +7,7 @@ import (
6 "os"
7 "path/filepath"
8 "strings"
9+ "time"
10
11 "github.com/charmbracelet/log"
12 "github.com/charmbracelet/soft-serve/git"
13@@ -14,6 +15,7 @@ import (
14 "github.com/charmbracelet/soft-serve/server/backend/sqlite"
15 "github.com/charmbracelet/soft-serve/server/config"
16 "github.com/charmbracelet/soft-serve/server/utils"
17+ gitm "github.com/gogs/git-module"
18 "github.com/spf13/cobra"
19 "golang.org/x/crypto/ssh"
20 "gopkg.in/yaml.v3"
21@@ -25,6 +27,9 @@ var (
22 Short: "Migrate config to new format",
23 Hidden: true,
24 RunE: func(cmd *cobra.Command, _ []string) error {
25+ // Disable logging timestamp
26+ log.SetReportTimestamp(false)
27+
28 keyPath := os.Getenv("SOFT_SERVE_KEY_PATH")
29 reposPath := os.Getenv("SOFT_SERVE_REPO_PATH")
30 bindAddr := os.Getenv("SOFT_SERVE_BIND_ADDRESS")
31@@ -46,7 +51,7 @@ var (
32 // Copy SSH host key
33 log.Info("Copying SSH host key...")
34 if keyPath != "" {
35- if err := os.MkdirAll(filepath.Join(cfg.DataPath, "ssh"), 0700); err != nil {
36+ if err := os.MkdirAll(filepath.Join(cfg.DataPath, "ssh"), os.ModePerm); err != nil {
37 return fmt.Errorf("failed to create ssh directory: %w", err)
38 }
39
40@@ -104,6 +109,9 @@ var (
41 }
42 }
43
44+ readme, readmePath, err := git.LatestFile(r, "README*")
45+ hasReadme := err == nil
46+
47 // Set server name
48 cfg.Name = ocfg.Name
49
50@@ -125,13 +133,17 @@ var (
51 // Copy repos
52 if reposPath != "" {
53 log.Info("Copying repos...")
54+ if err := os.MkdirAll(filepath.Join(cfg.DataPath, "repos"), os.ModePerm); err != nil {
55+ return fmt.Errorf("failed to create repos directory: %w", err)
56+ }
57+
58 dirs, err := os.ReadDir(reposPath)
59 if err != nil {
60 return fmt.Errorf("failed to read repos directory: %w", err)
61 }
62
63 for _, dir := range dirs {
64- if !dir.IsDir() {
65+ if !dir.IsDir() || dir.Name() == "config" {
66 continue
67 }
68
69@@ -140,12 +152,12 @@ var (
70 }
71
72 log.Infof(" Copying repo %s", dir.Name())
73- if err := os.MkdirAll(filepath.Join(cfg.DataPath, "repos"), 0700); err != nil {
74- return fmt.Errorf("failed to create repos directory: %w", err)
75+ src := filepath.Join(reposPath, utils.SanitizeRepo(dir.Name()))
76+ dst := filepath.Join(cfg.DataPath, "repos", utils.SanitizeRepo(dir.Name())) + ".git"
77+ if err := os.MkdirAll(dst, os.ModePerm); err != nil {
78+ return fmt.Errorf("failed to create repo directory: %w", err)
79 }
80
81- src := utils.SanitizeRepo(filepath.Join(reposPath, dir.Name()))
82- dst := utils.SanitizeRepo(filepath.Join(cfg.DataPath, "repos", dir.Name())) + ".git"
83 if err := copyDir(src, dst); err != nil {
84 return fmt.Errorf("failed to copy repo: %w", err)
85 }
86@@ -154,26 +166,100 @@ var (
87 fmt.Fprintf(os.Stderr, "failed to create repository: %s\n", err)
88 }
89 }
90+
91+ if hasReadme {
92+ log.Infof(" Copying readme from \"config\" to \".soft-serve\"")
93+
94+ // Switch to main branch
95+ bcmd := git.NewCommand("branch", "-M", "main")
96+
97+ rp := filepath.Join(cfg.DataPath, "repos", ".soft-serve.git")
98+ nr, err := git.Init(rp, true)
99+ if err != nil {
100+ return fmt.Errorf("failed to init repo: %w", err)
101+ }
102+
103+ if _, err := nr.SymbolicRef("HEAD", gitm.RefsHeads+"main"); err != nil {
104+ return fmt.Errorf("failed to set HEAD: %w", err)
105diff --git a/git/utils.go b/git/utils.go
106new file mode 100644
107index 0000000000000000000000000000000000000000..2b3d287285f8abf0a80a2c3084f2e97a246ce6ab
108--- /dev/null
109+++ b/git/utils.go
110@@ -0,0 +1,51 @@
111+package git
112+
113+import (
114+ "path/filepath"
115+
116+ "github.com/gobwas/glob"
117+)
118+
119+// LatestFile returns the contents of the first file at the specified path pattern in the repository and its file path.
120+func LatestFile(repo *Repository, pattern string) (string, string, error) {
121+ g := glob.MustCompile(pattern)
122+ dir := filepath.Dir(pattern)
123+ head, err := repo.HEAD()
124+ if err != nil {
125+ return "", "", err
126+ }
127+ t, err := repo.TreePath(head, dir)
128+ if err != nil {
129+ return "", "", err
130+ }
131+ ents, err := t.Entries()
132+ if err != nil {
133+ return "", "", err
134+ }
135+ for _, e := range ents {
136+ te := e
137+ fp := filepath.Join(dir, te.Name())
138+ if te.IsTree() {
139+ continue
140+ }
141+ if g.Match(fp) {
142+ if te.IsSymlink() {
143+ bts, err := te.Contents()
144+ if err != nil {
145+ return "", "", err
146+ }
147+ fp = string(bts)
148+ te, err = t.TreeEntry(fp)
149+ if err != nil {
150+ return "", "", err
151+ }
152+ }
153+ bts, err := te.Contents()
154+ if err != nil {
155+ return "", "", err
156+ }
157+ return string(bts), fp, nil
158+ }
159+ }
160+ return "", "", ErrFileNotFound
161+}
162diff --git a/go.mod b/go.mod
163index e6c7c0fe02ae29e8dc6eb4c6d5da581ee5d5bea9..6475eae923607d11c45877380d387dab8cb0593f 100644
164--- a/go.mod
165+++ b/go.mod
166@@ -18,7 +18,6 @@ require (
167 )
168
169 require (
170- github.com/aymanbagabas/go-osc52 v1.2.2
171 github.com/caarlos0/env/v7 v7.1.0
172 github.com/charmbracelet/keygen v0.4.2
173 github.com/charmbracelet/log v0.2.1
174diff --git a/go.sum b/go.sum
175index 1ea72fe0d34a0fc8147244823532d1399f086803..876c5c3c5fdd6a752393733fc96394cb4beaec34 100644
176--- a/go.sum
177+++ b/go.sum
178@@ -49,9 +49,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
179 github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
180 github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
181 github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
182+github.com/aymanbagabas/go-osc52 v1.2.1 h1:q2sWUyDcozPLcLabEMd+a+7Ea2DitxZVN9hTxab9L4E=
183 github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
184-github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo=
185-github.com/aymanbagabas/go-osc52 v1.2.2/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
186 github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
187 github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
188 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
189diff --git a/server/backend/sqlite/sqlite.go b/server/backend/sqlite/sqlite.go
190index bc69e2628cb5c90ade79b40a84e2a358d0a13bca..382c99ff3e32005802de520ab5b6dcd273f05303 100644
191--- a/server/backend/sqlite/sqlite.go
192+++ b/server/backend/sqlite/sqlite.go
193@@ -40,7 +40,7 @@ func (d *SqliteBackend) reposPath() string {
194 // NewSqliteBackend creates a new SqliteBackend.
195 func NewSqliteBackend(ctx context.Context, cfg *config.Config) (*SqliteBackend, error) {
196 dataPath := cfg.DataPath
197- if err := os.MkdirAll(dataPath, 0755); err != nil {
198+ if err := os.MkdirAll(dataPath, os.ModePerm); err != nil {
199 return nil, err
200 }
201
202@@ -254,7 +254,7 @@ func (d *SqliteBackend) RenameRepository(oldName string, newName string) error {
203 }
204
205 // Make sure the new repository parent directory exists.
206- if err := os.MkdirAll(filepath.Dir(np), 0755); err != nil {
207+ if err := os.MkdirAll(filepath.Dir(np), os.ModePerm); err != nil {
208 return err
209 }
210
211@@ -639,7 +639,7 @@ func (d *SqliteBackend) InitializeHooks(repo string) error {
212
213 repo = utils.SanitizeRepo(repo) + ".git"
214 hooksPath := filepath.Join(d.reposPath(), repo, "hooks")
215- if err := os.MkdirAll(hooksPath, 0755); err != nil {
216+ if err := os.MkdirAll(hooksPath, os.ModePerm); err != nil {
217 return err
218 }
219
220@@ -659,13 +659,13 @@ func (d *SqliteBackend) InitializeHooks(repo string) error {
221 var data bytes.Buffer
222 var args string
223 hp := filepath.Join(hooksPath, hook)
224- if err := os.WriteFile(hp, []byte(hookTpls[i]), 0755); err != nil {
225+ if err := os.WriteFile(hp, []byte(hookTpls[i]), os.ModePerm); err != nil {
226 return err
227 }
228
229 // Create hook.d directory.
230 hp += ".d"
231- if err := os.MkdirAll(hp, 0755); err != nil {
232+ if err := os.MkdirAll(hp, os.ModePerm); err != nil {
233 return err
234 }
235
236@@ -694,7 +694,7 @@ func (d *SqliteBackend) InitializeHooks(repo string) error {
237 }
238
239 hp = filepath.Join(hp, "soft-serve")
240- err = os.WriteFile(hp, data.Bytes(), 0755) //nolint:gosec
241+ err = os.WriteFile(hp, data.Bytes(), os.ModePerm) //nolint:gosec
242 if err != nil {
243 logger.Error("failed to write hook", "err", err)
244 continue
245diff --git a/server/backend/utils.go b/server/backend/utils.go
246index c6cdff4db8d7d4d36b90d75e53235a95a369731e..e2724402c1165ec073803d2a94e97c50d89a0b2d 100644
247--- a/server/backend/utils.go
248+++ b/server/backend/utils.go
249@@ -1,59 +1,17 @@
250 package backend
251
252 import (
253- "path/filepath"
254-
255 "github.com/charmbracelet/soft-serve/git"
256- "github.com/gobwas/glob"
257 )
258
259 // LatestFile returns the contents of the latest file at the specified path in
260 // the repository and its file path.
261 func LatestFile(r Repository, pattern string) (string, string, error) {
262- g := glob.MustCompile(pattern)
263- dir := filepath.Dir(pattern)
264 repo, err := r.Open()
265 if err != nil {
266 return "", "", err
267 }
268- head, err := repo.HEAD()
269- if err != nil {
270- return "", "", err
271- }
272- t, err := repo.TreePath(head, dir)
273- if err != nil {
274- return "", "", err
275- }
276- ents, err := t.Entries()
277- if err != nil {
278- return "", "", err
279- }
280- for _, e := range ents {
281- te := e
282- fp := filepath.Join(dir, te.Name())
283- if te.IsTree() {
284- continue
285- }
286- if g.Match(fp) {
287- if te.IsSymlink() {
288- bts, err := te.Contents()
289- if err != nil {
290- return "", "", err
291- }
292- fp = string(bts)
293- te, err = t.TreeEntry(fp)
294- if err != nil {
295- return "", "", err
296- }
297- }
298- bts, err := te.Contents()
299- if err != nil {
300- return "", "", err
301- }
302- return string(bts), fp, nil
303- }
304- }
305- return "", "", git.ErrFileNotFound
306+ return git.LatestFile(repo, pattern)
307 }
308
309 // Readme returns the repository's README.
310diff --git a/server/config/config.go b/server/config/config.go
311index 4c2373c52efc60a26f87c72cd8a92f57f8e4d739..7c598548430b8f846cea8d1e86bc75892ff44670 100644
312--- a/server/config/config.go
313+++ b/server/config/config.go
314@@ -203,10 +203,10 @@ func ParseConfig(path string) (*Config, error) {
315
316 // WriteConfig writes the configuration to the given file.
317 func WriteConfig(path string, cfg *Config) error {
318- if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
319+ if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
320 return err
321 }
322- return os.WriteFile(path, []byte(newConfigFile(cfg)), 0o600) // nolint: errcheck
323+ return os.WriteFile(path, []byte(newConfigFile(cfg)), 0o644) // nolint: errcheck
324 }
325
326 // DefaultConfig returns a Config with the values populated with the defaults
327diff --git a/server/config/config_test.go b/server/config/config_test.go
328index f4cc8f16942db8b1b50735f8fd91803ca6d3a8aa..3812e4f9e72b871f3611b53ee2a1db1a12c803cd 100644
329--- a/server/config/config_test.go
330+++ b/server/config/config_test.go
331@@ -34,7 +34,7 @@ func TestMergeInitAdminKeys(t *testing.T) {
332 })
333 is.NoErr(err)
334 fp := filepath.Join(t.TempDir(), "config.yaml")
335- err = os.WriteFile(fp, bts, 0644)
336+ err = os.WriteFile(fp, bts, 0o644)
337 is.NoErr(err)
338 cfg, err := ParseConfig(fp)
339 is.NoErr(err)
340@@ -55,7 +55,7 @@ func TestValidateInitAdminKeys(t *testing.T) {
341 })
342 is.NoErr(err)
343 fp := filepath.Join(t.TempDir(), "config.yaml")
344- err = os.WriteFile(fp, bts, 0644)
345+ err = os.WriteFile(fp, bts, 0o644)
346 is.NoErr(err)
347 cfg, err := ParseConfig(fp)
348 is.NoErr(err)