-
Notifications
You must be signed in to change notification settings - Fork 183
/
zip.go
171 lines (142 loc) · 3.96 KB
/
zip.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
164
165
166
167
168
169
170
171
package main
import (
"archive/zip"
"bytes"
"encoding/json"
"fmt"
"io"
"io/fs"
"log"
"os"
"strings"
)
func (r *rover) generateZip(fe fs.FS, filename string) error {
newZipFile, err := os.Create(filename)
if err != nil {
return err
}
defer newZipFile.Close()
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
// Add frontend to zip file
feItems, err := fs.ReadDir(fe, ".")
if err != nil {
log.Fatalln(err)
}
for _, feItem := range feItems {
if !feItem.IsDir() {
if err = AddEmbeddedToZip(fe, zipWriter, feItem.Name()); err != nil {
return err
}
continue
}
// Iterate through subdirectories (ui/dist/*)
feSubItems, err := fs.ReadDir(fe, feItem.Name())
if err != nil {
return err
}
for _, feSubItem := range feSubItems {
if err = AddEmbeddedToZip(fe, zipWriter, fmt.Sprintf("%s/%s", feItem.Name(), feSubItem.Name())); err != nil {
return err
}
}
}
// Add plan, rso, map, graph to zip file
if err = AddFileToZip(zipWriter, "plan", r.Plan); err != nil {
return err
}
if err = AddFileToZip(zipWriter, "rso", r.RSO); err != nil {
return err
}
if err = AddFileToZip(zipWriter, "map", r.Map); err != nil {
return err
}
if err = AddFileToZip(zipWriter, "graph", r.Graph); err != nil {
return err
}
return nil
}
func AddEmbeddedToZip(fe fs.FS, zipWriter *zip.Writer, filename string) error {
writer, err := zipWriter.Create(filename)
if err != nil {
return err
}
var fileToZip fs.File
// Rename standalone to index.html references from absolute to relative
if filename == "index.html" {
curContent, err := fs.ReadFile(fe, filename)
if err != nil {
return err
}
contents := strings.Split(string(curContent), "</head>")
// Add js files, workaround since CORS error if you try to do getJSON
content := fmt.Sprintf("%s%s%s", contents[0], `<script type="text/javascript" language="javascript" src="./map.js"></script>
<script type="text/javascript" language="javascript" src="./rso.js"></script>
<script type="text/javascript" language="javascript" src="./graph.js"></script>`, contents[1])
content = strings.ReplaceAll(content, "=\"/", "=\"./")
tempFileName, tempFile, err := createTempFile("temp-index.html", []byte(content))
defer os.Remove(tempFile.Name()) // clean up
defer tempFile.Close()
fileToZip, err = os.Open(tempFileName)
if err != nil {
return err
}
defer fileToZip.Close()
} else if strings.HasSuffix(filename, ".js") {
curContent, err := fs.ReadFile(fe, filename)
if err != nil {
return err
}
rawContent := bytes.ReplaceAll(curContent, []byte("r.p+\""), []byte("\"./"))
tempFileName, tempFile, err := createTempFile("temp-index.html", rawContent)
defer os.Remove(tempFile.Name()) // clean up
defer tempFile.Close()
fileToZip, err = os.Open(tempFileName)
if err != nil {
return err
}
defer fileToZip.Close()
} else {
fileToZip, err = fe.Open(filename)
if err != nil {
return err
}
defer fileToZip.Close()
}
_, err = io.Copy(writer, fileToZip)
return err
}
func AddFileToZip(zipWriter *zip.Writer, fileType string, j interface{}) error {
filename := fmt.Sprintf("%s.js", fileType)
writer, err := zipWriter.Create(filename)
if err != nil {
return err
}
b, err := json.Marshal(j)
if err != nil {
return fmt.Errorf("error producing JSON: %s\n", err)
}
// add syntax to make json file a js object
content := fmt.Sprintf("const %s = %s", fileType, string(b))
tempFileName, tempFile, err := createTempFile(filename, []byte(content))
defer os.Remove(tempFile.Name()) // clean up
defer tempFile.Close()
fileToZip, err := os.Open(tempFileName)
if err != nil {
return err
}
defer fileToZip.Close()
_, err = io.Copy(writer, fileToZip)
return err
}
func createTempFile(filename string, b []byte) (string, *os.File, error) {
tempFile, err := os.CreateTemp("", filename)
if err != nil {
log.Fatal(err)
}
_, err = tempFile.Write(b)
if err != nil {
return "", tempFile, err
}
return tempFile.Name(), tempFile, nil
}