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}