Browse code

add(github.com/jteeuwen/go-bindata): 93b909d1499a38620121b0a5eb43a18f3bccb083

Jessica Forrester authored on 2014/09/20 05:53:55
Showing 25 changed files
... ...
@@ -387,6 +387,11 @@
387 387
 			"Rev": "5a6d06c02600b1e57e55a9d9f71dbac1bfc9fe6c"
388 388
 		},
389 389
 		{
390
+			"ImportPath": "github.com/jteeuwen/go-bindata",
391
+			"Comment": "v3.0.5-31-g93b909d",
392
+			"Rev": "93b909d1499a38620121b0a5eb43a18f3bccb083"
393
+		},    
394
+		{
390 395
 			"ImportPath": "github.com/google/gofuzz",
391 396
 			"Rev": "aef70dacbc78771e35beb261bb3a72986adf7906"
392 397
 		},
393 398
new file mode 100644
... ...
@@ -0,0 +1,79 @@
0
+## Contribution guidelines.
1
+
2
+So you wish to contribute to this project? Fantastic!
3
+Here are a few guidelines to help you do this in a
4
+streamlined fashion.
5
+
6
+
7
+## Bug reports
8
+
9
+When supplying a bug report, please consider the following guidelines.
10
+These serve to make it easier for us to address the issue and find a solution.
11
+Most of these are pretty self-evident, but sometimes it is still necessary
12
+to reiterate them.
13
+
14
+* Be clear in the way you express the problem. Use simple language and
15
+  just enough of it to clearly define the issue. Not everyone is a native
16
+  English speaker. And while most can handle themselves pretty well,
17
+  it helps to stay away from more esoteric vocabulary.
18
+  
19
+  Be patient with non-native English speakers. If their bug reports
20
+  or comments are hard to understand, just ask for clarification.
21
+  Do not start guessing at their meaning, as this may just lead to
22
+  more confusion and misunderstandings.
23
+* Clearly define any information which is relevant to the problem.
24
+  This includes library versions, operating system and any other
25
+  external dependencies which may be needed.
26
+* Where applicable, provide a step-by-step listing of the way to
27
+  reproduce the problem. Make sure this is the simplest possible
28
+  way to do so. Omit any and all unneccesary steps, because they may
29
+  just complicate our understanding of the real problem.
30
+  If need be, create a whole new code project on your local machine,
31
+  which specifically tries to create the problem you are running into;
32
+  nothing more, nothing less.
33
+  
34
+  Include this program in the bug report. It often suffices to paste
35
+  the code in a [Gist](https://gist.github.com) or on the
36
+  [Go playground](http://play.golang.org).
37
+* If possible, provide us with a listing of the steps you have already
38
+  undertaken to solve the problem. This can save us a great deal of
39
+  wasted time, trying out solutions you have already covered.
40
+
41
+
42
+## Pull requests
43
+
44
+Bug reports are great. Supplying fixes to bugs is even better.
45
+When submitting a pull request, the following guidelines are
46
+good to keep in mind:
47
+
48
+* `go fmt`: **Always** run your code through `go fmt`, before
49
+  committing it. Code has to be readable by many different
50
+  people. And the only way this will be as painless as possible,
51
+  is if we all stick to the same code style.
52
+  
53
+  Some of our projects may have automated build-servers hooked up
54
+  to commit hooks. These will vet any submitted code and determine
55
+  if it meets a set of properties. One of which is code formatting.
56
+  These servers will outright deny a submission which has not been
57
+  run through `go fmt`, even if the code itself is correct.
58
+  
59
+  We try to maintain a zero-tolerance policy on this matter,
60
+  because consistently formatted code makes life a great deal
61
+  easier for everyone involved.
62
+* Commit log messages: When committing changes, do so often and
63
+  clearly -- Even if you have changed only 1 character in a code
64
+  comment. This means that commit log messages should clearly state
65
+  exactly what the change does and why. If it fixes a known issue,
66
+  then mention the issue number in the commit log. E.g.:
67
+  
68
+  > Fixes return value for `foo/boo.Baz()` to be consistent with
69
+  > the rest of the API. This addresses issue #32
70
+  
71
+  Do not pile a lot of unrelated changes into a single commit.
72
+  Pick and choose only those changes for a single commit, which are
73
+  directly related. We would much rather see a hundred commits
74
+  saying nothing but `"Runs go fmt"` in between any real fixes
75
+  than have these style changes embedded in those real fixes.
76
+  It creates a lot of noise when trying to review code.
77
+
78
+
0 79
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+license. Its contents can be found at:
2
+http://creativecommons.org/publicdomain/zero/1.0
0 3
new file mode 100644
... ...
@@ -0,0 +1,189 @@
0
+## bindata
1
+
2
+This package converts any file into managable Go source code. Useful for
3
+embedding binary data into a go program. The file data is optionally gzip
4
+compressed before being converted to a raw byte slice.
5
+
6
+It comes with a command line tool in the `go-bindata` sub directory.
7
+This tool offers a set of command line options, used to customize the
8
+output being generated.
9
+
10
+
11
+### Installation
12
+
13
+To install the library and command line program, use the following:
14
+
15
+	go get github.com/jteeuwen/go-bindata/...
16
+
17
+
18
+### Usage
19
+
20
+Conversion is done on one or more sets of files. They are all embedded in a new
21
+Go source file, along with a table of contents and an `Asset` function,
22
+which allows quick access to the asset, based on its name.
23
+
24
+The simplest invocation generates a `bindata.go` file in the current
25
+working directory. It includes all assets from the `data` directory.
26
+
27
+	$ go-bindata data/
28
+
29
+To include all input sub-directories recursively, use the elipsis postfix
30
+as defined for Go import paths. Otherwise it will only consider assets in the
31
+input directory itself.
32
+
33
+	$ go-bindata data/...
34
+
35
+To specify the name of the output file being generated, we use the following:
36
+
37
+	$ go-bindata -o myfile.go data/
38
+
39
+Multiple input directories can be specified if necessary.
40
+
41
+	$ go-bindata dir1/... /path/to/dir2/... dir3
42
+
43
+
44
+The following paragraphs detail some of the command line options which can be 
45
+supplied to `go-bindata`. Refer to the `testdata/out` directory for various
46
+output examples from the assets in `testdata/in`. Each example uses different
47
+command line options.
48
+
49
+To ignore files, pass in regexes using -ignore, for example:
50
+
51
+    $ go-bindata -ignore=\\.gitignore data/...
52
+
53
+### Accessing an asset
54
+
55
+To access asset data, we use the `Asset(string) []byte` function which
56
+is included in the generated output.
57
+
58
+	data := Asset("pub/style/foo.css")
59
+	if len(data) == 0 {
60
+		// Asset was not found.
61
+	}
62
+	
63
+	// use asset data
64
+
65
+
66
+### Debug vs Release builds
67
+
68
+When invoking the program with the `-debug` flag, the generated code does
69
+not actually include the asset data. Instead, it generates function stubs
70
+which load the data from the original file on disk. The asset API remains
71
+identical between debug and release builds, so your code will not have to
72
+change.
73
+
74
+This is useful during development when you expect the assets to change often.
75
+The host application using these assets uses the same API in both cases and
76
+will not have to care where the actual data comes from.
77
+
78
+An example is a Go webserver with some embedded, static web content like
79
+HTML, JS and CSS files. While developing it, you do not want to rebuild the
80
+whole server and restart it every time you make a change to a bit of
81
+javascript. You just want to build and launch the server once. Then just press
82
+refresh in the browser to see those changes. Embedding the assets with the
83
+`debug` flag allows you to do just that. When you are finished developing and
84
+ready for deployment, just re-invoke `go-bindata` without the `-debug` flag.
85
+It will now embed the latest version of the assets.
86
+
87
+
88
+### Lower memory footprint
89
+
90
+Using the `-nomemcopy` flag, will alter the way the output file is generated.
91
+It will employ a hack that allows us to read the file data directly from
92
+the compiled program's `.rodata` section. This ensures that when we call
93
+call our generated function, we omit unnecessary memcopies.
94
+
95
+The downside of this, is that it requires dependencies on the `reflect` and
96
+`unsafe` packages. These may be restricted on platforms like AppEngine and
97
+thus prevent you from using this mode.
98
+
99
+Another disadvantage is that the byte slice we create, is strictly read-only.
100
+For most use-cases this is not a problem, but if you ever try to alter the
101
+returned byte slice, a runtime panic is thrown. Use this mode only on target
102
+platforms where memory constraints are an issue.
103
+
104
+The default behaviour is to use the old code generation method. This
105
+prevents the two previously mentioned issues, but will employ at least one
106
+extra memcopy and thus increase memory requirements.
107
+
108
+For instance, consider the following two examples:
109
+
110
+This would be the default mode, using an extra memcopy but gives a safe
111
+implementation without dependencies on `reflect` and `unsafe`:
112
+
113
+```go
114
+func myfile() []byte {
115
+    return []byte{0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a}
116
+}
117
+```
118
+
119
+Here is the same functionality, but uses the `.rodata` hack.
120
+The byte slice returned from this example can not be written to without
121
+generating a runtime error.
122
+
123
+```go
124
+var _myfile = "\x89\x50\x4e\x47\x0d\x0a\x1a"
125
+
126
+func myfile() []byte {
127
+    var empty [0]byte
128
+    sx := (*reflect.StringHeader)(unsafe.Pointer(&_myfile))
129
+    b := empty[:]
130
+    bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
131
+    bx.Data = sx.Data
132
+    bx.Len = len(_myfile)
133
+    bx.Cap = bx.Len
134
+    return b
135
+}
136
+```
137
+
138
+
139
+### Optional compression
140
+
141
+When the `-nocompress` flag is given, the supplied resource is *not* GZIP
142
+compressed before being turned into Go code. The data should still be accessed
143
+through a function call, so nothing changes in the usage of the generated file.
144
+
145
+This feature is useful if you do not care for compression, or the supplied
146
+resource is already compressed. Doing it again would not add any value and may
147
+even increase the size of the data.
148
+
149
+The default behaviour of the program is to use compression.
150
+
151
+
152
+### Path prefix stripping
153
+
154
+The keys used in the `_bindata` map, are the same as the input file name
155
+passed to `go-bindata`. This includes the path. In most cases, this is not
156
+desireable, as it puts potentially sensitive information in your code base.
157
+For this purpose, the tool supplies another command line flag `-prefix`.
158
+This accepts a portion of a path name, which should be stripped off from
159
+the map keys and function names.
160
+
161
+For example, running without the `-prefix` flag, we get:
162
+
163
+	$ go-bindata /path/to/templates/
164
+
165
+	_bindata["/path/to/templates/foo.html"] = path_to_templates_foo_html
166
+
167
+Running with the `-prefix` flag, we get:
168
+
169
+	$ go-bindata -prefix "/path/to/" /path/to/templates/
170
+
171
+	_bindata["templates/foo.html"] = templates_foo_html
172
+
173
+
174
+### Build tags
175
+
176
+With the optional `-tags` flag, you can specify any go build tags that
177
+must be fulfilled for the output file to be included in a build. This
178
+is useful when including binary data in multiple formats, where the desired
179
+format is specified at build time with the appropriate tags.
180
+
181
+The tags are appended to a `// +build` line in the beginning of the output file
182
+and must follow the build tags syntax specified by the go tool.
183
+
184
+### Related projects
185
+
186
+[go-bindata-assetfs](https://github.com/elazarl/go-bindata-assetfs#readme) - 
187
+implements `http.FileSystem` interface. Allows you to serve assets with `net/http`.
188
+
0 189
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+// Asset holds information about a single asset to be processed.
7
+type Asset struct {
8
+	Path string // Full file path.
9
+	Name string // Key used in TOC -- name by which asset is referenced.
10
+	Func string // Function name for the procedure returning the asset contents.
11
+}
0 12
new file mode 100644
... ...
@@ -0,0 +1,44 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+import (
7
+	"fmt"
8
+	"io"
9
+)
10
+
11
+var (
12
+	newline    = []byte{'\n'}
13
+	dataindent = []byte{'\t', '\t'}
14
+	space      = []byte{' '}
15
+)
16
+
17
+type ByteWriter struct {
18
+	io.Writer
19
+	c int
20
+}
21
+
22
+func (w *ByteWriter) Write(p []byte) (n int, err error) {
23
+	if len(p) == 0 {
24
+		return
25
+	}
26
+
27
+	for n = range p {
28
+		if w.c%12 == 0 {
29
+			w.Writer.Write(newline)
30
+			w.Writer.Write(dataindent)
31
+			w.c = 0
32
+		} else {
33
+			w.Writer.Write(space)
34
+		}
35
+
36
+		fmt.Fprintf(w.Writer, "0x%02x,", p[n])
37
+		w.c++
38
+	}
39
+
40
+	n++
41
+
42
+	return
43
+}
0 44
new file mode 100644
... ...
@@ -0,0 +1,192 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+import (
7
+	"fmt"
8
+	"os"
9
+	"path/filepath"
10
+	"regexp"
11
+)
12
+
13
+// InputConfig defines options on a asset directory to be convert.
14
+type InputConfig struct {
15
+	// Path defines a directory containing asset files to be included
16
+	// in the generated output.
17
+	Path string
18
+
19
+	// Recusive defines whether subdirectories of Path
20
+	// should be recursively included in the conversion.
21
+	Recursive bool
22
+}
23
+
24
+// Config defines a set of options for the asset conversion.
25
+type Config struct {
26
+	// Name of the package to use. Defaults to 'main'.
27
+	Package string
28
+
29
+	// Tags specify a set of optional build tags, which should be
30
+	// included in the generated output. The tags are appended to a
31
+	// `// +build` line in the beginning of the output file
32
+	// and must follow the build tags syntax specified by the go tool.
33
+	Tags string
34
+
35
+	// Input defines the directory path, containing all asset files as
36
+	// well as whether to recursively process assets in any sub directories.
37
+	Input []InputConfig
38
+
39
+	// Output defines the output file for the generated code.
40
+	// If left empty, this defaults to 'bindata.go' in the current
41
+	// working directory.
42
+	Output string
43
+
44
+	// Prefix defines a path prefix which should be stripped from all
45
+	// file names when generating the keys in the table of contents.
46
+	// For example, running without the `-prefix` flag, we get:
47
+	//
48
+	// 	$ go-bindata /path/to/templates
49
+	// 	go_bindata["/path/to/templates/foo.html"] = _path_to_templates_foo_html
50
+	//
51
+	// Running with the `-prefix` flag, we get:
52
+	//
53
+	// 	$ go-bindata -prefix "/path/to/" /path/to/templates/foo.html
54
+	// 	go_bindata["templates/foo.html"] = templates_foo_html
55
+	Prefix string
56
+
57
+	// NoMemCopy will alter the way the output file is generated.
58
+	//
59
+	// It will employ a hack that allows us to read the file data directly from
60
+	// the compiled program's `.rodata` section. This ensures that when we call
61
+	// call our generated function, we omit unnecessary mem copies.
62
+	//
63
+	// The downside of this, is that it requires dependencies on the `reflect` and
64
+	// `unsafe` packages. These may be restricted on platforms like AppEngine and
65
+	// thus prevent you from using this mode.
66
+	//
67
+	// Another disadvantage is that the byte slice we create, is strictly read-only.
68
+	// For most use-cases this is not a problem, but if you ever try to alter the
69
+	// returned byte slice, a runtime panic is thrown. Use this mode only on target
70
+	// platforms where memory constraints are an issue.
71
+	//
72
+	// The default behaviour is to use the old code generation method. This
73
+	// prevents the two previously mentioned issues, but will employ at least one
74
+	// extra memcopy and thus increase memory requirements.
75
+	//
76
+	// For instance, consider the following two examples:
77
+	//
78
+	// This would be the default mode, using an extra memcopy but gives a safe
79
+	// implementation without dependencies on `reflect` and `unsafe`:
80
+	//
81
+	// 	func myfile() []byte {
82
+	// 		return []byte{0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a}
83
+	// 	}
84
+	//
85
+	// Here is the same functionality, but uses the `.rodata` hack.
86
+	// The byte slice returned from this example can not be written to without
87
+	// generating a runtime error.
88
+	//
89
+	// 	var _myfile = "\x89\x50\x4e\x47\x0d\x0a\x1a"
90
+	//
91
+	// 	func myfile() []byte {
92
+	// 		var empty [0]byte
93
+	// 		sx := (*reflect.StringHeader)(unsafe.Pointer(&_myfile))
94
+	// 		b := empty[:]
95
+	// 		bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
96
+	// 		bx.Data = sx.Data
97
+	// 		bx.Len = len(_myfile)
98
+	// 		bx.Cap = bx.Len
99
+	// 		return b
100
+	// 	}
101
+	NoMemCopy bool
102
+
103
+	// NoCompress means the assets are /not/ GZIP compressed before being turned
104
+	// into Go code. The generated function will automatically unzip
105
+	// the file data when called. Defaults to false.
106
+	NoCompress bool
107
+
108
+	// Perform a debug build. This generates an asset file, which
109
+	// loads the asset contents directly from disk at their original
110
+	// location, instead of embedding the contents in the code.
111
+	//
112
+	// This is mostly useful if you anticipate that the assets are
113
+	// going to change during your development cycle. You will always
114
+	// want your code to access the latest version of the asset.
115
+	// Only in release mode, will the assets actually be embedded
116
+	// in the code. The default behaviour is Release mode.
117
+	Debug bool
118
+
119
+	// Recursively process all assets in the input directory and its
120
+	// sub directories. This defaults to false, so only files in the
121
+	// input directory itself are read.
122
+	Recursive bool
123
+
124
+	// Ignores any filenames matching the regex pattern specified, e.g.
125
+	// path/to/file.ext will ignore only that file, or \\.gitignore
126
+	// will match any .gitignore file.
127
+	//
128
+	// This parameter can be provided multiple times.
129
+	Ignore []*regexp.Regexp
130
+}
131
+
132
+// NewConfig returns a default configuration struct.
133
+func NewConfig() *Config {
134
+	c := new(Config)
135
+	c.Package = "main"
136
+	c.NoMemCopy = false
137
+	c.NoCompress = false
138
+	c.Debug = false
139
+	c.Recursive = false
140
+	c.Output = "./bindata.go"
141
+	c.Ignore = make([]*regexp.Regexp, 0)
142
+	return c
143
+}
144
+
145
+// validate ensures the config has sane values.
146
+// Part of which means checking if certain file/directory paths exist.
147
+func (c *Config) validate() error {
148
+	if len(c.Package) == 0 {
149
+		return fmt.Errorf("Missing package name")
150
+	}
151
+
152
+	for _, input := range c.Input {
153
+		_, err := os.Lstat(input.Path)
154
+		if err != nil {
155
+			return fmt.Errorf("Failed to stat input path '%s': %v", input.Path, err)
156
+		}
157
+	}
158
+
159
+	if len(c.Output) == 0 {
160
+		cwd, err := os.Getwd()
161
+		if err != nil {
162
+			return fmt.Errorf("Unable to determine current working directory.")
163
+		}
164
+
165
+		c.Output = filepath.Join(cwd, "bindata.go")
166
+	}
167
+
168
+	stat, err := os.Lstat(c.Output)
169
+	if err != nil {
170
+		if !os.IsNotExist(err) {
171
+			return fmt.Errorf("Output path: %v", err)
172
+		}
173
+
174
+		// File does not exist. This is fine, just make
175
+		// sure the directory it is to be in exists.
176
+		dir, _ := filepath.Split(c.Output)
177
+		if dir != "" {
178
+			err = os.MkdirAll(dir, 0744)
179
+
180
+			if err != nil {
181
+				return fmt.Errorf("Create output directory: %v", err)
182
+			}
183
+		}
184
+	}
185
+
186
+	if stat != nil && stat.IsDir() {
187
+		return fmt.Errorf("Output path is a directory.")
188
+	}
189
+
190
+	return nil
191
+}
0 192
new file mode 100644
... ...
@@ -0,0 +1,196 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+import (
7
+	"bufio"
8
+	"fmt"
9
+	"os"
10
+	"path/filepath"
11
+	"regexp"
12
+	"strings"
13
+	"unicode"
14
+)
15
+
16
+// Translate reads assets from an input directory, converts them
17
+// to Go code and writes new files to the output specified
18
+// in the given configuration.
19
+func Translate(c *Config) error {
20
+	var toc []Asset
21
+
22
+	// Ensure our configuration has sane values.
23
+	err := c.validate()
24
+	if err != nil {
25
+		return err
26
+	}
27
+
28
+	// Locate all the assets.
29
+	for _, input := range c.Input {
30
+		err = findFiles(input.Path, c.Prefix, input.Recursive, &toc, c.Ignore)
31
+		if err != nil {
32
+			return err
33
+		}
34
+	}
35
+
36
+	// Create output file.
37
+	fd, err := os.Create(c.Output)
38
+	if err != nil {
39
+		return err
40
+	}
41
+
42
+	defer fd.Close()
43
+
44
+	// Create a buffered writer for better performance.
45
+	bfd := bufio.NewWriter(fd)
46
+	defer bfd.Flush()
47
+
48
+	// Write build tags, if applicable.
49
+	if len(c.Tags) > 0 {
50
+		_, err = fmt.Fprintf(bfd, "// +build %s\n\n", c.Tags)
51
+		if err != nil {
52
+			return err
53
+		}
54
+	}
55
+
56
+	// Write package declaration.
57
+	_, err = fmt.Fprintf(bfd, "package %s\n\n", c.Package)
58
+	if err != nil {
59
+		return err
60
+	}
61
+
62
+	// Write assets.
63
+	if c.Debug {
64
+		err = writeDebug(bfd, toc)
65
+	} else {
66
+		err = writeRelease(bfd, c, toc)
67
+	}
68
+
69
+	if err != nil {
70
+		return err
71
+	}
72
+
73
+	// Write table of contents
74
+	if err := writeTOC(bfd, toc); err != nil {
75
+		return err
76
+	}
77
+	// Write hierarchical tree of assets
78
+	return writeTOCTree(bfd, toc)
79
+}
80
+
81
+// findFiles recursively finds all the file paths in the given directory tree.
82
+// They are added to the given map as keys. Values will be safe function names
83
+// for each file, which will be used when generating the output code.
84
+func findFiles(dir, prefix string, recursive bool, toc *[]Asset, ignore []*regexp.Regexp) error {
85
+	if len(prefix) > 0 {
86
+		dir, _ = filepath.Abs(dir)
87
+		prefix, _ = filepath.Abs(prefix)
88
+		prefix = filepath.ToSlash(prefix)
89
+	}
90
+
91
+	fi, err := os.Stat(dir)
92
+	if err != nil {
93
+		return err
94
+	}
95
+
96
+	var list []os.FileInfo
97
+
98
+	if !fi.IsDir() {
99
+		dir = ""
100
+		list = []os.FileInfo{fi}
101
+	} else {
102
+		fd, err := os.Open(dir)
103
+		if err != nil {
104
+			return err
105
+		}
106
+
107
+		defer fd.Close()
108
+
109
+		list, err = fd.Readdir(0)
110
+		if err != nil {
111
+			return err
112
+		}
113
+	}
114
+
115
+	knownFuncs := make(map[string]int)
116
+
117
+	for _, file := range list {
118
+		var asset Asset
119
+		asset.Path = filepath.Join(dir, file.Name())
120
+		asset.Name = filepath.ToSlash(asset.Path)
121
+
122
+		ignoring := false
123
+		for _, re := range ignore {
124
+			if re.MatchString(asset.Path) {
125
+				ignoring = true
126
+				break
127
+			}
128
+		}
129
+		if ignoring {
130
+			continue
131
+		}
132
+
133
+		if file.IsDir() {
134
+			if recursive {
135
+				findFiles(asset.Path, prefix, recursive, toc, ignore)
136
+			}
137
+			continue
138
+		}
139
+
140
+		if strings.HasPrefix(asset.Name, prefix) {
141
+			asset.Name = asset.Name[len(prefix):]
142
+		}
143
+
144
+		// If we have a leading slash, get rid of it.
145
+		if len(asset.Name) > 0 && asset.Name[0] == '/' {
146
+			asset.Name = asset.Name[1:]
147
+		}
148
+
149
+		// This shouldn't happen.
150
+		if len(asset.Name) == 0 {
151
+			return fmt.Errorf("Invalid file: %v", asset.Path)
152
+		}
153
+
154
+		asset.Func = safeFunctionName(asset.Name, knownFuncs)
155
+		asset.Path, _ = filepath.Abs(asset.Path)
156
+		*toc = append(*toc, asset)
157
+	}
158
+
159
+	return nil
160
+}
161
+
162
+var regFuncName = regexp.MustCompile(`[^a-zA-Z0-9_]`)
163
+
164
+// safeFunctionName converts the given name into a name
165
+// which qualifies as a valid function identifier. It
166
+// also compares against a known list of functions to
167
+// prevent conflict based on name translation.
168
+func safeFunctionName(name string, knownFuncs map[string]int) string {
169
+	name = strings.ToLower(name)
170
+	name = regFuncName.ReplaceAllString(name, "_")
171
+
172
+	// Get rid of "__" instances for niceness.
173
+	for strings.Index(name, "__") > -1 {
174
+		name = strings.Replace(name, "__", "_", -1)
175
+	}
176
+
177
+	// Leading underscores are silly (unless they prefix a digit (see below)).
178
+	for len(name) > 1 && name[0] == '_' {
179
+		name = name[1:]
180
+	}
181
+
182
+	// Identifier can't start with a digit.
183
+	if unicode.IsDigit(rune(name[0])) {
184
+		name = "_" + name
185
+	}
186
+
187
+	if num, ok := knownFuncs[name]; ok {
188
+		knownFuncs[name] = num + 1
189
+		name = fmt.Sprintf("%s%d", name, num)
190
+	} else {
191
+		knownFuncs[name] = 2
192
+	}
193
+
194
+	return name
195
+}
0 196
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+import (
7
+	"fmt"
8
+	"io"
9
+)
10
+
11
+// writeDebug writes the debug code file.
12
+func writeDebug(w io.Writer, toc []Asset) error {
13
+	err := writeDebugHeader(w)
14
+	if err != nil {
15
+		return err
16
+	}
17
+
18
+	for i := range toc {
19
+		err = writeDebugAsset(w, &toc[i])
20
+		if err != nil {
21
+			return err
22
+		}
23
+	}
24
+
25
+	return nil
26
+}
27
+
28
+// writeDebugHeader writes output file headers.
29
+// This targets debug builds.
30
+func writeDebugHeader(w io.Writer) error {
31
+	_, err := fmt.Fprintf(w, `import (
32
+	"fmt"
33
+	"io/ioutil"
34
+	"strings"
35
+)
36
+
37
+// bindata_read reads the given file from disk. It returns an error on failure.
38
+func bindata_read(path, name string) ([]byte, error) {
39
+	buf, err := ioutil.ReadFile(path)
40
+	if err != nil {
41
+		err = fmt.Errorf("Error reading asset %%s at %%s: %%v", name, path, err)
42
+	}
43
+	return buf, err
44
+}
45
+
46
+`)
47
+	return err
48
+}
49
+
50
+// writeDebugAsset write a debug entry for the given asset.
51
+// A debug entry is simply a function which reads the asset from
52
+// the original file (e.g.: from disk).
53
+func writeDebugAsset(w io.Writer, asset *Asset) error {
54
+	_, err := fmt.Fprintf(w, `// %s reads file data from disk. It returns an error on failure.
55
+func %s() ([]byte, error) {
56
+	return bindata_read(
57
+		%q,
58
+		%q,
59
+	)
60
+}
61
+
62
+`, asset.Func, asset.Func, asset.Path, asset.Name)
63
+	return err
64
+}
0 65
new file mode 100644
... ...
@@ -0,0 +1,129 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+/*
5
+bindata converts any file into managable Go source code. Useful for
6
+embedding binary data into a go program. The file data is optionally gzip
7
+compressed before being converted to a raw byte slice.
8
+
9
+The following paragraphs cover some of the customization options
10
+which can be specified in the Config struct, which must be passed into
11
+the Translate() call.
12
+
13
+
14
+Debug vs Release builds
15
+
16
+When used with the `Debug` option, the generated code does not actually include
17
+the asset data. Instead, it generates function stubs which load the data from
18
+the original file on disk. The asset API remains identical between debug and
19
+release builds, so your code will not have to change.
20
+
21
+This is useful during development when you expect the assets to change often.
22
+The host application using these assets uses the same API in both cases and
23
+will not have to care where the actual data comes from.
24
+
25
+An example is a Go webserver with some embedded, static web content like
26
+HTML, JS and CSS files. While developing it, you do not want to rebuild the
27
+whole server and restart it every time you make a change to a bit of
28
+javascript. You just want to build and launch the server once. Then just press
29
+refresh in the browser to see those changes. Embedding the assets with the
30
+`debug` flag allows you to do just that. When you are finished developing and
31
+ready for deployment, just re-invoke `go-bindata` without the `-debug` flag.
32
+It will now embed the latest version of the assets.
33
+
34
+
35
+Lower memory footprint
36
+
37
+The `NoMemCopy` option will alter the way the output file is generated.
38
+It will employ a hack that allows us to read the file data directly from
39
+the compiled program's `.rodata` section. This ensures that when we call
40
+call our generated function, we omit unnecessary memcopies.
41
+
42
+The downside of this, is that it requires dependencies on the `reflect` and
43
+`unsafe` packages. These may be restricted on platforms like AppEngine and
44
+thus prevent you from using this mode.
45
+
46
+Another disadvantage is that the byte slice we create, is strictly read-only.
47
+For most use-cases this is not a problem, but if you ever try to alter the
48
+returned byte slice, a runtime panic is thrown. Use this mode only on target
49
+platforms where memory constraints are an issue.
50
+
51
+The default behaviour is to use the old code generation method. This
52
+prevents the two previously mentioned issues, but will employ at least one
53
+extra memcopy and thus increase memory requirements.
54
+
55
+For instance, consider the following two examples:
56
+
57
+This would be the default mode, using an extra memcopy but gives a safe
58
+implementation without dependencies on `reflect` and `unsafe`:
59
+
60
+	func myfile() []byte {
61
+		return []byte{0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a}
62
+	}
63
+
64
+Here is the same functionality, but uses the `.rodata` hack.
65
+The byte slice returned from this example can not be written to without
66
+generating a runtime error.
67
+
68
+	var _myfile = "\x89\x50\x4e\x47\x0d\x0a\x1a"
69
+
70
+	func myfile() []byte {
71
+		var empty [0]byte
72
+		sx := (*reflect.StringHeader)(unsafe.Pointer(&_myfile))
73
+		b := empty[:]
74
+		bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
75
+		bx.Data = sx.Data
76
+		bx.Len = len(_myfile)
77
+		bx.Cap = bx.Len
78
+		return b
79
+	}
80
+
81
+
82
+Optional compression
83
+
84
+The NoCompress option indicates that the supplied assets are *not* GZIP
85
+compressed before being turned into Go code. The data should still be accessed
86
+through a function call, so nothing changes in the API.
87
+
88
+This feature is useful if you do not care for compression, or the supplied
89
+resource is already compressed. Doing it again would not add any value and may
90
+even increase the size of the data.
91
+
92
+The default behaviour of the program is to use compression.
93
+
94
+
95
+Path prefix stripping
96
+
97
+The keys used in the `_bindata` map are the same as the input file name
98
+passed to `go-bindata`. This includes the path. In most cases, this is not
99
+desireable, as it puts potentially sensitive information in your code base.
100
+For this purpose, the tool supplies another command line flag `-prefix`.
101
+This accepts a portion of a path name, which should be stripped off from
102
+the map keys and function names.
103
+
104
+For example, running without the `-prefix` flag, we get:
105
+
106
+	$ go-bindata /path/to/templates/
107
+
108
+	_bindata["/path/to/templates/foo.html"] = path_to_templates_foo_html
109
+
110
+Running with the `-prefix` flag, we get:
111
+
112
+	$ go-bindata -prefix "/path/to/" /path/to/templates/
113
+
114
+	_bindata["templates/foo.html"] = templates_foo_html
115
+
116
+
117
+Build tags
118
+
119
+With the optional Tags field, you can specify any go build tags that
120
+must be fulfilled for the output file to be included in a build. This
121
+is useful when including binary data in multiple formats, where the desired
122
+format is specified at build time with the appropriate tags.
123
+
124
+The tags are appended to a `// +build` line in the beginning of the output file
125
+and must follow the build tags syntax specified by the go tool.
126
+
127
+*/
128
+package bindata
0 129
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+package main
1
+
2
+import "strings"
3
+
4
+// borrowed from https://github.com/hashicorp/serf/blob/master/command/agent/flag_slice_value.go
5
+
6
+// AppendSliceValue implements the flag.Value interface and allows multiple
7
+// calls to the same variable to append a list.
8
+type AppendSliceValue []string
9
+
10
+func (s *AppendSliceValue) String() string {
11
+	return strings.Join(*s, ",")
12
+}
13
+
14
+func (s *AppendSliceValue) Set(value string) error {
15
+	if *s == nil {
16
+		*s = make([]string, 0, 1)
17
+	}
18
+
19
+	*s = append(*s, value)
20
+	return nil
21
+}
0 22
new file mode 100644
... ...
@@ -0,0 +1,102 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package main
5
+
6
+import (
7
+	"flag"
8
+	"fmt"
9
+	"github.com/jteeuwen/go-bindata"
10
+	"os"
11
+	"path/filepath"
12
+	"regexp"
13
+	"strings"
14
+)
15
+
16
+func main() {
17
+	cfg := parseArgs()
18
+	err := bindata.Translate(cfg)
19
+
20
+	if err != nil {
21
+		fmt.Fprintf(os.Stderr, "bindata: %v\n", err)
22
+		os.Exit(1)
23
+	}
24
+}
25
+
26
+// parseArgs create s a new, filled configuration instance
27
+// by reading and parsing command line options.
28
+//
29
+// This function exits the program with an error, if
30
+// any of the command line options are incorrect.
31
+func parseArgs() *bindata.Config {
32
+	var version bool
33
+
34
+	c := bindata.NewConfig()
35
+
36
+	flag.Usage = func() {
37
+		fmt.Printf("Usage: %s [options] <input directories>\n\n", os.Args[0])
38
+		flag.PrintDefaults()
39
+	}
40
+
41
+	flag.BoolVar(&c.Debug, "debug", c.Debug, "Do not embed the assets, but provide the embedding API. Contents will still be loaded from disk.")
42
+	flag.StringVar(&c.Tags, "tags", c.Tags, "Optional set of build tags to include.")
43
+	flag.StringVar(&c.Prefix, "prefix", c.Prefix, "Optional path prefix to strip off asset names.")
44
+	flag.StringVar(&c.Package, "pkg", c.Package, "Package name to use in the generated code.")
45
+	flag.BoolVar(&c.NoMemCopy, "nomemcopy", c.NoMemCopy, "Use a .rodata hack to get rid of unnecessary memcopies. Refer to the documentation to see what implications this carries.")
46
+	flag.BoolVar(&c.NoCompress, "nocompress", c.NoCompress, "Assets will *not* be GZIP compressed when this flag is specified.")
47
+	flag.StringVar(&c.Output, "o", c.Output, "Optional name of the output file to be generated.")
48
+	flag.BoolVar(&version, "version", false, "Displays version information.")
49
+
50
+	ignore := make([]string, 0)
51
+	flag.Var((*AppendSliceValue)(&ignore), "ignore", "Regex pattern to ignore")
52
+
53
+	flag.Parse()
54
+
55
+	patterns := make([]*regexp.Regexp, 0)
56
+	for _, pattern := range ignore {
57
+		patterns = append(patterns, regexp.MustCompile(pattern))
58
+	}
59
+	c.Ignore = patterns
60
+
61
+	if version {
62
+		fmt.Printf("%s\n", Version())
63
+		os.Exit(0)
64
+	}
65
+
66
+	// Make sure we have input paths.
67
+	if flag.NArg() == 0 {
68
+		fmt.Fprintf(os.Stderr, "Missing <input dir>\n\n")
69
+		flag.Usage()
70
+		os.Exit(1)
71
+	}
72
+
73
+	// Create input configurations.
74
+	c.Input = make([]bindata.InputConfig, flag.NArg())
75
+	for i := range c.Input {
76
+		c.Input[i] = parseInput(flag.Arg(i))
77
+	}
78
+
79
+	return c
80
+}
81
+
82
+// parseRecursive determines whether the given path has a recrusive indicator and
83
+// returns a new path with the recursive indicator chopped off if it does.
84
+//
85
+//  ex:
86
+//      /path/to/foo/...    -> (/path/to/foo, true)
87
+//      /path/to/bar        -> (/path/to/bar, false)
88
+func parseInput(path string) bindata.InputConfig {
89
+	if strings.HasSuffix(path, "/...") {
90
+		return bindata.InputConfig{
91
+			Path:      filepath.Clean(path[:len(path)-4]),
92
+			Recursive: true,
93
+		}
94
+	} else {
95
+		return bindata.InputConfig{
96
+			Path:      filepath.Clean(path),
97
+			Recursive: false,
98
+		}
99
+	}
100
+
101
+}
0 102
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package main
5
+
6
+import (
7
+	"fmt"
8
+	"runtime"
9
+)
10
+
11
+const (
12
+	AppName         = "go-bindata"
13
+	AppVersionMajor = 3
14
+	AppVersionMinor = 1
15
+)
16
+
17
+// revision part of the program version.
18
+// This will be set automatically at build time like so:
19
+//
20
+//     go build -ldflags "-X main.AppVersionRev `date -u +%s`"
21
+var AppVersionRev string
22
+
23
+func Version() string {
24
+	if len(AppVersionRev) == 0 {
25
+		AppVersionRev = "0"
26
+	}
27
+
28
+	return fmt.Sprintf("%s %d.%d.%s (Go runtime %s).\nCopyright (c) 2010-2013, Jim Teeuwen.",
29
+		AppName, AppVersionMajor, AppVersionMinor, AppVersionRev, runtime.Version())
30
+}
0 31
new file mode 100644
... ...
@@ -0,0 +1,272 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+import (
7
+	"compress/gzip"
8
+	"fmt"
9
+	"io"
10
+	"os"
11
+)
12
+
13
+// writeRelease writes the release code file.
14
+func writeRelease(w io.Writer, c *Config, toc []Asset) error {
15
+	err := writeReleaseHeader(w, c)
16
+	if err != nil {
17
+		return err
18
+	}
19
+
20
+	for i := range toc {
21
+		err = writeReleaseAsset(w, c, &toc[i])
22
+		if err != nil {
23
+			return err
24
+		}
25
+	}
26
+
27
+	return nil
28
+}
29
+
30
+// writeReleaseHeader writes output file headers.
31
+// This targets release builds.
32
+func writeReleaseHeader(w io.Writer, c *Config) error {
33
+	if c.NoCompress {
34
+		if c.NoMemCopy {
35
+			return header_uncompressed_nomemcopy(w)
36
+		} else {
37
+			return header_uncompressed_memcopy(w)
38
+		}
39
+	} else {
40
+		if c.NoMemCopy {
41
+			return header_compressed_nomemcopy(w)
42
+		} else {
43
+			return header_compressed_memcopy(w)
44
+		}
45
+	}
46
+}
47
+
48
+// writeReleaseAsset write a release entry for the given asset.
49
+// A release entry is a function which embeds and returns
50
+// the file's byte content.
51
+func writeReleaseAsset(w io.Writer, c *Config, asset *Asset) error {
52
+	fd, err := os.Open(asset.Path)
53
+	if err != nil {
54
+		return err
55
+	}
56
+
57
+	defer fd.Close()
58
+
59
+	if c.NoCompress {
60
+		if c.NoMemCopy {
61
+			return uncompressed_nomemcopy(w, asset, fd)
62
+		} else {
63
+			return uncompressed_memcopy(w, asset, fd)
64
+		}
65
+	} else {
66
+		if c.NoMemCopy {
67
+			return compressed_nomemcopy(w, asset, fd)
68
+		} else {
69
+			return compressed_memcopy(w, asset, fd)
70
+		}
71
+	}
72
+}
73
+
74
+func header_compressed_nomemcopy(w io.Writer) error {
75
+	_, err := fmt.Fprintf(w, `import (
76
+	"bytes"
77
+	"compress/gzip"
78
+	"fmt"
79
+	"io"
80
+	"reflect"
81
+	"strings"
82
+	"unsafe"
83
+)
84
+
85
+func bindata_read(data, name string) ([]byte, error) {
86
+	var empty [0]byte
87
+	sx := (*reflect.StringHeader)(unsafe.Pointer(&data))
88
+	b := empty[:]
89
+	bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
90
+	bx.Data = sx.Data
91
+	bx.Len = len(data)
92
+	bx.Cap = bx.Len
93
+
94
+	gz, err := gzip.NewReader(bytes.NewBuffer(b))
95
+	if err != nil {
96
+		return nil, fmt.Errorf("Read %%q: %%v", name, err)
97
+	}
98
+
99
+	var buf bytes.Buffer
100
+	_, err = io.Copy(&buf, gz)
101
+	gz.Close()
102
+
103
+	if err != nil {
104
+		return nil, fmt.Errorf("Read %%q: %%v", name, err)
105
+	}
106
+
107
+	return buf.Bytes(), nil
108
+}
109
+
110
+`)
111
+	return err
112
+}
113
+
114
+func header_compressed_memcopy(w io.Writer) error {
115
+	_, err := fmt.Fprintf(w, `import (
116
+	"bytes"
117
+	"compress/gzip"
118
+	"fmt"
119
+	"io"
120
+	"strings"
121
+)
122
+
123
+func bindata_read(data []byte, name string) ([]byte, error) {
124
+	gz, err := gzip.NewReader(bytes.NewBuffer(data))
125
+	if err != nil {
126
+		return nil, fmt.Errorf("Read %%q: %%v", name, err)
127
+	}
128
+
129
+	var buf bytes.Buffer
130
+	_, err = io.Copy(&buf, gz)
131
+	gz.Close()
132
+
133
+	if err != nil {
134
+		return nil, fmt.Errorf("Read %%q: %%v", name, err)
135
+	}
136
+
137
+	return buf.Bytes(), nil
138
+}
139
+
140
+`)
141
+	return err
142
+}
143
+
144
+func header_uncompressed_nomemcopy(w io.Writer) error {
145
+	_, err := fmt.Fprintf(w, `import (
146
+	"fmt"
147
+	"reflect"
148
+	"strings"
149
+	"unsafe"
150
+)
151
+
152
+func bindata_read(data, name string) ([]byte, error) {
153
+	var empty [0]byte
154
+	sx := (*reflect.StringHeader)(unsafe.Pointer(&data))
155
+	b := empty[:]
156
+	bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
157
+	bx.Data = sx.Data
158
+	bx.Len = len(data)
159
+	bx.Cap = bx.Len
160
+	return b, nil
161
+}
162
+
163
+`)
164
+	return err
165
+}
166
+
167
+func header_uncompressed_memcopy(w io.Writer) error {
168
+	_, err := fmt.Fprintf(w, `import (
169
+	"fmt"
170
+	"strings"
171
+)
172
+`)
173
+	return err
174
+}
175
+
176
+func compressed_nomemcopy(w io.Writer, asset *Asset, r io.Reader) error {
177
+	_, err := fmt.Fprintf(w, `var _%s = "`, asset.Func)
178
+	if err != nil {
179
+		return err
180
+	}
181
+
182
+	gz := gzip.NewWriter(&StringWriter{Writer: w})
183
+	_, err = io.Copy(gz, r)
184
+	gz.Close()
185
+
186
+	if err != nil {
187
+		return err
188
+	}
189
+
190
+	_, err = fmt.Fprintf(w, `"
191
+
192
+func %s() ([]byte, error) {
193
+	return bindata_read(
194
+		_%s,
195
+		%q,
196
+	)
197
+}
198
+
199
+`, asset.Func, asset.Func, asset.Name)
200
+	return err
201
+}
202
+
203
+func compressed_memcopy(w io.Writer, asset *Asset, r io.Reader) error {
204
+	_, err := fmt.Fprintf(w, `func %s() ([]byte, error) {
205
+	return bindata_read([]byte{`, asset.Func)
206
+
207
+	if err != nil {
208
+		return nil
209
+	}
210
+
211
+	gz := gzip.NewWriter(&ByteWriter{Writer: w})
212
+	_, err = io.Copy(gz, r)
213
+	gz.Close()
214
+
215
+	if err != nil {
216
+		return err
217
+	}
218
+
219
+	_, err = fmt.Fprintf(w, `
220
+	},
221
+		%q,
222
+	)
223
+}
224
+
225
+`, asset.Name)
226
+	return err
227
+}
228
+
229
+func uncompressed_nomemcopy(w io.Writer, asset *Asset, r io.Reader) error {
230
+	_, err := fmt.Fprintf(w, `var _%s = "`, asset.Func)
231
+	if err != nil {
232
+		return err
233
+	}
234
+
235
+	_, err = io.Copy(&StringWriter{Writer: w}, r)
236
+	if err != nil {
237
+		return err
238
+	}
239
+
240
+	_, err = fmt.Fprintf(w, `"
241
+
242
+func %s() ([]byte, error) {
243
+	return bindata_read(
244
+		_%s,
245
+		%q,
246
+	)
247
+}
248
+
249
+`, asset.Func, asset.Func, asset.Name)
250
+	return err
251
+}
252
+
253
+func uncompressed_memcopy(w io.Writer, asset *Asset, r io.Reader) error {
254
+	_, err := fmt.Fprintf(w, `func %s() ([]byte, error) {
255
+	return []byte{`, asset.Func)
256
+	if err != nil {
257
+		return err
258
+	}
259
+
260
+	_, err = io.Copy(&ByteWriter{Writer: w}, r)
261
+	if err != nil {
262
+		return err
263
+	}
264
+
265
+	_, err = fmt.Fprintf(w, `
266
+	}, nil
267
+}
268
+
269
+`)
270
+	return err
271
+}
0 272
new file mode 100644
... ...
@@ -0,0 +1,36 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+import (
7
+	"io"
8
+)
9
+
10
+const lowerHex = "0123456789abcdef"
11
+
12
+type StringWriter struct {
13
+	io.Writer
14
+	c int
15
+}
16
+
17
+func (w *StringWriter) Write(p []byte) (n int, err error) {
18
+	if len(p) == 0 {
19
+		return
20
+	}
21
+
22
+	buf := []byte(`\x00`)
23
+	var b byte
24
+
25
+	for n, b = range p {
26
+		buf[2] = lowerHex[b/16]
27
+		buf[3] = lowerHex[b%16]
28
+		w.Writer.Write(buf)
29
+		w.c++
30
+	}
31
+
32
+	n++
33
+
34
+	return
35
+}
0 36
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+// sample file
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+// sample file
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+// sample file
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+// sample file
0 1
new file mode 100644
... ...
@@ -0,0 +1,86 @@
0
+package main
1
+
2
+import (
3
+	"bytes"
4
+	"compress/gzip"
5
+	"io"
6
+	"log"
7
+)
8
+
9
+func bindata_read(data []byte, name string) []byte {
10
+	gz, err := gzip.NewReader(bytes.NewBuffer(data))
11
+	if err != nil {
12
+		log.Fatalf("Read %q: %v", name, err)
13
+	}
14
+
15
+	var buf bytes.Buffer
16
+	_, err = io.Copy(&buf, gz)
17
+	gz.Close()
18
+
19
+	if err != nil {
20
+		log.Fatalf("Read %q: %v", name, err)
21
+	}
22
+
23
+	return buf.Bytes()
24
+}
25
+
26
+func in_b_test_asset() []byte {
27
+	return bindata_read([]byte{
28
+		0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xd2, 0xd7,
29
+		0x57, 0x28, 0x4e, 0xcc, 0x2d, 0xc8, 0x49, 0x55, 0x48, 0xcb, 0xcc, 0x49,
30
+		0xe5, 0x02, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x82, 0x8c, 0x85, 0x0f,
31
+		0x00, 0x00, 0x00,
32
+	},
33
+		"in/b/test.asset",
34
+	)
35
+}
36
+
37
+func in_test_asset() []byte {
38
+	return bindata_read([]byte{
39
+		0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xd2, 0xd7,
40
+		0x57, 0x28, 0x4e, 0xcc, 0x2d, 0xc8, 0x49, 0x55, 0x48, 0xcb, 0xcc, 0x49,
41
+		0xe5, 0x02, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x82, 0x8c, 0x85, 0x0f,
42
+		0x00, 0x00, 0x00,
43
+	},
44
+		"in/test.asset",
45
+	)
46
+}
47
+
48
+func in_a_test_asset() []byte {
49
+	return bindata_read([]byte{
50
+		0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xd2, 0xd7,
51
+		0x57, 0x28, 0x4e, 0xcc, 0x2d, 0xc8, 0x49, 0x55, 0x48, 0xcb, 0xcc, 0x49,
52
+		0xe5, 0x02, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x82, 0x8c, 0x85, 0x0f,
53
+		0x00, 0x00, 0x00,
54
+	},
55
+		"in/a/test.asset",
56
+	)
57
+}
58
+
59
+func in_c_test_asset() []byte {
60
+	return bindata_read([]byte{
61
+		0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xd2, 0xd7,
62
+		0x57, 0x28, 0x4e, 0xcc, 0x2d, 0xc8, 0x49, 0x55, 0x48, 0xcb, 0xcc, 0x49,
63
+		0xe5, 0x02, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x82, 0x8c, 0x85, 0x0f,
64
+		0x00, 0x00, 0x00,
65
+	},
66
+		"in/c/test.asset",
67
+	)
68
+}
69
+
70
+// Asset loads and returns the asset for the given name.
71
+// This returns nil of the asset could not be found.
72
+func Asset(name string) []byte {
73
+	if f, ok := _bindata[name]; ok {
74
+		return f()
75
+	}
76
+	return nil
77
+}
78
+
79
+// _bindata is a table, holding each asset generator, mapped to its name.
80
+var _bindata = map[string]func() []byte{
81
+	"in/b/test.asset": in_b_test_asset,
82
+	"in/test.asset":   in_test_asset,
83
+	"in/a/test.asset": in_a_test_asset,
84
+	"in/c/test.asset": in_c_test_asset,
85
+}
0 86
new file mode 100644
... ...
@@ -0,0 +1,88 @@
0
+package main
1
+
2
+import (
3
+	"bytes"
4
+	"compress/gzip"
5
+	"io"
6
+	"log"
7
+	"reflect"
8
+	"unsafe"
9
+)
10
+
11
+func bindata_read(data, name string) []byte {
12
+	var empty [0]byte
13
+	sx := (*reflect.StringHeader)(unsafe.Pointer(&data))
14
+	b := empty[:]
15
+	bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
16
+	bx.Data = sx.Data
17
+	bx.Len = len(data)
18
+	bx.Cap = bx.Len
19
+
20
+	gz, err := gzip.NewReader(bytes.NewBuffer(b))
21
+	if err != nil {
22
+		log.Fatalf("Read %q: %v", name, err)
23
+	}
24
+
25
+	var buf bytes.Buffer
26
+	_, err = io.Copy(&buf, gz)
27
+	gz.Close()
28
+
29
+	if err != nil {
30
+		log.Fatalf("Read %q: %v", name, err)
31
+	}
32
+
33
+	return buf.Bytes()
34
+}
35
+
36
+var _in_b_test_asset = "\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\x28\x4e\xcc\x2d\xc8\x49\x55\x48\xcb\xcc\x49\xe5\x02\x04\x00\x00\xff\xff\x8a\x82\x8c\x85\x0f\x00\x00\x00"
37
+
38
+func in_b_test_asset() []byte {
39
+	return bindata_read(
40
+		_in_b_test_asset,
41
+		"in/b/test.asset",
42
+	)
43
+}
44
+
45
+var _in_test_asset = "\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\x28\x4e\xcc\x2d\xc8\x49\x55\x48\xcb\xcc\x49\xe5\x02\x04\x00\x00\xff\xff\x8a\x82\x8c\x85\x0f\x00\x00\x00"
46
+
47
+func in_test_asset() []byte {
48
+	return bindata_read(
49
+		_in_test_asset,
50
+		"in/test.asset",
51
+	)
52
+}
53
+
54
+var _in_a_test_asset = "\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\x28\x4e\xcc\x2d\xc8\x49\x55\x48\xcb\xcc\x49\xe5\x02\x04\x00\x00\xff\xff\x8a\x82\x8c\x85\x0f\x00\x00\x00"
55
+
56
+func in_a_test_asset() []byte {
57
+	return bindata_read(
58
+		_in_a_test_asset,
59
+		"in/a/test.asset",
60
+	)
61
+}
62
+
63
+var _in_c_test_asset = "\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\x28\x4e\xcc\x2d\xc8\x49\x55\x48\xcb\xcc\x49\xe5\x02\x04\x00\x00\xff\xff\x8a\x82\x8c\x85\x0f\x00\x00\x00"
64
+
65
+func in_c_test_asset() []byte {
66
+	return bindata_read(
67
+		_in_c_test_asset,
68
+		"in/c/test.asset",
69
+	)
70
+}
71
+
72
+// Asset loads and returns the asset for the given name.
73
+// This returns nil of the asset could not be found.
74
+func Asset(name string) []byte {
75
+	if f, ok := _bindata[name]; ok {
76
+		return f()
77
+	}
78
+	return nil
79
+}
80
+
81
+// _bindata is a table, holding each asset generator, mapped to its name.
82
+var _bindata = map[string]func() []byte{
83
+	"in/b/test.asset": in_b_test_asset,
84
+	"in/test.asset":   in_test_asset,
85
+	"in/a/test.asset": in_a_test_asset,
86
+	"in/c/test.asset": in_c_test_asset,
87
+}
0 88
new file mode 100644
... ...
@@ -0,0 +1,80 @@
0
+package main
1
+
2
+import (
3
+	"bytes"
4
+	"io"
5
+	"log"
6
+	"os"
7
+)
8
+
9
+// bindata_read reads the given file from disk.
10
+// It panics if anything went wrong.
11
+func bindata_read(path, name string) []byte {
12
+	fd, err := os.Open(path)
13
+	if err != nil {
14
+		log.Fatalf("Read %s: %v", name, err)
15
+	}
16
+
17
+	defer fd.Close()
18
+
19
+	var buf bytes.Buffer
20
+	_, err = io.Copy(&buf, fd)
21
+	if err != nil {
22
+		log.Fatalf("Read %s: %v", name, err)
23
+	}
24
+
25
+	return buf.Bytes()
26
+}
27
+
28
+// in_b_test_asset reads file data from disk.
29
+// It panics if something went wrong in the process.
30
+func in_b_test_asset() []byte {
31
+	return bindata_read(
32
+		"/a/code/go/src/github.com/jteeuwen/go-bindata/testdata/in/b/test.asset",
33
+		"in/b/test.asset",
34
+	)
35
+}
36
+
37
+// in_test_asset reads file data from disk.
38
+// It panics if something went wrong in the process.
39
+func in_test_asset() []byte {
40
+	return bindata_read(
41
+		"/a/code/go/src/github.com/jteeuwen/go-bindata/testdata/in/test.asset",
42
+		"in/test.asset",
43
+	)
44
+}
45
+
46
+// in_a_test_asset reads file data from disk.
47
+// It panics if something went wrong in the process.
48
+func in_a_test_asset() []byte {
49
+	return bindata_read(
50
+		"/a/code/go/src/github.com/jteeuwen/go-bindata/testdata/in/a/test.asset",
51
+		"in/a/test.asset",
52
+	)
53
+}
54
+
55
+// in_c_test_asset reads file data from disk.
56
+// It panics if something went wrong in the process.
57
+func in_c_test_asset() []byte {
58
+	return bindata_read(
59
+		"/a/code/go/src/github.com/jteeuwen/go-bindata/testdata/in/c/test.asset",
60
+		"in/c/test.asset",
61
+	)
62
+}
63
+
64
+// Asset loads and returns the asset for the given name.
65
+// This returns nil of the asset could not be found.
66
+func Asset(name string) []byte {
67
+	if f, ok := _bindata[name]; ok {
68
+		return f()
69
+	}
70
+	return nil
71
+}
72
+
73
+// _bindata is a table, holding each asset generator, mapped to its name.
74
+var _bindata = map[string]func() []byte{
75
+	"in/b/test.asset": in_b_test_asset,
76
+	"in/test.asset":   in_test_asset,
77
+	"in/a/test.asset": in_a_test_asset,
78
+	"in/c/test.asset": in_c_test_asset,
79
+}
0 80
new file mode 100644
... ...
@@ -0,0 +1,46 @@
0
+package main
1
+
2
+func in_b_test_asset() []byte {
3
+	return []byte{
4
+		0x2f, 0x2f, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x66, 0x69,
5
+		0x6c, 0x65, 0x0a,
6
+	}
7
+}
8
+
9
+func in_test_asset() []byte {
10
+	return []byte{
11
+		0x2f, 0x2f, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x66, 0x69,
12
+		0x6c, 0x65, 0x0a,
13
+	}
14
+}
15
+
16
+func in_a_test_asset() []byte {
17
+	return []byte{
18
+		0x2f, 0x2f, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x66, 0x69,
19
+		0x6c, 0x65, 0x0a,
20
+	}
21
+}
22
+
23
+func in_c_test_asset() []byte {
24
+	return []byte{
25
+		0x2f, 0x2f, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x66, 0x69,
26
+		0x6c, 0x65, 0x0a,
27
+	}
28
+}
29
+
30
+// Asset loads and returns the asset for the given name.
31
+// This returns nil of the asset could not be found.
32
+func Asset(name string) []byte {
33
+	if f, ok := _bindata[name]; ok {
34
+		return f()
35
+	}
36
+	return nil
37
+}
38
+
39
+// _bindata is a table, holding each asset generator, mapped to its name.
40
+var _bindata = map[string]func() []byte{
41
+	"in/b/test.asset": in_b_test_asset,
42
+	"in/test.asset":   in_test_asset,
43
+	"in/a/test.asset": in_a_test_asset,
44
+	"in/c/test.asset": in_c_test_asset,
45
+}
0 46
new file mode 100644
... ...
@@ -0,0 +1,70 @@
0
+package main
1
+
2
+import (
3
+	"reflect"
4
+	"unsafe"
5
+)
6
+
7
+func bindata_read(data, name string) []byte {
8
+	var empty [0]byte
9
+	sx := (*reflect.StringHeader)(unsafe.Pointer(&data))
10
+	b := empty[:]
11
+	bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
12
+	bx.Data = sx.Data
13
+	bx.Len = len(data)
14
+	bx.Cap = bx.Len
15
+	return b
16
+}
17
+
18
+var _in_b_test_asset = "\x2f\x2f\x20\x73\x61\x6d\x70\x6c\x65\x20\x66\x69\x6c\x65\x0a"
19
+
20
+func in_b_test_asset() []byte {
21
+	return bindata_read(
22
+		_in_b_test_asset,
23
+		"in/b/test.asset",
24
+	)
25
+}
26
+
27
+var _in_test_asset = "\x2f\x2f\x20\x73\x61\x6d\x70\x6c\x65\x20\x66\x69\x6c\x65\x0a"
28
+
29
+func in_test_asset() []byte {
30
+	return bindata_read(
31
+		_in_test_asset,
32
+		"in/test.asset",
33
+	)
34
+}
35
+
36
+var _in_a_test_asset = "\x2f\x2f\x20\x73\x61\x6d\x70\x6c\x65\x20\x66\x69\x6c\x65\x0a"
37
+
38
+func in_a_test_asset() []byte {
39
+	return bindata_read(
40
+		_in_a_test_asset,
41
+		"in/a/test.asset",
42
+	)
43
+}
44
+
45
+var _in_c_test_asset = "\x2f\x2f\x20\x73\x61\x6d\x70\x6c\x65\x20\x66\x69\x6c\x65\x0a"
46
+
47
+func in_c_test_asset() []byte {
48
+	return bindata_read(
49
+		_in_c_test_asset,
50
+		"in/c/test.asset",
51
+	)
52
+}
53
+
54
+// Asset loads and returns the asset for the given name.
55
+// This returns nil of the asset could not be found.
56
+func Asset(name string) []byte {
57
+	if f, ok := _bindata[name]; ok {
58
+		return f()
59
+	}
60
+	return nil
61
+}
62
+
63
+// _bindata is a table, holding each asset generator, mapped to its name.
64
+var _bindata = map[string]func() []byte{
65
+	"in/b/test.asset": in_b_test_asset,
66
+	"in/test.asset":   in_test_asset,
67
+	"in/a/test.asset": in_a_test_asset,
68
+	"in/c/test.asset": in_c_test_asset,
69
+}
0 70
new file mode 100644
... ...
@@ -0,0 +1,184 @@
0
+// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
1
+// license. Its contents can be found at:
2
+// http://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+package bindata
5
+
6
+import (
7
+	"fmt"
8
+	"io"
9
+	"os"
10
+	"strings"
11
+)
12
+
13
+type assetTree struct {
14
+	Asset    Asset
15
+	Children map[string]*assetTree
16
+}
17
+
18
+func newAssetTree() *assetTree {
19
+	tree := &assetTree{}
20
+	tree.Children = make(map[string]*assetTree)
21
+	return tree
22
+}
23
+
24
+func (node *assetTree) child(name string) *assetTree {
25
+	rv, ok := node.Children[name]
26
+	if !ok {
27
+		rv = newAssetTree()
28
+		node.Children[name] = rv
29
+	}
30
+	return rv
31
+}
32
+
33
+func (root *assetTree) Add(route []string, asset Asset) {
34
+	for _, name := range route {
35
+		root = root.child(name)
36
+	}
37
+	root.Asset = asset
38
+}
39
+
40
+func ident(w io.Writer, n int) {
41
+	for i := 0; i < n; i++ {
42
+		w.Write([]byte{'\t'})
43
+	}
44
+}
45
+
46
+func (root *assetTree) funcOrNil() string {
47
+	if root.Asset.Func == "" {
48
+		return "nil"
49
+	} else {
50
+		return root.Asset.Func
51
+	}
52
+}
53
+
54
+func (root *assetTree) writeGoMap(w io.Writer, nident int) {
55
+	fmt.Fprintf(w, "&_bintree_t{%s, map[string]*_bintree_t{\n", root.funcOrNil())
56
+	for p, child := range root.Children {
57
+		ident(w, nident+1)
58
+		fmt.Fprintf(w, `"%s": `, p)
59
+		child.writeGoMap(w, nident+1)
60
+	}
61
+	ident(w, nident)
62
+	io.WriteString(w, "}}")
63
+	if nident > 0 {
64
+		io.WriteString(w, ",")
65
+	}
66
+	io.WriteString(w, "\n")
67
+}
68
+
69
+func (root *assetTree) WriteAsGoMap(w io.Writer) error {
70
+	_, err := fmt.Fprint(w, `type _bintree_t struct {
71
+	Func func() ([]byte, error)
72
+	Children map[string]*_bintree_t
73
+}
74
+var _bintree = `)
75
+	root.writeGoMap(w, 0)
76
+	return err
77
+}
78
+
79
+func writeTOCTree(w io.Writer, toc []Asset) error {
80
+	_, err := fmt.Fprintf(w, `// AssetDir returns the file names below a certain
81
+// directory embedded in the file by go-bindata.
82
+// For example if you run go-bindata on data/... and data contains the
83
+// following hierarchy:
84
+//     data/
85
+//       foo.txt
86
+//       img/
87
+//         a.png
88
+//         b.png
89
+// then AssetDir("data") would return []string{"foo.txt", "img"}
90
+// AssetDir("data/img") would return []string{"a.png", "b.png"}
91
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error
92
+// AssetDir("") will return []string{"data"}.
93
+func AssetDir(name string) ([]string, error) {
94
+	node := _bintree
95
+	if len(name) != 0 {
96
+		cannonicalName := strings.Replace(name, "\\", "/", -1)
97
+		pathList := strings.Split(cannonicalName, "/")
98
+		for _, p := range pathList {
99
+			node = node.Children[p]
100
+			if node == nil {
101
+				return nil, fmt.Errorf("Asset %%s not found", name)
102
+			}
103
+		}
104
+	}
105
+	if node.Func != nil {
106
+		return nil, fmt.Errorf("Asset %%s not found", name)
107
+	}
108
+	rv := make([]string, 0, len(node.Children))
109
+	for name := range node.Children {
110
+		rv = append(rv, name)
111
+	}
112
+	return rv, nil
113
+}
114
+
115
+`)
116
+	if err != nil {
117
+		return err
118
+	}
119
+	tree := newAssetTree()
120
+	for i := range toc {
121
+		pathList := strings.Split(toc[i].Name, string(os.PathSeparator))
122
+		tree.Add(pathList, toc[i])
123
+	}
124
+	return tree.WriteAsGoMap(w)
125
+}
126
+
127
+// writeTOC writes the table of contents file.
128
+func writeTOC(w io.Writer, toc []Asset) error {
129
+	err := writeTOCHeader(w)
130
+	if err != nil {
131
+		return err
132
+	}
133
+
134
+	for i := range toc {
135
+		err = writeTOCAsset(w, &toc[i])
136
+		if err != nil {
137
+			return err
138
+		}
139
+	}
140
+
141
+	return writeTOCFooter(w)
142
+}
143
+
144
+// writeTOCHeader writes the table of contents file header.
145
+func writeTOCHeader(w io.Writer) error {
146
+	_, err := fmt.Fprintf(w, `// Asset loads and returns the asset for the given name.
147
+// It returns an error if the asset could not be found or
148
+// could not be loaded.
149
+func Asset(name string) ([]byte, error) {
150
+	cannonicalName := strings.Replace(name, "\\", "/", -1)
151
+	if f, ok := _bindata[cannonicalName]; ok {
152
+		return f()
153
+	}
154
+	return nil, fmt.Errorf("Asset %%s not found", name)
155
+}
156
+
157
+// AssetNames returns the names of the assets.
158
+func AssetNames() []string {
159
+	names := make([]string, 0, len(_bindata))
160
+	for name := range _bindata {
161
+		names = append(names, name)
162
+	}
163
+	return names
164
+}
165
+
166
+// _bindata is a table, holding each asset generator, mapped to its name.
167
+var _bindata = map[string]func() ([]byte, error){
168
+`)
169
+	return err
170
+}
171
+
172
+// writeTOCAsset write a TOC entry for the given asset.
173
+func writeTOCAsset(w io.Writer, asset *Asset) error {
174
+	_, err := fmt.Fprintf(w, "\t%q: %s,\n", asset.Name, asset.Func)
175
+	return err
176
+}
177
+
178
+// writeTOCFooter writes the table of contents file footer.
179
+func writeTOCFooter(w io.Writer) error {
180
+	_, err := fmt.Fprintf(w, `}
181
+`)
182
+	return err
183
+}