/
tree_cloner.go
91 lines (79 loc) · 2.07 KB
/
tree_cloner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package app
import (
"log"
"github.com/chigopher/pathlib"
"github.com/kmazurek/gitlab-tree-clone/internal/domain"
"github.com/kmazurek/gitlab-tree-clone/internal/util"
"golang.org/x/sync/errgroup"
)
type TreeCloner struct {
errGroup *errgroup.Group
gitClient domain.GitClient
gitlabClient domain.GitlabClient
ignoreIDs map[int]bool
ignoreNames map[string]bool
}
func NewTreeCloner(
gitClient domain.GitClient,
gitlabClient domain.GitlabClient,
errGroup *errgroup.Group,
ignoreIDs []int,
ignoreNames []string) (*TreeCloner, error) {
var idMap = make(map[int]bool)
for _, id := range ignoreIDs {
idMap[id] = true
}
var nameMap = make(map[string]bool)
for _, name := range ignoreNames {
nameMap[name] = true
}
return &TreeCloner{
errGroup: errGroup,
gitClient: gitClient,
gitlabClient: gitlabClient,
ignoreIDs: idMap,
ignoreNames: nameMap,
}, nil
}
func (tc *TreeCloner) CloneTree(groupID int, path *pathlib.Path) error {
group, err := tc.gitlabClient.GetGroup(groupID)
if err != nil {
return err
}
return tc.cloneGroup(group.ID, group.Name, path)
}
func (tc *TreeCloner) cloneGroup(groupID int, groupName string, path *pathlib.Path) error {
log.Println("Cloning group:", groupName, "to path:", path.String())
groupPath := path.Join(groupName)
err := groupPath.MkdirAll()
if err != nil {
return err
}
subgroups, err := tc.gitlabClient.ListSubgroups(groupID)
if err != nil {
return err
}
for _, subgroup := range subgroups {
subgroup := subgroup
tc.errGroup.Go(func() error {
if util.MapContains(tc.ignoreIDs, subgroup.ID) || util.MapContains(tc.ignoreNames, subgroup.Name) {
return nil
}
return tc.cloneGroup(subgroup.ID, subgroup.Name, groupPath)
})
}
projects, err := tc.gitlabClient.ListProjects(groupID)
if err != nil {
return err
}
for _, project := range projects {
project := project
invalid := project.Archived || project.EmptyRepo
if !invalid {
tc.errGroup.Go(func() error {
return tc.gitClient.CloneRepo(project.HTTPURLToRepo, groupPath.Join(project.Name))
})
}
}
return nil
}