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	"errors"
 9
10	"github.com/go-git/go-git/v6/plumbing"
11	"github.com/goccy/go-yaml"
12)
13
14type repoConfiguration struct {
15	DefaultBranch                         string
16	NoForcePush                           []string
17	NbMaxBranchesBeforeRejectingAnonymous int
18}
19
20type RepoConfiguration struct {
21	DefaultBranch                         plumbing.ReferenceName
22	NoForcePush                           []plumbing.ReferenceName
23	NbMaxBranchesBeforeRejectingAnonymous int
24}
25
26func newRepoConfiguration(defaultBranch string, nbMaxBranchesBeforeRejectingAnonymous int) repoConfiguration {
27	return repoConfiguration{
28		DefaultBranch:                         defaultBranch,
29		NoForcePush:                           []string{defaultBranch},
30		NbMaxBranchesBeforeRejectingAnonymous: nbMaxBranchesBeforeRejectingAnonymous,
31	}
32}
33
34func (r repoConfiguration) toFileContent() []byte {
35	content, _ := yaml.Marshal(r)
36	return content
37}
38
39func readRepoConfiguration(fileContent []byte) (RepoConfiguration, error) {
40	repoConf := repoConfiguration{}
41	err := yaml.Unmarshal(fileContent, &repoConf)
42	if err != nil {
43		return RepoConfiguration{}, err
44	}
45	noForcePush := make([]plumbing.ReferenceName, len(repoConf.NoForcePush))
46	for i, rc := range repoConf.NoForcePush {
47		noForcePush[i] = plumbing.NewBranchReferenceName(rc)
48	}
49	return RepoConfiguration{
50		DefaultBranch:                         plumbing.NewBranchReferenceName(repoConf.DefaultBranch),
51		NoForcePush:                           noForcePush,
52		NbMaxBranchesBeforeRejectingAnonymous: repoConf.NbMaxBranchesBeforeRejectingAnonymous,
53	}, nil
54}
55
56func (r RepoConfiguration) IsNoPushBranch(branch plumbing.ReferenceName) bool {
57	for _, b := range r.NoForcePush {
58		if b == branch {
59			return true
60		}
61	}
62	return false
63}
64
65func (r RepoConfiguration) CanCreateAnonymousBranch(repo *GitRootRepository, globalNbBranches int) error {
66	projectNbBranches := r.NbMaxBranchesBeforeRejectingAnonymous
67	if globalNbBranches == 0 || projectNbBranches == 0 {
68		return errors.New("anonymous branches not allowed")
69	} else if globalNbBranches > 0 || projectNbBranches > 0 {
70		branches, err := repo.Branches()
71		if err != nil {
72			return errors.New("error in couting branches")
73		}
74		goodGlobal := globalNbBranches == -1 || len(branches) < globalNbBranches
75		goodLocal := projectNbBranches == -1 || len(branches) < projectNbBranches
76		if !goodGlobal || !goodLocal {
77			return errors.New("max anonymous branches reach, please retry later")
78		}
79	}
80	return nil
81}