-
Notifications
You must be signed in to change notification settings - Fork 0
/
seed.go
142 lines (125 loc) · 3.5 KB
/
seed.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main
import (
"fmt"
"github.com/otiai10/copy"
"golang.org/x/crypto/ssh"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
go_git_ssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
"io/ioutil"
"os"
"path/filepath"
)
type Seed struct {
config Config
}
func NewSeed(ci ConfigInput) (Seed, error) {
config, err := NewConfig(ci)
if err != nil {
return Seed{}, err
}
return Seed{config: config}, nil
}
func (s *Seed) clone() error {
// remove directory if exists
path := filepath.Join(s.config.cdir, "seeder")
err := os.RemoveAll(path)
if err != nil {
return err
}
// create directory
err = os.Mkdir(path, os.ModePerm)
if err != nil {
return err
}
opts := &git.CloneOptions{
URL: s.config.url.String(),
}
if s.config.proto == "ssh" && s.config.key != "" {
opts.Auth = GetSSHKeyAuth(s.config.key)
}
// set branch if defined
if s.config.branch != "" {
opts.ReferenceName = plumbing.NewBranchReferenceName(s.config.branch)
opts.SingleBranch = true
}
if s.config.quiet == false {
opts.Progress = os.Stdout
}
// clone repo
_, err = git.PlainClone(path, false, opts)
if err != nil {
return err
}
// Remove .git
if !s.config.git {
err = os.RemoveAll(filepath.Join(path, ".git"))
if err != nil {
return err
}
}
return nil
}
func (s Seed) process() error {
// absolute (Abs) paths to source and dst direct
srcDirAbs := filepath.Join(s.config.cdir, "seeder")
dstDirAbs, _ := os.Getwd()
for i, p := range s.config.src {
srcGlob := filepath.Join(srcDirAbs, p)
matches, _ := filepath.Glob(srcGlob)
// TODO: Error that source did not match any files?
matchCount := len(matches)
if matchCount == 0 {
continue
}
for _, matchSrcAbs := range matches {
// stat info of the match
matchSrcInfo, _ := os.Stat(matchSrcAbs)
// relative path of the match from the source dir (srcDirAbs)
matchSrcRel, _ := filepath.Rel(srcDirAbs, matchSrcAbs) //strings.ReplaceAll(matchSrcAbs, srcDirAbs, "")
// last element (file or dir) of the match
matchSrcBase := filepath.Base(matchSrcAbs)
// default destination uses the path as it is in the source project
matchDstAbs := filepath.Join(dstDirAbs, matchSrcRel)
// custom destination if specified
dstPath := s.config.dst[i]
if dstPath != "" {
// Set as if a destination file path was given (not a directory)
matchDstAbs = filepath.Join(dstDirAbs, s.config.dst[i])
// Determine if the user is specifying a directory by the lack of an extension
matchDstExt := filepath.Ext(matchDstAbs)
if matchDstExt == "" {
// Use the original filename as the destination file
matchDstAbs = filepath.Join(matchDstAbs, matchSrcBase)
}
}
// determine what the destination directory is
matchDstDir := matchDstAbs
if !matchSrcInfo.IsDir() {
matchDstDir = filepath.Dir(matchDstAbs)
}
// create the destination directory if it doesn't exist
if _, err := os.Stat(matchDstDir); os.IsNotExist(err) {
_ = os.MkdirAll(matchDstDir, os.ModePerm)
}
// print cli output
if !s.config.quiet {
fmt.Println("copying:", matchDstAbs)
}
// copy
err := copy.Copy(matchSrcAbs, matchDstAbs)
if err != nil {
return err
}
}
}
return nil
}
func GetSSHKeyAuth(privateSshKeyFile string) transport.AuthMethod {
var auth transport.AuthMethod
sshKey, _ := ioutil.ReadFile(privateSshKeyFile)
signer, _ := ssh.ParsePrivateKey([]byte(sshKey))
auth = &go_git_ssh.PublicKeys{User: "git", Signer: signer}
return auth
}