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}