diff --git a/bale.go b/bale.go index 1d0a2e3..6095f5c 100644 --- a/bale.go +++ b/bale.go @@ -15,6 +15,10 @@ package main import ( + "bytes" + "compress/gzip" + "fmt" + "io" "os" "path" "path/filepath" @@ -47,27 +51,136 @@ func runBale(cmd *Command, args []string) { com.ColorLog("[ERRO] Fail to parse bee.json[ %s ]\n", err) } + os.RemoveAll("bale") os.Mkdir("bale", os.ModePerm) + // Pack and compress data. for _, p := range conf.Bale.Dirs { filepath.Walk(p, walkFn) } + + // Generate auto-uncompress function. + buf := new(bytes.Buffer) + buf.WriteString(fmt.Sprintf(_BALE_HEADER, conf.Bale.Import, + strings.Join(resFiles, "\",\n\t\t\""), + strings.Join(resFiles, ",\n\t\tbale.R"))) + + fw, err := os.Create("bale.go") + if err != nil { + com.ColorLog("[ERRO] Fail to create file[ %s ]\n", err) + os.Exit(2) + } + defer fw.Close() + + _, err = fw.Write(buf.Bytes()) + if err != nil { + com.ColorLog("[ERRO] Fail to write data[ %s ]\n", err) + os.Exit(2) + } + + com.ColorLog("[SUCC] Baled resources successfully!\n") } +const ( + _BALE_HEADER = `package main + +import( + "os" + "strings" + "path" + + "%s" +) + +func isExist(path string) bool { + _, err := os.Stat(path) + return err == nil || os.IsExist(err) +} + +func init() { + files := []string{ + "%s", + } + + funcs := []func() []byte{ + bale.R%s, + } + + for i, f := range funcs { + fp := getFilePath(files[i]) + if !isExist(fp) { + saveFile(fp, f()) + } + } +} + +func getFilePath(name string) string { + name = strings.Replace(name, "_4_", "/", -1) + name = strings.Replace(name, "_3_", " ", -1) + name = strings.Replace(name, "_2_", "-", -1) + name = strings.Replace(name, "_1_", ".", -1) + name = strings.Replace(name, "_0_", "_", -1) + return name +} + +func saveFile(filePath string, b []byte) (int, error) { + os.MkdirAll(path.Dir(filePath), os.ModePerm) + fw, err := os.Create(filePath) + if err != nil { + return 0, err + } + defer fw.Close() + return fw.Write(b) +} +` +) + +var resFiles = make([]string, 0, 10) + func walkFn(resPath string, info os.FileInfo, err error) error { if info.IsDir() || filterSuffix(resPath) { return nil } - resPath = strings.Replace(resPath, "_", "__", -1) - resPath = strings.Replace(resPath, ".", "___", -1) + // Open resource files. + fr, err := os.Open(resPath) + if err != nil { + com.ColorLog("[ERRO] Fail to read file[ %s ]\n", err) + os.Exit(2) + } + + // Convert path. + resPath = strings.Replace(resPath, "_", "_0_", -1) + resPath = strings.Replace(resPath, ".", "_1_", -1) + resPath = strings.Replace(resPath, "-", "_2_", -1) + resPath = strings.Replace(resPath, " ", "_3_", -1) sep := "/" if runtime.GOOS == "windows" { sep = "\\" } - resPath = strings.Replace(resPath, sep, "_", -1) + resPath = strings.Replace(resPath, sep, "_4_", -1) + + // Create corresponding Go source files. os.MkdirAll(path.Dir(resPath), os.ModePerm) - os.Create("bale/" + resPath + ".go") + fw, err := os.Create("bale/" + resPath + ".go") + if err != nil { + com.ColorLog("[ERRO] Fail to create file[ %s ]\n", err) + os.Exit(2) + } + defer fw.Close() + + // Write header. + fmt.Fprintf(fw, _HEADER, resPath) + + // Copy and compress data. + gz := gzip.NewWriter(&ByteWriter{Writer: fw}) + io.Copy(gz, fr) + gz.Close() + + // Write footer. + fmt.Fprint(fw, _FOOTER) + + resFiles = append(resFiles, resPath) return nil } @@ -79,3 +192,56 @@ func filterSuffix(name string) bool { } return false } + +const ( + _HEADER = `package bale + +import( + "bytes" + "compress/gzip" + "io" +) + +func R%s() []byte { + gz, err := gzip.NewReader(bytes.NewBuffer([]byte{` + _FOOTER = ` + })) + + if err != nil { + panic("Unpack resources failed: " + err.Error()) + } + + var b bytes.Buffer + io.Copy(&b, gz) + gz.Close() + + return b.Bytes() +}` +) + +var newline = []byte{'\n'} + +type ByteWriter struct { + io.Writer + c int +} + +func (w *ByteWriter) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return + } + + for n = range p { + if w.c%12 == 0 { + w.Writer.Write(newline) + w.c = 0 + } + + fmt.Fprintf(w.Writer, "0x%02x,", p[n]) + w.c++ + } + + n++ + + return +} diff --git a/bee.json b/bee.json index 8e3c7eb..67ea18b 100644 --- a/bee.json +++ b/bee.json @@ -6,12 +6,12 @@ "others": [] }, "bale": { - "import": "github.com/astaxie/bee/bale", + "import": "github.com/beego/beeweb/bale", "dirs": [ "views", "static", "conf" ], "ignore_ext": [ - ".go" + ".go", ".DS_Store" ] } } \ No newline at end of file