github.com/ngocphuongnb/tetua@v0.0.7-alpha/packages/prebuild/prebuild.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  	"os/exec"
    10  	"path"
    11  	"path/filepath"
    12  	"strings"
    13  
    14  	"github.com/ngocphuongnb/tetua/app/config"
    15  	jadecmd "github.com/ngocphuongnb/tetua/packages/jade"
    16  )
    17  
    18  type BuildCache struct {
    19  	ViewMTime map[string]int64
    20  	EntMTime  int64
    21  }
    22  
    23  func getDirLastMTime(root string) int64 {
    24  	var lastModTime int64
    25  	if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
    26  		if !info.IsDir() {
    27  			if info.ModTime().UnixMicro() > lastModTime {
    28  				lastModTime = info.ModTime().UnixMicro()
    29  			}
    30  		}
    31  		return nil
    32  	}); err != nil {
    33  		panic(err)
    34  	}
    35  	return lastModTime
    36  }
    37  
    38  func getBuildCache(buildCacheFile string) BuildCache {
    39  	buildCache := BuildCache{}
    40  	buildCacheBytes, err := ioutil.ReadFile(buildCacheFile)
    41  
    42  	if err == nil {
    43  		if err = json.Unmarshal(buildCacheBytes, &buildCache); err != nil {
    44  			log.Fatal(err)
    45  		}
    46  	}
    47  
    48  	return buildCache
    49  }
    50  
    51  func BuildViewAssets(viewsDir, viewsOutputDir, buildCacheFile string, force bool) error {
    52  	buildCache := getBuildCache(buildCacheFile)
    53  	cachedViewMTimes := buildCache.ViewMTime
    54  	changedPageFiles := make([]string, 0)
    55  	changedPartialsFiles := make([]string, 0)
    56  	changedFiles := make([]string, 0)
    57  
    58  	if !force {
    59  		if err := filepath.Walk(viewsDir, func(viewFilePath string, info os.FileInfo, err error) error {
    60  			if !info.IsDir() {
    61  				isPageFile := strings.HasPrefix(viewFilePath, path.Join(viewsDir, "pages"))
    62  				fileMTime := info.ModTime().UnixMicro()
    63  
    64  				if viewFileLastMTime, ok := cachedViewMTimes[viewFilePath]; ok && viewFileLastMTime >= fileMTime {
    65  
    66  				} else {
    67  					if isPageFile {
    68  						changedPageFiles = append(changedPageFiles, viewFilePath)
    69  					} else {
    70  						changedPartialsFiles = append(changedPartialsFiles, viewFilePath)
    71  					}
    72  					cachedViewMTimes[viewFilePath] = fileMTime
    73  				}
    74  			}
    75  			return nil
    76  		}); err != nil {
    77  			return err
    78  		}
    79  	}
    80  
    81  	// If has partials change, rebuild all
    82  	if force || len(changedPartialsFiles) > 0 {
    83  		fmt.Println("> Has partials changed")
    84  		changedFiles = append(changedFiles, viewsDir+"/pages")
    85  	} else {
    86  		// If has page change, rebuild only changed page
    87  		if len(changedPageFiles) > 0 {
    88  			fmt.Println("> Has pages changed")
    89  			changedFiles = changedPageFiles
    90  		}
    91  	}
    92  
    93  	if len(changedFiles) > 0 {
    94  		jadecmd.CompilePaths(changedFiles, jadecmd.CompileConfig{
    95  			Writer:  true,
    96  			PkgName: "views",
    97  			OutDir:  viewsOutputDir,
    98  		})
    99  
   100  		buildCache.ViewMTime = cachedViewMTimes
   101  		b, err := json.Marshal(buildCache)
   102  		if err != nil {
   103  			return err
   104  		}
   105  
   106  		if err = os.WriteFile(buildCacheFile, b, 0644); err != nil {
   107  			return err
   108  		}
   109  	} else {
   110  		fmt.Println("> No views changed")
   111  	}
   112  
   113  	return nil
   114  }
   115  
   116  func GenerateEnt(buildCacheFile string, force bool) error {
   117  	lastEntSchemaMTime := getDirLastMTime("./packages/entrepository/ent/schema")
   118  	buildCache := getBuildCache(buildCacheFile)
   119  
   120  	if force || lastEntSchemaMTime > buildCache.EntMTime {
   121  		fmt.Println("> Has ent schema changed")
   122  		buildCache.EntMTime = lastEntSchemaMTime
   123  		cmd := exec.Command("go", "generate", "./packages/entrepository/ent", "-vvvv")
   124  		cmd.Stdout = os.Stdout
   125  		cmd.Stderr = os.Stderr
   126  		if err := cmd.Run(); err != nil {
   127  			return err
   128  		}
   129  
   130  		b, err := json.Marshal(buildCache)
   131  		if err != nil {
   132  			return err
   133  		}
   134  
   135  		if err = os.WriteFile(buildCacheFile, b, 0644); err != nil {
   136  			return err
   137  		}
   138  		return nil
   139  	}
   140  
   141  	fmt.Println("> No ent schema changed")
   142  	return nil
   143  }
   144  
   145  func main() {
   146  	force := false
   147  	if len(os.Args) > 1 {
   148  		force = os.Args[1] == "--force"
   149  	}
   150  
   151  	if err := BuildViewAssets(
   152  		path.Join("./app/themes", config.APP_THEME, "views"),
   153  		"./views",
   154  		"./private/tmp/cache.json",
   155  		force,
   156  	); err != nil {
   157  		panic(err)
   158  	}
   159  	if err := GenerateEnt("./private/tmp/cache.json", force); err != nil {
   160  		panic(err)
   161  	}
   162  }