-
Notifications
You must be signed in to change notification settings - Fork 51
/
modules.go
132 lines (115 loc) · 4.73 KB
/
modules.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
package main
import (
"archive/tar"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func unTar(r io.Reader, targetBaseDir string) {
funcName := funcName()
tarBallReader := tar.NewReader(r)
for {
header, err := tarBallReader.Next()
if err != nil {
if err == io.EOF {
break
}
Fatalf(funcName + "(): error while tar reader.Next() for io.Reader with targetBaseDir " + targetBaseDir + " Error: " + err.Error())
}
// get the individual filename and extract to the current directory
filename := header.Name
// check if currently extracting archive is a forge or a git module
// we need to remove the module name from the filename otherwise the skiplist pattern would not match
// e.g puppetlabs-stdlib-6.0.0/MAINTAINERS.md for a forge module
// and MAINTAINERS.md for a git module
skiplistFilename := filename
if targetBaseDir == config.ForgeCacheDir {
skiplistFilenameComponents := strings.SplitAfterN(filename, "/", 2)
if len(skiplistFilenameComponents) > 1 {
skiplistFilename = skiplistFilenameComponents[1]
}
}
if matchSkiplistContent(skiplistFilename) {
continue
}
targetFilename := filepath.Join(targetBaseDir, filename)
switch header.Typeflag {
case tar.TypeDir:
//fmt.Println("Untarring :", targetFilename)
// handle directory
//fmt.Println("Creating directory :", filename)
//err = os.MkdirAll(targetFilename, os.FileMode(header.Mode)) // or use 0755 if you prefer
err = os.MkdirAll(targetFilename, os.FileMode(0755)) // or use 0755 if you prefer
if err != nil {
Fatalf(funcName + "(): error while MkdirAll() file: " + filename + " Error: " + err.Error())
}
err = os.Chtimes(targetFilename, header.AccessTime, header.ModTime)
if err != nil {
Fatalf(funcName + "(): error while Chtimes() file: " + filename + " Error: " + err.Error())
}
case tar.TypeReg:
// handle normal file
//fmt.Println("Untarring :", targetFilename)
writer, err := os.Create(targetFilename)
if err != nil {
Fatalf(funcName + "(): error while Create() file: " + filename + " Error: " + err.Error())
}
if _, err = io.Copy(writer, tarBallReader); err != nil {
Fatalf(funcName + "(): error while io.copy() file: " + filename + " Error: " + err.Error())
}
if err = os.Chmod(targetFilename, os.FileMode(header.Mode)); err != nil {
Fatalf(funcName + "(): error while Chmod() file: " + filename + " Error: " + err.Error())
}
if err = os.Chtimes(targetFilename, header.AccessTime, header.ModTime); err != nil {
Fatalf(funcName + "(): error while Chtimes() file: " + filename + " Error: " + err.Error())
}
writer.Close()
case tar.TypeSymlink:
if fileExists(targetFilename) {
if err = os.Remove(targetFilename); err != nil {
Fatalf(funcName + "(): error while removing existing file " + targetFilename + " to be replaced with symlink pointing to " + header.Linkname + " Error: " + err.Error())
}
}
if err = os.Symlink(header.Linkname, targetFilename); err != nil {
Fatalf(funcName + "(): error while creating symlink " + targetFilename + " pointing to " + header.Linkname + " Error: " + err.Error())
}
case tar.TypeLink:
if fileExists(targetFilename) {
if err = os.Remove(targetFilename); err != nil {
Fatalf(funcName + "(): error while removing existing file " + targetFilename + " to be replaced with hardlink pointing to " + header.Linkname + " Error: " + err.Error())
}
}
if err = os.Link(header.Linkname, targetFilename); err != nil {
Fatalf(funcName + "(): error while creating hardlink " + targetFilename + " pointing to " + header.Linkname + " Error: " + err.Error())
}
// Skip pax_global_header with the commit ID this archive was created from
case tar.TypeXGlobalHeader:
continue
default:
Fatalf(funcName + "(): Unable to untar type: " + string(header.Typeflag) + " in file " + filename)
}
}
// tarball produced by git archive has trailing nulls in the stream which are not
// read by the module, when removed this can cause the git archive to hang trying
// to output the nulls into a full pipe buffer, avoid this by discarding the rest
// until the stream ends.
buf := make([]byte, 4096)
nread, err := r.Read(buf)
for nread > 0 && err == nil {
Debugf(fmt.Sprintf("Discarded %d bytes of trailing data from tar", nread))
nread, err = r.Read(buf)
}
}
func matchSkiplistContent(filePath string) bool {
for _, blPattern := range config.PurgeSkiplist {
filepathResult, _ := filepath.Match(blPattern, filePath)
if strings.HasPrefix(filePath, blPattern) || filepathResult {
Debugf("skipping file " + filePath + " because purge_skiplist pattern '" + blPattern + "' matches")
return true
}
}
//Debugf("not skipping file " + filePath + " because no purge_skiplist pattern matches")
return false
}