summaryrefslogtreecommitdiff
path: root/clone.go
blob: 164e354f8b9e8841544f18e0482beea8fa8e4e3d (plain)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main

import (
	"errors"
	"os"
	"path/filepath"

	"go.wit.com/lib/gui/shell"
	"go.wit.com/lib/protobuf/gitpb"
	"go.wit.com/log"
)

func clone(gopath string) (*gitpb.Repo, error) {
	// if the user defined a repo, attempt to download it now
	if gopath == "" {
		// nothing to clone
		// user probably wants to --recursive on current working dir
		return nil, errors.New("gopath was blank")
	}
	os.Setenv("REPO_AUTO_CLONE", "true")
	// pb, _ := forge.NewGoPath(gopath)
	check := forge.Repos.FindByGoPath(gopath)
	if check != nil {
		if check.IsValid() {
			// repo already exists and is valid
			return check, nil
		}
	}
	pb, err := forge.Clone(gopath)
	if err != nil {
		log.Info("clone() could not download err:", err)
		return nil, err
	}

	// first try to generate go.mod & go.sum with go-mod-clean
	if err := pb.ValidGoSum(); err != nil {
		// update go.sum and go.mod
		if err := pb.RunStrict([]string{"go-mod-clean"}); err != nil {
			log.Info("")
			log.Info("Do you have go-mod-clean? Otherwise:")
			log.Info("  go install go.wit.com/apps/go-mod-clean@latest")
			log.Info("")
		}
	}
	// if this fails, just use go mod
	if err := pb.ValidGoSum(); err != nil {
		if err := pb.RunStrict([]string{"go", "mod", "init", pb.GoPath}); err != nil {
			log.Info("go mod init failed", err)
		}
		if err := pb.RunStrict([]string{"go", "mod", "tidy"}); err != nil {
			log.Info("go mod tidy failed", err)
		}
	}
	if err := pb.ValidGoSum(); err != nil {
		// have to give up. can't recursive clone without go.mod file
		log.Info("could not generate valid go.sum file")
		return nil, err
	}
	pb.ParseGoSum()

	// double check it actually downloaded
	fullgitdir := filepath.Join(forge.GetGoSrc(), gopath, ".git")
	if !shell.IsDir(fullgitdir) {
		log.Info("repo cloned failed", filepath.Join(forge.GetGoSrc(), gopath))
		return nil, errors.New(fullgitdir + " was not created")
	}
	log.Info("onward and upward")
	return pb, nil
}

// really only does go.sum things
// so not 'really' recursive
// but that is because go.sum is supposed
// to have everything required in it
func recursiveClone(check *gitpb.Repo) error {
	var good int
	var bad int

	if check == nil {
		return errors.New("repo was nil")
	}
	log.Info("STARTING RECURSIVE CLONE", check.GoPath)
	log.Info("STARTING RECURSIVE CLONE", check.GoPath)
	if check.GoPrimitive {
		log.Info("repo is a primitive", check.GoPath)
		// go primitive repos are "pure"
		return nil
	}

	// if just cloned, parse the go.sum file for deps
	check.ParseGoSum()

	if check.GoDeps == nil {
		log.Info("repo godeps == nil", check.GoPath)
		return errors.New("go.sum is missing?")
	}

	// probably this should never be 0 because GoPrimitive should have been true otherwise
	if check.GoDeps.Len() == 0 {
		log.Info("repo len(godeps) == 0", check.GoPath)
		return errors.New("go.sum never parsed?")
	}

	log.Info("deps for", check.GoPath, "len()", check.GoDeps.Len())
	deps := check.GoDeps.SortByGoPath()
	for deps.Scan() {
		depRepo := deps.Next()
		log.Info("download:", depRepo.GoPath)
		_, err := clone(depRepo.GoPath)
		if err != nil {
			log.Info("recursiveClone() could not download", depRepo.GoPath)
			log.Info("err:", err)
			bad += 1
		} else {
			log.Info("downloaded", depRepo.GoPath)
			good += 1
		}
	}
	log.Info("got", good, "repos", "failed on", bad, "repos")
	if bad != 0 {
		return errors.New("clone failed on some repos")
	}
	return nil
}