forked from lug/matterbridge
		
	
		
			
				
	
	
		
			159 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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)
 | |
| 	}
 | |
| 
 | |
| }
 | 
