Initial commit
This commit is contained in:
119
compile.go
Normal file
119
compile.go
Normal file
@ -0,0 +1,119 @@
|
||||
package precompiler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/tdewolff/minify"
|
||||
"github.com/tdewolff/minify/css"
|
||||
"github.com/tdewolff/minify/js"
|
||||
)
|
||||
|
||||
// FileType represents a supported file extension (without the .)
|
||||
type FileType string
|
||||
|
||||
// supported file types
|
||||
const (
|
||||
CSS FileType = "css"
|
||||
JS FileType = "js"
|
||||
)
|
||||
|
||||
func initMinify() *minify.M {
|
||||
minifier := minify.New()
|
||||
minifier.AddFunc("text/css", css.Minify)
|
||||
minifier.AddFunc("text/js", js.Minify)
|
||||
return minifier
|
||||
}
|
||||
|
||||
func getBytes(config Config, minifier *minify.M) (map[FileType]*bytes.Buffer, error) {
|
||||
buf := make(map[FileType]*bytes.Buffer)
|
||||
|
||||
for _, file := range config.Files {
|
||||
if file, err := os.Open(file); err == nil {
|
||||
ext := FileType(filepath.Ext(file.Name())[1:])
|
||||
if !supportedFileType(ext) {
|
||||
fmt.Println("Unsupported file type:", file.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
if buf[ext] == nil {
|
||||
buf[ext] = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
if config.Minify {
|
||||
if err = minifier.Minify("text/"+string(ext), buf[ext], file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if _, err = buf[ext].ReadFrom(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// CompileResult holds the results of compilation
|
||||
type CompileResult struct {
|
||||
Bytes []byte
|
||||
Hash string
|
||||
OutputPath string
|
||||
}
|
||||
|
||||
func finalize(config Config, buf map[FileType]*bytes.Buffer) (map[FileType]*CompileResult, error) {
|
||||
ret := make(map[FileType]*CompileResult, len(buf))
|
||||
|
||||
for key, b := range buf {
|
||||
if b.Len() > 0 {
|
||||
bytes := b.Bytes()
|
||||
hash := sha256.Sum256(bytes)
|
||||
ret[key] = &CompileResult{
|
||||
Bytes: bytes,
|
||||
Hash: hex.EncodeToString(hash[:]),
|
||||
}
|
||||
|
||||
if len(config.OutputDir) > 0 {
|
||||
ext := "." + string(key)
|
||||
if config.Minify {
|
||||
ext = ".min" + ext
|
||||
}
|
||||
dir := filepath.Join(config.OutputDir, string(key))
|
||||
os.MkdirAll(dir, os.ModeDir)
|
||||
destFile := filepath.Join(dir, "app-"+ret[key].Hash+ext)
|
||||
ret[key].OutputPath = destFile
|
||||
ioutil.WriteFile(destFile, bytes, 0644)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Compile compiles files indicated by the config into a single file per type
|
||||
func Compile(config Config) (map[FileType]*CompileResult, error) {
|
||||
var buf map[FileType]*bytes.Buffer
|
||||
var err error
|
||||
if buf, err = getBytes(config, initMinify()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return finalize(config, buf)
|
||||
}
|
||||
|
||||
func supportedFileType(t FileType) bool {
|
||||
switch t {
|
||||
case CSS, JS:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
8
config.go
Normal file
8
config.go
Normal file
@ -0,0 +1,8 @@
|
||||
package precompiler
|
||||
|
||||
// Config holds information on how to run the compiler
|
||||
type Config struct {
|
||||
Files []string
|
||||
Minify bool
|
||||
OutputDir string
|
||||
}
|
23
main.go
Normal file
23
main.go
Normal file
@ -0,0 +1,23 @@
|
||||
package precompiler
|
||||
|
||||
func main() {
|
||||
Compile(Config{
|
||||
Files: []string{
|
||||
"assets/css/bootstrap.min.default.css",
|
||||
"assets/css/font-awesome.min.css",
|
||||
"assets/css/tempusdominus-bootstrap-4.min.css",
|
||||
"assets/css/roboto.css",
|
||||
"assets/css/application.css",
|
||||
"assets/js/jquery.min.js",
|
||||
"assets/js/popper.min.js",
|
||||
"assets/js/bootstrap.min.js",
|
||||
"assets/js/linkify.min.js",
|
||||
"assets/js/linkify-jquery.min.js",
|
||||
"assets/js/moment.min.js",
|
||||
"assets/js/tempusdominus-bootstrap-4.min.js",
|
||||
"assets/js/application.js",
|
||||
},
|
||||
Minify: true,
|
||||
OutputDir: "assets/",
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user