158 lines
4.0 KiB
Go
158 lines
4.0 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"archive/zip"
|
||
|
"fmt"
|
||
|
"go/build"
|
||
|
"io"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
zipexe "github.com/daaku/go.zipexe"
|
||
|
)
|
||
|
|
||
|
func operationAppend(pkgs []*build.Package) {
|
||
|
// 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)
|
||
|
}
|
||
|
defer binfile.Close()
|
||
|
|
||
|
binfileInfo, err := binfile.Stat()
|
||
|
if err != nil {
|
||
|
fmt.Printf("Error: unable to stat executable file: %s\n", err)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
|
||
|
// create zip.Writer
|
||
|
zipWriter := zip.NewWriter(tmpZipfile)
|
||
|
|
||
|
// write the zip offset into the zip data
|
||
|
zipWriter.SetOffset(binfileInfo.Size())
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
}
|