forked from GeertJohan/go.rice
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathappended.go
163 lines (149 loc) · 4.97 KB
/
appended.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package rice
import (
"archive/zip"
"os"
"time"
)
// appendedBox defines an appended box
type appendedBox struct {
Name string // box name
Files map[string]*appendedFile // appended files (*zip.File) by full path
Time time.Time
}
type appendedFile struct {
zipFile *zip.File
dir bool
dirInfo *appendedDirInfo
children []*appendedFile
content []byte
}
// appendedBoxes is a public register of appendes boxes
var appendedBoxes = make(map[string]*appendedBox)
func init() {
// FIXME: Reenable the code when a fix of the zipreader is available.
// The following code is commented out since it produce a panic even if the append feature of go.rice was not used.
// The panic is
// panic: runtime error: invalid memory address or nil pointer dereference
// [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x9d8266]
//
// goroutine 1 [running]:
// debug/elf.(*Section).ReadAt(0xc000512000?, {0xc0002bc240?, 0x70?, 0x7fa657540fff?}, 0x7fa657366000?)
// <autogenerated>:1 +0x26
// archive/zip.readDirectoryEnd({0xfb6b00, 0xc000051480}, 0x210)
// /usr/local/go/src/archive/zip/reader.go:526 +0xf5
// archive/zip.(*Reader).init(0xc00049e4d0, {0xfb6b00?, 0xc000051480}, 0x210)
// /usr/local/go/src/archive/zip/reader.go:97 +0x5c
// archive/zip.NewReader({0xfb6b00, 0xc000051480}, 0x210)
// /usr/local/go/src/archive/zip/reader.go:90 +0x5e
// github.com/daaku/go%2ezipexe.zipExeReaderElf({0xfb8e20?, 0xc000012708}, 0x197499a)
// /home/folder/pkg/mod/github.com/daaku/[email protected]/zipexe.go:128 +0x8b
// github.com/daaku/go%2ezipexe.NewReader({0xfb8e20, 0xc000012708}, 0x0?)
// /home/folder/pkg/mod/github.com/daaku/[email protected]/zipexe.go:48 +0x98
// github.com/daaku/go%2ezipexe.OpenCloser({0xc000046960?, 0xc00045fab0?})
// /home/folder/pkg/mod/github.com/daaku/[email protected]/zipexe.go:30 +0x57
// github.com/GeertJohan/go%2erice.init.0()
// /home/foldere/go.rice/appended.go:42 +0x65
/*
// find if exec is appended
thisFile, err := os.Executable()
if err != nil {
return // not appended or cant find self executable
}
thisFile, err = filepath.EvalSymlinks(thisFile)
if err != nil {
return
}
closer, rd, err := zipexe.OpenCloser(thisFile)
if err != nil {
return // not appended
}
defer closer.Close()
for _, f := range rd.File {
// get box and file name from f.Name
fileParts := strings.SplitN(strings.TrimLeft(filepath.ToSlash(f.Name), "/"), "/", 2)
boxName := fileParts[0]
var fileName string
if len(fileParts) > 1 {
fileName = fileParts[1]
}
// find box or create new one if doesn't exist
box := appendedBoxes[boxName]
if box == nil {
box = &appendedBox{
Name: boxName,
Files: make(map[string]*appendedFile),
Time: f.ModTime(),
}
appendedBoxes[boxName] = box
}
// create and add file to box
af := &appendedFile{
zipFile: f,
}
if f.Comment == "dir" {
af.dir = true
af.dirInfo = &appendedDirInfo{
name: filepath.Base(af.zipFile.Name),
time: af.zipFile.ModTime(),
}
} else {
// this is a file, we need it's contents so we can create a bytes.Reader when the file is opened
// make a new byteslice
af.content = make([]byte, af.zipFile.FileInfo().Size())
// ignore reading empty files from zip (empty file still is a valid file to be read though!)
if len(af.content) > 0 {
// open io.ReadCloser
rc, err := af.zipFile.Open()
if err != nil {
af.content = nil // this will cause an error when the file is being opened or seeked (which is good)
// TODO: it's quite blunt to just log this stuff. but this is in init, so rice.Debug can't be changed yet..
log.Printf("error opening appended file %s: %v", af.zipFile.Name, err)
} else {
_, err = rc.Read(af.content)
rc.Close()
if err != nil {
af.content = nil // this will cause an error when the file is being opened or seeked (which is good)
// TODO: it's quite blunt to just log this stuff. but this is in init, so rice.Debug can't be changed yet..
log.Printf("error reading data for appended file %s: %v", af.zipFile.Name, err)
}
}
}
}
// add appendedFile to box file list
box.Files[fileName] = af
// add to parent dir (if any)
dirName := filepath.Dir(fileName)
if dirName == "." {
dirName = ""
}
if fileName != "" { // don't make box root dir a child of itself
if dir := box.Files[dirName]; dir != nil {
dir.children = append(dir.children, af)
}
}
}*/
}
// implements os.FileInfo.
// used for Readdir()
type appendedDirInfo struct {
name string
time time.Time
}
func (adi *appendedDirInfo) Name() string {
return adi.name
}
func (adi *appendedDirInfo) Size() int64 {
return 0
}
func (adi *appendedDirInfo) Mode() os.FileMode {
return os.ModeDir
}
func (adi *appendedDirInfo) ModTime() time.Time {
return adi.time
}
func (adi *appendedDirInfo) IsDir() bool {
return true
}
func (adi *appendedDirInfo) Sys() interface{} {
return nil
}