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) GetRepositories(ctx context.Context) ([]string, error) {
54 entries, err := os.ReadDir(m.conf.PathRepositories())
55 if err != nil {
56 return nil, oops.With("dataDir", m.conf.PathRepositories()).Wrapf(err, "can't read dir data")
57 }
58 repoNames := []string{}
59 for _, e := range entries {
60 name := e.Name()
61 if name != "." && name != ".." {
62 repoNames = append(repoNames, e.Name())
63 }
64 }
65 return repoNames, nil
66}
67
68func (m *Manager) ForgeRepoMakeDiffRepos(ctx context.Context, repositories []byte) ([]RepoConf, []string, error) {
69 entries, err := os.ReadDir(m.conf.PathRepositories())
70 if err != nil {
71 return nil, nil, oops.With("dataDir", m.conf.PathRepositories()).Wrapf(err, "can't read dir data")
72 }
73
74 reposInFile, err := fromFileContent(repositories)
75 if err != nil {
76 oops.Wrapf(err, "can't decode file repositories")
77 }
78
79 m.logger.Debug("reposDiff", logger.NewLoggerPair("repositories", string(repositories)))
80
81 repoToCreate := make([]RepoConf, 0)
82 repoToDelete := make([]string, 0)
83
84 for _, repo := range reposInFile {
85 found := false
86 for _, e := range entries {
87 if e.Name() == repo.Name {
88 found = true
89 break
90 }
91 }
92 if !found {
93 repoToCreate = append(repoToCreate, repo)
94 }
95 }
96
97 for _, e := range entries {
98 found := false
99 for _, repo := range reposInFile {
100 if e.Name() == repo.Name {
101 found = true
102 break
103 }
104 }
105 if !found {
106 repoToDelete = append(repoToDelete, e.Name())
107 }
108 }
109
110 return repoToCreate, repoToDelete, nil
111}