-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathgenstatic.go
110 lines (96 loc) · 3.06 KB
/
genstatic.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
// Copyright 2015, Yahoo Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// based on https://github.com/golang/tools/blob/master/godoc/static/makestatic.go
// which carries the following copyright notice:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The LICENSE file for the golang/tools repository can be found in
// https://github.com/golang/tools/blob/master/LICENSE
// +build ignore
// Command genstatic reads a set of files (Webseclab templates)
// and writes a Go source file to "static.go"
// that declares a map of string constants containing contents of the input files.
// It is intended to be invoked via "go generate" (directive in "templates.go").
package main
import (
"bufio"
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"unicode/utf8"
)
func main() {
if err := makestatic(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func makestatic() error {
f, err := os.Create("static.go")
if err != nil {
return err
}
defer f.Close()
w := bufio.NewWriter(f)
fmt.Fprintf(w, "%v\n\npackage webseclab\n\n", warning)
fmt.Fprintf(w, "// Templates contains all the webseclab Go templates as strings.\n")
fmt.Fprintf(w, "var Templates = map[string]string{\n")
base := "templates/"
files, err := getTemplateFiles(base)
for _, fn := range files {
b, err := ioutil.ReadFile(base + fn)
if err != nil {
return err
}
fmt.Fprintf(w, "\t%q: ", fn)
if utf8.Valid(b) {
fmt.Fprintf(w, "`%s`", sanitize(b))
} else {
fmt.Fprintf(w, "%q", b)
}
fmt.Fprintln(w, ",")
}
fmt.Fprintln(w, "}")
if err := w.Flush(); err != nil {
return err
}
return f.Close()
}
// sanitize prepares a valid UTF-8 string as a raw string constant.
func sanitize(b []byte) []byte {
// Replace ` with `+"`"+`
b = bytes.Replace(b, []byte("`"), []byte("`+\"`\"+`"), -1)
// Replace BOM with `+"\xEF\xBB\xBF"+`
// (A BOM is valid UTF-8 but not permitted in Go source files.
// I wouldn't bother handling this, but for some insane reason
// jquery.js has a BOM somewhere in the middle.)
return bytes.Replace(b, []byte("\xEF\xBB\xBF"), []byte("`+\"\\xEF\\xBB\\xBF\"+`"), -1)
}
// copied from templates.go to prevent making it exported
// getTemplateFiles collects all files under the base dir
func getTemplateFiles(base string) (files []string, err error) {
files = make([]string, 0, 50)
visit := func(path string, f os.FileInfo, err error) error {
if f == nil {
return errors.New("File " + path + " does not exist or not readable")
}
// don't add common shared files
if strings.HasSuffix(path, "common/footer") ||
strings.HasSuffix(path, "common/header") {
return nil
}
if !f.IsDir() {
files = append(files, strings.TrimPrefix(path, base))
}
return err
}
err = filepath.Walk(base, visit)
return files, err
}
const warning = "// DO NOT EDIT ** This file was generated by \"go generate\" (gen directive in templates.go) ** DO NOT EDIT //"