summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/GeertJohan/go.rice/rice
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/GeertJohan/go.rice/rice')
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/append.go172
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/clean.go33
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/embed-go.go158
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go204
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/find.go150
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/flags.go80
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/identifier.go14
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/main.go68
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/templates.go98
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/util.go22
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/writecoff.go42
11 files changed, 1041 insertions, 0 deletions
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/append.go b/vendor/github.com/GeertJohan/go.rice/rice/append.go
new file mode 100644
index 00000000..ae3d95fd
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/append.go
@@ -0,0 +1,172 @@
+package main
+
+import (
+ "archive/zip"
+ "fmt"
+ "go/build"
+ "io"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "time"
+
+ "github.com/daaku/go.zipexe"
+)
+
+func operationAppend(pkgs []*build.Package) {
+ if runtime.GOOS == "windows" {
+ _, err := exec.LookPath("zip")
+ if err != nil {
+ fmt.Println("#### WARNING ! ####")
+ fmt.Println("`rice append` is known not to work under windows because the `zip` command is not available. Please let me know if you got this to work (and how).")
+ }
+ }
+
+ // MARKED FOR DELETION
+ // This is actually not required, the append command now has the option --exec required.
+ // // check if package is a command
+ // if !pkg.IsCommand() {
+ // fmt.Println("Error: can not append to non-main package. Please follow instructions at github.com/GeertJohan/go.rice")
+ // os.Exit(1)
+ // }
+
+ // create tmp zipfile
+ tmpZipfileName := filepath.Join(os.TempDir(), fmt.Sprintf("ricebox-%d-%s.zip", time.Now().Unix(), randomString(10)))
+ verbosef("Will create tmp zipfile: %s\n", tmpZipfileName)
+ tmpZipfile, err := os.Create(tmpZipfileName)
+ if err != nil {
+ fmt.Printf("Error creating tmp zipfile: %s\n", err)
+ os.Exit(1)
+ }
+ defer func() {
+ tmpZipfile.Close()
+ os.Remove(tmpZipfileName)
+ }()
+
+ // find abs path for binary file
+ binfileName, err := filepath.Abs(flags.Append.Executable)
+ if err != nil {
+ fmt.Printf("Error finding absolute path for executable to append: %s\n", err)
+ os.Exit(1)
+ }
+ verbosef("Will append to file: %s\n", binfileName)
+
+ // check that command doesn't already have zip appended
+ if rd, _ := zipexe.Open(binfileName); rd != nil {
+ fmt.Printf("Cannot append to already appended executable. Please remove %s and build a fresh one.\n", binfileName)
+ os.Exit(1)
+ }
+
+ // open binfile
+ binfile, err := os.OpenFile(binfileName, os.O_WRONLY, os.ModeAppend)
+ if err != nil {
+ fmt.Printf("Error: unable to open executable file: %s\n", err)
+ os.Exit(1)
+ }
+
+ // create zip.Writer
+ zipWriter := zip.NewWriter(tmpZipfile)
+
+ for _, pkg := range pkgs {
+ // find boxes for this command
+ boxMap := findBoxes(pkg)
+
+ // notify user when no calls to rice.FindBox are made (is this an error and therefore os.Exit(1) ?
+ if len(boxMap) == 0 {
+ fmt.Printf("no calls to rice.FindBox() or rice.MustFindBox() found in import path `%s`\n", pkg.ImportPath)
+ continue
+ }
+
+ verbosef("\n")
+
+ for boxname := range boxMap {
+ appendedBoxName := strings.Replace(boxname, `/`, `-`, -1)
+
+ // walk box path's and insert files
+ boxPath := filepath.Clean(filepath.Join(pkg.Dir, boxname))
+ filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
+ if info == nil {
+ fmt.Printf("Error: box \"%s\" not found on disk\n", path)
+ os.Exit(1)
+ }
+ // create zipFilename
+ zipFileName := filepath.Join(appendedBoxName, strings.TrimPrefix(path, boxPath))
+ // write directories as empty file with comment "dir"
+ if info.IsDir() {
+ _, err := zipWriter.CreateHeader(&zip.FileHeader{
+ Name: zipFileName,
+ Comment: "dir",
+ })
+ if err != nil {
+ fmt.Printf("Error creating dir in tmp zip: %s\n", err)
+ os.Exit(1)
+ }
+ return nil
+ }
+
+ // create zipFileWriter
+ zipFileHeader, err := zip.FileInfoHeader(info)
+ if err != nil {
+ fmt.Printf("Error creating zip FileHeader: %v\n", err)
+ os.Exit(1)
+ }
+ zipFileHeader.Name = zipFileName
+ zipFileWriter, err := zipWriter.CreateHeader(zipFileHeader)
+ if err != nil {
+ fmt.Printf("Error creating file in tmp zip: %s\n", err)
+ os.Exit(1)
+ }
+ srcFile, err := os.Open(path)
+ if err != nil {
+ fmt.Printf("Error opening file to append: %s\n", err)
+ os.Exit(1)
+ }
+ _, err = io.Copy(zipFileWriter, srcFile)
+ if err != nil {
+ fmt.Printf("Error copying file contents to zip: %s\n", err)
+ os.Exit(1)
+ }
+ srcFile.Close()
+
+ return nil
+ })
+ }
+ }
+
+ err = zipWriter.Close()
+ if err != nil {
+ fmt.Printf("Error closing tmp zipfile: %s\n", err)
+ os.Exit(1)
+ }
+
+ err = tmpZipfile.Sync()
+ if err != nil {
+ fmt.Printf("Error syncing tmp zipfile: %s\n", err)
+ os.Exit(1)
+ }
+ _, err = tmpZipfile.Seek(0, 0)
+ if err != nil {
+ fmt.Printf("Error seeking tmp zipfile: %s\n", err)
+ os.Exit(1)
+ }
+ _, err = binfile.Seek(0, 2)
+ if err != nil {
+ fmt.Printf("Error seeking bin file: %s\n", err)
+ os.Exit(1)
+ }
+
+ _, err = io.Copy(binfile, tmpZipfile)
+ if err != nil {
+ fmt.Printf("Error appending zipfile to executable: %s\n", err)
+ os.Exit(1)
+ }
+
+ zipA := exec.Command("zip", "-A", binfileName)
+ err = zipA.Run()
+ if err != nil {
+ fmt.Printf("Error setting zip offset: %s\n", err)
+ os.Exit(1)
+ }
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/clean.go b/vendor/github.com/GeertJohan/go.rice/rice/clean.go
new file mode 100644
index 00000000..6155c064
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/clean.go
@@ -0,0 +1,33 @@
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func operationClean(pkg *build.Package) {
+ filepath.Walk(pkg.Dir, func(filename string, info os.FileInfo, err error) error {
+ if err != nil {
+ fmt.Printf("error walking pkg dir to clean files: %v\n", err)
+ os.Exit(1)
+ }
+ if info.IsDir() {
+ return nil
+ }
+ verbosef("checking file '%s'\n", filename)
+ if filepath.Base(filename) == "rice-box.go" ||
+ strings.HasSuffix(filename, ".rice-box.go") ||
+ strings.HasSuffix(filename, ".rice-box.syso") {
+ err := os.Remove(filename)
+ if err != nil {
+ fmt.Printf("error removing file (%s): %s\n", filename, err)
+ os.Exit(-1)
+ }
+ verbosef("removed file '%s'\n", filename)
+ }
+ return nil
+ })
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/embed-go.go b/vendor/github.com/GeertJohan/go.rice/rice/embed-go.go
new file mode 100644
index 00000000..c5a0e9e8
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/embed-go.go
@@ -0,0 +1,158 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/build"
+ "go/format"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+const boxFilename = "rice-box.go"
+
+func operationEmbedGo(pkg *build.Package) {
+
+ boxMap := findBoxes(pkg)
+
+ // notify user when no calls to rice.FindBox are made (is this an error and therefore os.Exit(1) ?
+ if len(boxMap) == 0 {
+ fmt.Println("no calls to rice.FindBox() found")
+ return
+ }
+
+ verbosef("\n")
+ var boxes []*boxDataType
+
+ for boxname := range boxMap {
+ // find path and filename for this box
+ boxPath := filepath.Join(pkg.Dir, boxname)
+
+ // Check to see if the path for the box is a symbolic link. If so, simply
+ // box what the symbolic link points to. Note: the filepath.Walk function
+ // will NOT follow any nested symbolic links. This only handles the case
+ // where the root of the box is a symbolic link.
+ symPath, serr := os.Readlink(boxPath)
+ if serr == nil {
+ boxPath = symPath
+ }
+
+ // verbose info
+ verbosef("embedding box '%s' to '%s'\n", boxname, boxFilename)
+
+ // read box metadata
+ boxInfo, ierr := os.Stat(boxPath)
+ if ierr != nil {
+ fmt.Printf("Error: unable to access box at %s\n", boxPath)
+ os.Exit(1)
+ }
+
+ // create box datastructure (used by template)
+ box := &boxDataType{
+ BoxName: boxname,
+ UnixNow: boxInfo.ModTime().Unix(),
+ Files: make([]*fileDataType, 0),
+ Dirs: make(map[string]*dirDataType),
+ }
+
+ if !boxInfo.IsDir() {
+ fmt.Printf("Error: Box %s must point to a directory but points to %s instead\n",
+ boxname, boxPath)
+ os.Exit(1)
+ }
+
+ // fill box datastructure with file data
+ filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ fmt.Printf("error walking box: %s\n", err)
+ os.Exit(1)
+ }
+
+ filename := strings.TrimPrefix(path, boxPath)
+ filename = strings.Replace(filename, "\\", "/", -1)
+ filename = strings.TrimPrefix(filename, "/")
+ if info.IsDir() {
+ dirData := &dirDataType{
+ Identifier: "dir" + nextIdentifier(),
+ FileName: filename,
+ ModTime: info.ModTime().Unix(),
+ ChildFiles: make([]*fileDataType, 0),
+ ChildDirs: make([]*dirDataType, 0),
+ }
+ verbosef("\tincludes dir: '%s'\n", dirData.FileName)
+ box.Dirs[dirData.FileName] = dirData
+
+ // add tree entry (skip for root, it'll create a recursion)
+ if dirData.FileName != "" {
+ pathParts := strings.Split(dirData.FileName, "/")
+ parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
+ parentDir.ChildDirs = append(parentDir.ChildDirs, dirData)
+ }
+ } else {
+ fileData := &fileDataType{
+ Identifier: "file" + nextIdentifier(),
+ FileName: filename,
+ ModTime: info.ModTime().Unix(),
+ }
+ verbosef("\tincludes file: '%s'\n", fileData.FileName)
+ fileData.Content, err = ioutil.ReadFile(path)
+ if err != nil {
+ fmt.Printf("error reading file content while walking box: %s\n", err)
+ os.Exit(1)
+ }
+ box.Files = append(box.Files, fileData)
+
+ // add tree entry
+ pathParts := strings.Split(fileData.FileName, "/")
+ parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
+ if parentDir == nil {
+ fmt.Printf("Error: parent of %s is not within the box\n", path)
+ os.Exit(1)
+ }
+ parentDir.ChildFiles = append(parentDir.ChildFiles, fileData)
+ }
+ return nil
+ })
+ boxes = append(boxes, box)
+
+ }
+
+ embedSourceUnformated := bytes.NewBuffer(make([]byte, 0))
+
+ // execute template to buffer
+ err := tmplEmbeddedBox.Execute(
+ embedSourceUnformated,
+ embedFileDataType{pkg.Name, boxes},
+ )
+ if err != nil {
+ log.Printf("error writing embedded box to file (template execute): %s\n", err)
+ os.Exit(1)
+ }
+
+ // format the source code
+ embedSource, err := format.Source(embedSourceUnformated.Bytes())
+ if err != nil {
+ log.Printf("error formatting embedSource: %s\n", err)
+ os.Exit(1)
+ }
+
+ // create go file for box
+ boxFile, err := os.Create(filepath.Join(pkg.Dir, boxFilename))
+ if err != nil {
+ log.Printf("error creating embedded box file: %s\n", err)
+ os.Exit(1)
+ }
+ defer boxFile.Close()
+
+ // write source to file
+ _, err = io.Copy(boxFile, bytes.NewBuffer(embedSource))
+ if err != nil {
+ log.Printf("error writing embedSource to file: %s\n", err)
+ os.Exit(1)
+ }
+
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go b/vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go
new file mode 100644
index 00000000..beef3ea7
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go
@@ -0,0 +1,204 @@
+package main
+
+import (
+ "bytes"
+ "encoding/gob"
+ "fmt"
+ "go/build"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "text/template"
+
+ "github.com/GeertJohan/go.rice/embedded"
+ "github.com/akavel/rsrc/coff"
+)
+
+type sizedReader struct {
+ *bytes.Reader
+}
+
+func (s sizedReader) Size() int64 {
+ return int64(s.Len())
+}
+
+var tmplEmbeddedSysoHelper *template.Template
+
+func init() {
+ var err error
+ tmplEmbeddedSysoHelper, err = template.New("embeddedSysoHelper").Parse(`package {{.Package}}
+// ############# GENERATED CODE #####################
+// ## This file was generated by the rice tool.
+// ## Do not edit unless you know what you're doing.
+// ##################################################
+
+// extern char _bricebox_{{.Symname}}[], _ericebox_{{.Symname}};
+// int get_{{.Symname}}_length() {
+// return &_ericebox_{{.Symname}} - _bricebox_{{.Symname}};
+// }
+import "C"
+import (
+ "bytes"
+ "encoding/gob"
+ "github.com/GeertJohan/go.rice/embedded"
+ "unsafe"
+)
+
+func init() {
+ ptr := unsafe.Pointer(&C._bricebox_{{.Symname}})
+ bts := C.GoBytes(ptr, C.get_{{.Symname}}_length())
+ embeddedBox := &embedded.EmbeddedBox{}
+ err := gob.NewDecoder(bytes.NewReader(bts)).Decode(embeddedBox)
+ if err != nil {
+ panic("error decoding embedded box: "+err.Error())
+ }
+ embeddedBox.Link()
+ embedded.RegisterEmbeddedBox(embeddedBox.Name, embeddedBox)
+}`)
+ if err != nil {
+ panic("could not parse template embeddedSysoHelper: " + err.Error())
+ }
+}
+
+type embeddedSysoHelperData struct {
+ Package string
+ Symname string
+}
+
+func operationEmbedSyso(pkg *build.Package) {
+
+ regexpSynameReplacer := regexp.MustCompile(`[^a-z0-9_]`)
+
+ boxMap := findBoxes(pkg)
+
+ // notify user when no calls to rice.FindBox are made (is this an error and therefore os.Exit(1) ?
+ if len(boxMap) == 0 {
+ fmt.Println("no calls to rice.FindBox() found")
+ return
+ }
+
+ verbosef("\n")
+
+ for boxname := range boxMap {
+ // find path and filename for this box
+ boxPath := filepath.Join(pkg.Dir, boxname)
+ boxFilename := strings.Replace(boxname, "/", "-", -1)
+ boxFilename = strings.Replace(boxFilename, "..", "back", -1)
+ boxFilename = strings.Replace(boxFilename, ".", "-", -1)
+
+ // verbose info
+ verbosef("embedding box '%s'\n", boxname)
+ verbosef("\tto file %s\n", boxFilename)
+
+ // read box metadata
+ boxInfo, ierr := os.Stat(boxPath)
+ if ierr != nil {
+ fmt.Printf("Error: unable to access box at %s\n", boxPath)
+ os.Exit(1)
+ }
+
+ // create box datastructure (used by template)
+ box := &embedded.EmbeddedBox{
+ Name: boxname,
+ Time: boxInfo.ModTime(),
+ EmbedType: embedded.EmbedTypeSyso,
+ Files: make(map[string]*embedded.EmbeddedFile),
+ Dirs: make(map[string]*embedded.EmbeddedDir),
+ }
+
+ // fill box datastructure with file data
+ filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ fmt.Printf("error walking box: %s\n", err)
+ os.Exit(1)
+ }
+
+ filename := strings.TrimPrefix(path, boxPath)
+ filename = strings.Replace(filename, "\\", "/", -1)
+ filename = strings.TrimPrefix(filename, "/")
+ if info.IsDir() {
+ embeddedDir := &embedded.EmbeddedDir{
+ Filename: filename,
+ DirModTime: info.ModTime(),
+ }
+ verbosef("\tincludes dir: '%s'\n", embeddedDir.Filename)
+ box.Dirs[embeddedDir.Filename] = embeddedDir
+
+ // add tree entry (skip for root, it'll create a recursion)
+ if embeddedDir.Filename != "" {
+ pathParts := strings.Split(embeddedDir.Filename, "/")
+ parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
+ parentDir.ChildDirs = append(parentDir.ChildDirs, embeddedDir)
+ }
+ } else {
+ embeddedFile := &embedded.EmbeddedFile{
+ Filename: filename,
+ FileModTime: info.ModTime(),
+ Content: "",
+ }
+ verbosef("\tincludes file: '%s'\n", embeddedFile.Filename)
+ contentBytes, err := ioutil.ReadFile(path)
+ if err != nil {
+ fmt.Printf("error reading file content while walking box: %s\n", err)
+ os.Exit(1)
+ }
+ embeddedFile.Content = string(contentBytes)
+ box.Files[embeddedFile.Filename] = embeddedFile
+ }
+ return nil
+ })
+
+ // encode embedded box to gob file
+ boxGobBuf := &bytes.Buffer{}
+ err := gob.NewEncoder(boxGobBuf).Encode(box)
+ if err != nil {
+ fmt.Printf("error encoding box to gob: %v\n", err)
+ os.Exit(1)
+ }
+
+ verbosef("gob-encoded embeddedBox is %d bytes large\n", boxGobBuf.Len())
+
+ // write coff
+ symname := regexpSynameReplacer.ReplaceAllString(boxname, "_")
+ createCoffSyso(boxname, symname, "386", boxGobBuf.Bytes())
+ createCoffSyso(boxname, symname, "amd64", boxGobBuf.Bytes())
+
+ // write go
+ sysoHelperData := embeddedSysoHelperData{
+ Package: pkg.Name,
+ Symname: symname,
+ }
+ fileSysoHelper, err := os.Create(boxFilename + ".rice-box.go")
+ if err != nil {
+ fmt.Printf("error creating syso helper: %v\n", err)
+ os.Exit(1)
+ }
+ err = tmplEmbeddedSysoHelper.Execute(fileSysoHelper, sysoHelperData)
+ if err != nil {
+ fmt.Printf("error executing tmplEmbeddedSysoHelper: %v\n", err)
+ os.Exit(1)
+ }
+ }
+}
+
+func createCoffSyso(boxFilename string, symname string, arch string, data []byte) {
+ boxCoff := coff.NewRDATA()
+ switch arch {
+ case "386":
+ case "amd64":
+ boxCoff.FileHeader.Machine = 0x8664
+ default:
+ panic("invalid arch")
+ }
+ boxCoff.AddData("_bricebox_"+symname, sizedReader{bytes.NewReader(data)})
+ boxCoff.AddData("_ericebox_"+symname, io.NewSectionReader(strings.NewReader("\000\000"), 0, 2)) // TODO: why? copied from rsrc, which copied it from as-generated
+ boxCoff.Freeze()
+ err := writeCoff(boxCoff, boxFilename+"_"+arch+".rice-box.syso")
+ if err != nil {
+ fmt.Printf("error writing %s coff/.syso: %v\n", arch, err)
+ os.Exit(1)
+ }
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/find.go b/vendor/github.com/GeertJohan/go.rice/rice/find.go
new file mode 100644
index 00000000..6d78eeaa
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/find.go
@@ -0,0 +1,150 @@
+package main
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func badArgument(fileset *token.FileSet, p token.Pos) {
+ pos := fileset.Position(p)
+ filename := pos.Filename
+ base, err := os.Getwd()
+ if err == nil {
+ rpath, perr := filepath.Rel(base, pos.Filename)
+ if perr == nil {
+ filename = rpath
+ }
+ }
+ msg := fmt.Sprintf("%s:%d: Error: found call to rice.FindBox, "+
+ "but argument must be a string literal.\n", filename, pos.Line)
+ fmt.Println(msg)
+ os.Exit(1)
+}
+
+func findBoxes(pkg *build.Package) map[string]bool {
+ // create map of boxes to embed
+ var boxMap = make(map[string]bool)
+
+ // create one list of files for this package
+ filenames := make([]string, 0, len(pkg.GoFiles)+len(pkg.CgoFiles))
+ filenames = append(filenames, pkg.GoFiles...)
+ filenames = append(filenames, pkg.CgoFiles...)
+
+ // loop over files, search for rice.FindBox(..) calls
+ for _, filename := range filenames {
+ // find full filepath
+ fullpath := filepath.Join(pkg.Dir, filename)
+ if strings.HasSuffix(filename, "rice-box.go") {
+ // Ignore *.rice-box.go files
+ verbosef("skipping file %q\n", fullpath)
+ continue
+ }
+ verbosef("scanning file %q\n", fullpath)
+
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, fullpath, nil, 0)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ var riceIsImported bool
+ ricePkgName := "rice"
+ for _, imp := range f.Imports {
+ if strings.HasSuffix(imp.Path.Value, "go.rice\"") {
+ if imp.Name != nil {
+ ricePkgName = imp.Name.Name
+ }
+ riceIsImported = true
+ break
+ }
+ }
+ if !riceIsImported {
+ // Rice wasn't imported, so we won't find a box.
+ continue
+ }
+ if ricePkgName == "_" {
+ // Rice pkg is unnamed, so we won't find a box.
+ continue
+ }
+
+ // Inspect AST, looking for calls to (Must)?FindBox.
+ // First parameter of the func must be a basic literal.
+ // Identifiers won't be resolved.
+ var nextIdentIsBoxFunc bool
+ var nextBasicLitParamIsBoxName bool
+ var boxCall token.Pos
+ var variableToRemember string
+ var validVariablesForBoxes map[string]bool = make(map[string]bool)
+
+ ast.Inspect(f, func(node ast.Node) bool {
+ if node == nil {
+ return false
+ }
+ switch x := node.(type) {
+ // this case fixes the var := func() style assignments, not assignments to vars declared separately from the assignment.
+ case *ast.AssignStmt:
+ var assign = node.(*ast.AssignStmt)
+ name, found := assign.Lhs[0].(*ast.Ident)
+ if found {
+ variableToRemember = name.Name
+ composite, first := assign.Rhs[0].(*ast.CompositeLit)
+ if first {
+ riceSelector, second := composite.Type.(*ast.SelectorExpr)
+
+ if second {
+ callCorrect := riceSelector.Sel.Name == "Config"
+ packageName, third := riceSelector.X.(*ast.Ident)
+
+ if third && callCorrect && packageName.Name == ricePkgName {
+ validVariablesForBoxes[name.Name] = true
+ verbosef("\tfound variable, saving to scan for boxes: %q\n", name.Name)
+ }
+ }
+ }
+ }
+ case *ast.Ident:
+ if nextIdentIsBoxFunc || ricePkgName == "." {
+ nextIdentIsBoxFunc = false
+ if x.Name == "FindBox" || x.Name == "MustFindBox" {
+ nextBasicLitParamIsBoxName = true
+ boxCall = x.Pos()
+ }
+ } else {
+ if x.Name == ricePkgName || validVariablesForBoxes[x.Name] {
+ nextIdentIsBoxFunc = true
+ }
+ }
+ case *ast.BasicLit:
+ if nextBasicLitParamIsBoxName {
+ if x.Kind == token.STRING {
+ nextBasicLitParamIsBoxName = false
+ // trim "" or ``
+ name := x.Value[1 : len(x.Value)-1]
+ boxMap[name] = true
+ verbosef("\tfound box %q\n", name)
+ } else {
+ badArgument(fset, boxCall)
+ }
+ }
+
+ default:
+ if nextIdentIsBoxFunc {
+ nextIdentIsBoxFunc = false
+ }
+ if nextBasicLitParamIsBoxName {
+ badArgument(fset, boxCall)
+ }
+ }
+ return true
+ })
+ }
+
+ return boxMap
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/flags.go b/vendor/github.com/GeertJohan/go.rice/rice/flags.go
new file mode 100644
index 00000000..167fea80
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/flags.go
@@ -0,0 +1,80 @@
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "os"
+
+ goflags "github.com/jessevdk/go-flags" // rename import to `goflags` (file scope) so we can use `var flags` (package scope)
+)
+
+// flags
+var flags struct {
+ Verbose bool `long:"verbose" short:"v" description:"Show verbose debug information"`
+ ImportPaths []string `long:"import-path" short:"i" description:"Import path(s) to use. Using PWD when left empty. Specify multiple times for more import paths to append"`
+
+ Append struct {
+ Executable string `long:"exec" description:"Executable to append" required:"true"`
+ } `command:"append"`
+
+ EmbedGo struct{} `command:"embed-go" alias:"embed"`
+ EmbedSyso struct{} `command:"embed-syso"`
+ Clean struct{} `command:"clean"`
+}
+
+// flags parser
+var flagsParser *goflags.Parser
+
+// initFlags parses the given flags.
+// when the user asks for help (-h or --help): the application exists with status 0
+// when unexpected flags is given: the application exits with status 1
+func parseArguments() {
+ // create flags parser in global var, for flagsParser.Active.Name (operation)
+ flagsParser = goflags.NewParser(&flags, goflags.Default)
+
+ // parse flags
+ args, err := flagsParser.Parse()
+ if err != nil {
+ // assert the err to be a flags.Error
+ flagError := err.(*goflags.Error)
+ if flagError.Type == goflags.ErrHelp {
+ // user asked for help on flags.
+ // program can exit successfully
+ os.Exit(0)
+ }
+ if flagError.Type == goflags.ErrUnknownFlag {
+ fmt.Println("Use --help to view available options.")
+ os.Exit(1)
+ }
+ if flagError.Type == goflags.ErrRequired {
+ os.Exit(1)
+ }
+ fmt.Printf("Error parsing flags: %s\n", err)
+ os.Exit(1)
+ }
+
+ // error on left-over arguments
+ if len(args) > 0 {
+ fmt.Printf("Unexpected arguments: %s\nUse --help to view available options.", args)
+ os.Exit(1)
+ }
+
+ // default ImportPath to pwd when not set
+ if len(flags.ImportPaths) == 0 {
+ pwd, err := os.Getwd()
+ if err != nil {
+ fmt.Printf("error getting pwd: %s\n", err)
+ os.Exit(1)
+ }
+ verbosef("using pwd as import path\n")
+ // find non-absolute path for this pwd
+ pkg, err := build.ImportDir(pwd, build.FindOnly)
+ if err != nil {
+ fmt.Printf("error using current directory as import path: %s\n", err)
+ os.Exit(1)
+ }
+ flags.ImportPaths = append(flags.ImportPaths, pkg.ImportPath)
+ verbosef("using import paths: %s\n", flags.ImportPaths)
+ return
+ }
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/identifier.go b/vendor/github.com/GeertJohan/go.rice/rice/identifier.go
new file mode 100644
index 00000000..445ee7da
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/identifier.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ "strconv"
+
+ "github.com/GeertJohan/go.incremental"
+)
+
+var identifierCount incremental.Uint64
+
+func nextIdentifier() string {
+ num := identifierCount.Next()
+ return strconv.FormatUint(num, 36) // 0123456789abcdefghijklmnopqrstuvwxyz
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/main.go b/vendor/github.com/GeertJohan/go.rice/rice/main.go
new file mode 100644
index 00000000..7bac5fa3
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/main.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "log"
+ "os"
+)
+
+func main() {
+ // parser arguments
+ parseArguments()
+
+ // find package for path
+ var pkgs []*build.Package
+ for _, importPath := range flags.ImportPaths {
+ pkg := pkgForPath(importPath)
+ pkgs = append(pkgs, pkg)
+ }
+
+ // switch on the operation to perform
+ switch flagsParser.Active.Name {
+ case "embed", "embed-go":
+ for _, pkg := range pkgs {
+ operationEmbedGo(pkg)
+ }
+ case "embed-syso":
+ log.Println("WARNING: embedding .syso is experimental..")
+ for _, pkg := range pkgs {
+ operationEmbedSyso(pkg)
+ }
+ case "append":
+ operationAppend(pkgs)
+ case "clean":
+ for _, pkg := range pkgs {
+ operationClean(pkg)
+ }
+ }
+
+ // all done
+ verbosef("\n")
+ verbosef("rice finished successfully\n")
+}
+
+// helper function to get *build.Package for given path
+func pkgForPath(path string) *build.Package {
+ // get pwd for relative imports
+ pwd, err := os.Getwd()
+ if err != nil {
+ fmt.Printf("error getting pwd (required for relative imports): %s\n", err)
+ os.Exit(1)
+ }
+
+ // read full package information
+ pkg, err := build.Import(path, pwd, 0)
+ if err != nil {
+ fmt.Printf("error reading package: %s\n", err)
+ os.Exit(1)
+ }
+
+ return pkg
+}
+
+func verbosef(format string, stuff ...interface{}) {
+ if flags.Verbose {
+ log.Printf(format, stuff...)
+ }
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/templates.go b/vendor/github.com/GeertJohan/go.rice/rice/templates.go
new file mode 100644
index 00000000..02561ca0
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/templates.go
@@ -0,0 +1,98 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "text/template"
+)
+
+var tmplEmbeddedBox *template.Template
+
+func init() {
+ var err error
+
+ // parse embedded box template
+ tmplEmbeddedBox, err = template.New("embeddedBox").Parse(`package {{.Package}}
+
+import (
+ "github.com/GeertJohan/go.rice/embedded"
+ "time"
+)
+
+{{range .Boxes}}
+func init() {
+
+ // define files
+ {{range .Files}}{{.Identifier}} := &embedded.EmbeddedFile{
+ Filename: ` + "`" + `{{.FileName}}` + "`" + `,
+ FileModTime: time.Unix({{.ModTime}}, 0),
+ Content: string({{.Content | printf "%q"}}),
+ }
+ {{end}}
+
+ // define dirs
+ {{range .Dirs}}{{.Identifier}} := &embedded.EmbeddedDir{
+ Filename: ` + "`" + `{{.FileName}}` + "`" + `,
+ DirModTime: time.Unix({{.ModTime}}, 0),
+ ChildFiles: []*embedded.EmbeddedFile{
+ {{range .ChildFiles}}{{.Identifier}}, // {{.FileName}}
+ {{end}}
+ },
+ }
+ {{end}}
+
+ // link ChildDirs
+ {{range .Dirs}}{{.Identifier}}.ChildDirs = []*embedded.EmbeddedDir{
+ {{range .ChildDirs}}{{.Identifier}}, // {{.FileName}}
+ {{end}}
+ }
+ {{end}}
+
+ // register embeddedBox
+ embedded.RegisterEmbeddedBox(` + "`" + `{{.BoxName}}` + "`" + `, &embedded.EmbeddedBox{
+ Name: ` + "`" + `{{.BoxName}}` + "`" + `,
+ Time: time.Unix({{.UnixNow}}, 0),
+ Dirs: map[string]*embedded.EmbeddedDir{
+ {{range .Dirs}}"{{.FileName}}": {{.Identifier}},
+ {{end}}
+ },
+ Files: map[string]*embedded.EmbeddedFile{
+ {{range .Files}}"{{.FileName}}": {{.Identifier}},
+ {{end}}
+ },
+ })
+}
+{{end}}`)
+ if err != nil {
+ fmt.Printf("error parsing embedded box template: %s\n", err)
+ os.Exit(-1)
+ }
+}
+
+type embedFileDataType struct {
+ Package string
+ Boxes []*boxDataType
+}
+
+type boxDataType struct {
+ BoxName string
+ UnixNow int64
+ Files []*fileDataType
+ Dirs map[string]*dirDataType
+}
+
+type fileDataType struct {
+ Identifier string
+ FileName string
+ Content []byte
+ ModTime int64
+}
+
+type dirDataType struct {
+ Identifier string
+ FileName string
+ Content []byte
+ ModTime int64
+ ChildDirs []*dirDataType
+ ChildFiles []*fileDataType
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/util.go b/vendor/github.com/GeertJohan/go.rice/rice/util.go
new file mode 100644
index 00000000..c9ed4b0a
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/util.go
@@ -0,0 +1,22 @@
+package main
+
+import (
+ "math/rand"
+ "time"
+)
+
+// randomString generates a pseudo-random alpha-numeric string with given length.
+func randomString(length int) string {
+ rand.Seed(time.Now().UnixNano())
+ k := make([]rune, length)
+ for i := 0; i < length; i++ {
+ c := rand.Intn(35)
+ if c < 10 {
+ c += 48 // numbers (0-9) (0+48 == 48 == '0', 9+48 == 57 == '9')
+ } else {
+ c += 87 // lower case alphabets (a-z) (10+87 == 97 == 'a', 35+87 == 122 = 'z')
+ }
+ k[i] = rune(c)
+ }
+ return string(k)
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/writecoff.go b/vendor/github.com/GeertJohan/go.rice/rice/writecoff.go
new file mode 100644
index 00000000..0c12c0ff
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/writecoff.go
@@ -0,0 +1,42 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "reflect"
+
+ "github.com/akavel/rsrc/binutil"
+ "github.com/akavel/rsrc/coff"
+)
+
+// copied from github.com/akavel/rsrc
+// LICENSE: MIT
+// Copyright 2013-2014 The rsrc Authors. (https://github.com/akavel/rsrc/blob/master/AUTHORS)
+func writeCoff(coff *coff.Coff, fnameout string) error {
+ out, err := os.Create(fnameout)
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+ w := binutil.Writer{W: out}
+
+ // write the resulting file to disk
+ binutil.Walk(coff, func(v reflect.Value, path string) error {
+ if binutil.Plain(v.Kind()) {
+ w.WriteLE(v.Interface())
+ return nil
+ }
+ vv, ok := v.Interface().(binutil.SizedReader)
+ if ok {
+ w.WriteFromSized(vv)
+ return binutil.WALK_SKIP
+ }
+ return nil
+ })
+
+ if w.Err != nil {
+ return fmt.Errorf("Error writing output file: %s", w.Err)
+ }
+
+ return nil
+}