GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5package repository
6
7import (
8 "context"
9 "os"
10
11 "github.com/goccy/go-yaml"
12 "github.com/samber/oops"
13 "gitroot.dev/server/logger"
14)
15
16type RepoKind string
17
18const (
19 RepoKindNormal = "normal"
20 RepoKindFork = "fork"
21)
22
23type RepoConf struct {
24 Name string `yaml:"-"`
25 Kind RepoKind
26 DefaultBranch string
27 Owners []string
28 ForkUrl string
29}
30
31func fromFileContent(fileContent []byte) ([]RepoConf, error) {
32 repositories := make([]RepoConf, 0)
33 repositoriesByName := make(map[string]RepoConf)
34 if err := yaml.UnmarshalWithOptions(fileContent, &repositoriesByName, yaml.UseOrderedMap()); err != nil {
35 return nil, oops.Wrapf(err, "can't parse yaml users")
36 }
37 for name, repo := range repositoriesByName {
38 repo.Name = name
39 repositories = append(repositories, repo)
40 }
41 return repositories, nil
42}
43
44func toFileContent(repositories []RepoConf) ([]byte, error) {
45 u := make(map[string]RepoConf)
46 for _, j := range repositories {
47 u[j.Name] = j
48 }
49 content, err := yaml.Marshal(u)
50 return content, oops.Wrapf(err, "can't marshal yaml repositories")
51}
52
53func (m *Manager) ForgeRepoMakeDiffRepos(ctx context.Context, repositories []byte) ([]RepoConf, []string, error) {
54 entries, err := os.ReadDir(m.conf.PathRepositories())
55 if err != nil {
56 return nil, nil, oops.With("dataDir", m.conf.PathRepositories()).Wrapf(err, "can't read dir data")
57 }
58
59 reposInFile, err := fromFileContent(repositories)
60 if err != nil {
61 oops.Wrapf(err, "can't decode file repositories")
62 }
63
64 m.logger.Debug("reposDiff", logger.NewLoggerPair("repositories", string(repositories)))
65
66 repoToCreate := make([]RepoConf, 0)
67 repoToDelete := make([]string, 0)
68
69 for _, repo := range reposInFile {
70 found := false
71 for _, e := range entries {
72 if e.Name() == repo.Name {
73 found = true
74 break
75 }
76 }
77 if !found {
78 repoToCreate = append(repoToCreate, repo)
79 }
80 }
81
82 for _, e := range entries {
83 found := false
84 for _, repo := range reposInFile {
85 if e.Name() == repo.Name {
86 found = true
87 break
88 }
89 }
90 if !found {
91 repoToDelete = append(repoToDelete, e.Name())
92 }
93 }
94
95 return repoToCreate, repoToDelete, nil
96}