Changed from package to command. Removed bindata dependency from generated go files by embedding the unpacking code in the generated function.

This commit is contained in:
jim teeuwen 2011-06-17 17:44:59 +02:00
commit 2a84f0bab0
9 changed files with 2135 additions and 0 deletions

10
CONTRIBUTORS Normal file
View File

@ -0,0 +1,10 @@
# This is the list of people who can contribute (or have contributed) to this
# project. This includes code, documentation, testing, content creation and
# bugfixes.
#
# Names should be added to this file like so:
# Name [<email address>]
#
# Please keep the list sorted.
Jim Teeuwen <jimteeuwen at gmail dot com>

3
LICENSE Normal file
View File

@ -0,0 +1,3 @@
This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
license. Its contents can be found at:
http://creativecommons.org/publicdomain/zero/1.0

15
Makefile Normal file
View File

@ -0,0 +1,15 @@
# This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
# license. Its contents can be found at:
# http://creativecommons.org/publicdomain/zero/1.0
include $(GOROOT)/src/Make.inc
TARG = bindata
GOFILES = main.go gowriter.go bindata.go
all:
$(GC) -o $(TARG).6 $(GOFILES)
$(LD) -s -o $(TARG) $(TARG).6
clean:
rm -rf *.o *.a *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* *.so *.exe $(TARG)

56
README Normal file
View File

@ -0,0 +1,56 @@
================================================================================
bindata
================================================================================
This tool converts any file into managable Go source code. Useful for embedding
binary data into a go program. The file data is gzip compressed before being
converted to a raw byte slice.
If gofmt is available on the system, bindata will invoke it to format the
generated go file.
================================================================================
DEPENDENCIES
================================================================================
n/a
================================================================================
USAGE
================================================================================
$ goinstall github.com/jteeuwen/go-bindata
The simplest invocation is to pass it only the input file name.
The output file and code settings are inferred from this automatically.
$ bindata -i testdata/gophercolor.png
[w] No output file specified. Using 'testdata/gophercolor.png.go'.
[w] No package name specified. Using 'main'.
[w] No function name specified. Using 'gophercolor_png'.
[i] Done.
This creates the "testdata/gophercolor.png.go" file which has a package
declaration with name 'main' and one function named 'gophercolor_png'.
It looks like this:
func gophercolor_png() ([]byte, os.Error) {
var gz *gzip.Decompressor
var err os.Error
if gz, err = gzip.NewReader(bytes.NewBuffer([]byte{
...
})); err != nil {
return nil, err
}
var b bytes.Buffer
io.Copy(&b, gz)
gz.Close()
return b.Bytes(), nil
}
You can now simply include the new .go file in your program and call
gophercolor_png() to get the uncompressed image data.
Invoke the program with the -h flag for more options.

74
bindata.go Normal file
View File

@ -0,0 +1,74 @@
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
// license. Its contents can be found at:
// http://creativecommons.org/publicdomain/zero/1.0/
package main
import (
"path"
"fmt"
"exec"
"io"
"os"
"compress/gzip"
)
// If gofmt exists on the system, run it over the target file to
// fix up the generated code. This is not necessary, just a convenience.
func gofmt(file string) (err os.Error) {
var prog string
if prog = os.Getenv("GOBIN"); len(prog) == 0 {
return
}
prog = path.Join(prog, "gofmt")
cmd := exec.Command(prog, "-w", file)
return cmd.Run()
}
// Translate the input file.
// input -> gzip -> gowriter -> output.
func translate(input, output, pkgname, funcname string) (err os.Error) {
var fs, fd *os.File
var gz *gzip.Compressor
if fs, err = os.Open(input); err != nil {
return
}
defer fs.Close()
if fd, err = os.Create(output); err != nil {
return
}
defer fd.Close()
fmt.Fprintf(fd, `// auto generated from '%s'.
package %s
import ( "io"; "os"; "bytes"; "compress/gzip" )
func %s() ([]byte, os.Error) {
var gz *gzip.Decompressor
var err os.Error
if gz, err = gzip.NewReader(bytes.NewBuffer([]byte{`, input, pkgname, funcname)
if gz, err = gzip.NewWriter(&GoWriter{Writer: fd}); err != nil {
return
}
io.Copy(gz, fs)
gz.Close()
fmt.Fprint(fd, `
})); err != nil {
return nil, err
}
var b bytes.Buffer
io.Copy(&b, gz)
gz.Close()
return b.Bytes(), nil}`)
return
}

