forked from openshift/origin
/
git.go
78 lines (64 loc) · 1.86 KB
/
git.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
package git
import (
"net/url"
"os"
"regexp"
"strings"
"github.com/openshift/source-to-image/pkg/sti/util"
)
// Git is an interface used by main STI code to extract/checkout git repositories
type Git interface {
ValidCloneSpec(source string) bool
Clone(source, target string) error
Checkout(repo, ref string) error
}
// NewGit returns a new instance of the default implementation of the Git interface
func NewGit() Git {
return &stiGit{
runner: util.NewCommandRunner(),
}
}
type stiGit struct {
runner util.CommandRunner
}
var gitSshUrlExp = regexp.MustCompile(`\A([\w\d\-_\.+]+@[\w\d\-_\.+]+:[\w\d\-_\.+%/]+\.git)$`)
var allowedSchemes = []string{"git", "http", "https", "file"}
func stringInSlice(s string, slice []string) bool {
for _, element := range slice {
if s == element {
return true
}
}
return false
}
// ValidCloneSpec determines if the given string reference points to a valid git
// repository
func (h *stiGit) ValidCloneSpec(source string) bool {
url, err := url.Parse(source)
if err != nil {
return false
}
if stringInSlice(url.Scheme, allowedSchemes) {
return true
}
// support 'git@' ssh urls and local protocol without 'file://' scheme
return url.Scheme == "" && (strings.HasSuffix(source, ".git") ||
(strings.HasPrefix(source, "git@") && gitSshUrlExp.MatchString(source)))
}
// Clone clones a git repository to a specific target directory
func (h *stiGit) Clone(source, target string) error {
opts := util.CommandOpts{
Stdout: os.Stdout,
Stderr: os.Stderr,
}
return h.runner.RunWithOptions(opts, "git", "clone", "--recursive", source, target)
}
// Checkout checks out a specific branch reference of a given git repository
func (h *stiGit) Checkout(repo, ref string) error {
opts := util.CommandOpts{
Stdout: os.Stdout,
Stderr: os.Stderr,
Dir: repo,
}
return h.runner.RunWithOptions(opts, "git", "checkout", ref)
}