-
Notifications
You must be signed in to change notification settings - Fork 33
/
backup.go
109 lines (94 loc) · 2.74 KB
/
backup.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main
import (
"log"
"net/url"
"os/exec"
"path"
"sync"
"github.com/mitchellh/go-homedir"
"github.com/spf13/afero"
)
// We have them here so that we can override these in the tests
var execCommand = exec.Command
var appFS = afero.NewOsFs()
var gitCommand = "git"
var gethomeDir = homedir.Dir
// Check if we have a copy of the repo already, if
// we do, we update the repo, else we do a fresh clone
func backUp(backupDir string, repo *Repository, bare bool, wg *sync.WaitGroup) ([]byte, error) {
defer wg.Done()
var dirName string
if bare {
dirName = repo.Name + ".git"
} else {
dirName = repo.Name
}
repoDir := path.Join(backupDir, repo.Namespace, dirName)
_, err := appFS.Stat(repoDir)
var stdoutStderr []byte
if err == nil {
log.Printf("%s exists, updating. \n", repo.Name)
var cmd *exec.Cmd
if bare {
cmd = execCommand(gitCommand, "-C", repoDir, "remote", "update", "--prune")
} else {
cmd = execCommand(gitCommand, "-C", repoDir, "pull")
}
stdoutStderr, err = cmd.CombinedOutput()
} else {
log.Printf("Cloning %s\n", repo.Name)
log.Printf("%#v\n", repo)
if repo.Private && ignorePrivate != nil && *ignorePrivate {
log.Printf("Skipping %s as it is a private repo.\n", repo.Name)
return stdoutStderr, nil
}
if useHTTPSClone != nil && *useHTTPSClone {
// Add username and token to the clone URL
// https://gitlab.com/amitsaha/testproject1 => https://amitsaha:[email protected]/amitsaha/testproject1
u, err := url.Parse(repo.CloneURL)
if err != nil {
log.Fatalf("Invalid clone URL: %v\n", err)
}
repo.CloneURL = u.Scheme + "://" + gitHostUsername + ":" + gitHostToken + "@" + u.Host + u.Path
}
var cmd *exec.Cmd
if bare {
cmd = execCommand(gitCommand, "clone", "--mirror", repo.CloneURL, repoDir)
} else {
cmd = execCommand(gitCommand, "clone", repo.CloneURL, repoDir)
}
stdoutStderr, err = cmd.CombinedOutput()
}
return stdoutStderr, err
}
func setupBackupDir(backupDir, service, githostURL *string) string {
var gitHost, backupPath string
var err error
if len(*githostURL) != 0 {
u, err := url.Parse(*githostURL)
if err != nil {
panic(err)
}
gitHost = u.Host
} else {
gitHost = knownServices[*service]
}
if len(*backupDir) == 0 {
homeDir, err := gethomeDir()
if err == nil {
backupPath = path.Join(homeDir, ".gitbackup", gitHost)
} else {
log.Fatal("Could not determine home directory and backup directory not specified")
}
} else {
backupPath = path.Join(*backupDir, gitHost)
}
err = createBackupRootDirIfRequired(backupPath)
if err != nil {
log.Fatalf("Error creating backup directory: %s %v", backupPath, err)
}
return backupPath
}
func createBackupRootDirIfRequired(backupPath string) error {
return appFS.MkdirAll(backupPath, 0771)
}