34
gowriter.go Normal file
View File

@ -0,0 +1,34 @@
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
// license. Its contents can be found at:
// http://creativecommons.org/publicdomain/zero/1.0/
package main
import (
"fmt"
"io"
"os"
)
type GoWriter struct {
io.Writer
c int
}
func (this *GoWriter) Write(p []byte) (n int, err os.Error) {
if len(p) == 0 {
return
}
for n = range p {
if this.c%12 == 0 {
this.Writer.Write([]byte{'\n'})
this.c = 0
}
fmt.Fprintf(this.Writer, "0x%02x,", p[n])
this.c++
}
return
}

93
main.go Normal file
View File

@ -0,0 +1,93 @@
// Copyright (c) 2010, Jim Teeuwen. All rights reserved.
// This code is subject to a 1-clause BSD license.
// See the LICENSE file for its contents.
package main
import (
"os"
"flag"
"fmt"
"path"
"strings"
"runtime"
)
const (
APP_NAME = "bindata"
APP_VERSION = "0.2"
)
func main() {
in := flag.String("i", "", "Path to the input file.")
out := flag.String("o", "", "Optional path to the output file.")
pkgname := flag.String("p", "", "Optional name of the package to generate.")
funcname := flag.String("f", "", "Optional name of the function to generate.")
version := flag.Bool("v", false, "Display version information.")
flag.Parse()
if *version {
fmt.Fprintf(os.Stdout, "%s v%s (Go runtime %s)\n",
APP_NAME, APP_VERSION, runtime.Version())
return
}
if len(*in) == 0 {
fmt.Fprintln(os.Stderr, "[e] No input file specified.")
os.Exit(1)
}
if len(*out) == 0 {
// Ensure we create our own output filename that does not already exist.
dir, file := path.Split(*in)
*out = path.Join(dir, file) + ".go"
if _, err := os.Lstat(*out); err == nil {
// File already exists. Pad name with a sequential number until we
// find a name that is available.
count := 0
for {
f := path.Join(dir, fmt.Sprintf("%s.%d.go", file, count))
if _, err := os.Lstat(f); err != nil {
*out = f
break
}
count++
}
}
fmt.Fprintf(os.Stderr, "[w] No output file specified. Using '%s'.\n", *out)
}
if len(*pkgname) == 0 {
fmt.Fprintln(os.Stderr, "[w] No package name specified. Using 'main'.")
*pkgname = "main"
}
if len(*funcname) == 0 {
_, file := path.Split(*in)
file = strings.ToLower(file)
file = strings.Replace(file, " ", "_", -1)
file = strings.Replace(file, ".", "_", -1)
file = strings.Replace(file, "-", "_", -1)
fmt.Fprintf(os.Stderr, "[w] No function name specified. Using '%s'.\n", file)
*funcname = file
}
// Read the input file, transform it into a gzip compressed data stream and
// write it out as a go source file.
if err := translate(*in, *out, *pkgname, *funcname); err != nil {
fmt.Fprintf(os.Stderr, "[e] %s\n", err)
return
}
// If gofmt exists on the system, use it to format the generated source file.
if err := gofmt(*out); err != nil {
fmt.Fprintf(os.Stderr, "[e] %s\n", err)
os.Exit(1)
}
fmt.Fprintln(os.Stdout, "[i] Done.")
}

BIN
testdata/gophercolor.png vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

1850
testdata/gophercolor.png.go vendored Normal file

File diff suppressed because it is too large Load Diff