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}