diff --git a/main.go b/main.go index 8b8eab1..4a8d2da 100755 --- a/main.go +++ b/main.go @@ -43,6 +43,7 @@ toc: {{.Toc}} ) var globalConfig *GlobalConfig +var themeConfig *ThemeConfig var rootPath string func main() { @@ -187,8 +188,8 @@ func ParseGlobalConfigByCli(c *cli.Context, develop bool) { func ParseGlobalConfigWrap(root string, develop bool) { rootPath = root - globalConfig = ParseGlobalConfig(filepath.Join(rootPath, "config.yml"), develop) - if globalConfig == nil { + globalConfig, themeConfig = ParseGlobalConfig(filepath.Join(rootPath, "config.yml"), develop) + if globalConfig == nil || themeConfig == nil { return } } diff --git a/parse.go b/parse.go index f72032b..d4a2fba 100755 --- a/parse.go +++ b/parse.go @@ -148,12 +148,12 @@ func ReplaceRootFlag(content string) string { return strings.Replace(content, "-/", globalConfig.Site.Root+"/", -1) } -func ParseGlobalConfig(configPath string, develop bool) *GlobalConfig { +func ParseGlobalConfig(configPath string, develop bool) (*GlobalConfig, *ThemeConfig) { var config *GlobalConfig // Parse Global Config data, err := os.ReadFile(configPath) if err != nil { - return nil + return nil, nil } if err = yaml.Unmarshal(data, &config); err != nil { Fatal(err.Error()) @@ -181,7 +181,7 @@ func ParseGlobalConfig(configPath string, develop bool) *GlobalConfig { for item, langItem := range themeConfig.Lang { config.I18n[item] = langItem[config.Site.Lang] } - return config + return config, themeConfig } func ParseThemeConfig(configPath string) *ThemeConfig { diff --git a/serve.go b/serve.go index 6467487..ef130d8 100644 --- a/serve.go +++ b/serve.go @@ -3,6 +3,7 @@ package main import ( "os" "path/filepath" + "reflect" "github.com/InkProject/ink.go" "github.com/facebookgo/symwalk" @@ -13,12 +14,61 @@ import ( var watcher *fsnotify.Watcher var conn *websocket.Conn +func buildWatchList() (files []string, dirs []string) { + dirs = []string{ + filepath.Join(rootPath, "source"), + } + files = []string{ + filepath.Join(rootPath, "config.yml"), + filepath.Join(themePath), + } + + // Add files and directories defined in theme's config.yml to watcher + for _, themeCopiedPath := range themeConfig.Copy { + if themeCopiedPath != "" { + fullPath := filepath.Join(themePath, themeCopiedPath) + s, err := os.Stat(fullPath) + if s == nil || err != nil { + continue + } + + if s.IsDir() { + dirs = append(dirs, fullPath) + } else { + files = append(files, fullPath) + } + } + } + return files, dirs +} + +// Add files and dirs to watcher +func configureWatcher(watcher *fsnotify.Watcher, files []string, dirs []string) error { + for _, source := range dirs { + symwalk.Walk(source, func(path string, f os.FileInfo, err error) error { + if f != nil && f.IsDir() { + if err := watcher.Add(path); err != nil { + Warn(err.Error()) + } + } + return nil + }) + } + for _, source := range files { + if err := watcher.Add(source); err != nil { + Warn(err.Error()) + } + } + return nil +} + func Watch() { // Listen watched file change event if watcher != nil { watcher.Close() } watcher, _ = fsnotify.NewWatcher() + files, dirs := buildWatchList() go func() { for { select { @@ -27,6 +77,15 @@ func Watch() { // Handle when file change Log(event.Name) ParseGlobalConfigWrap(rootPath, true) + + newFiles, newDirs := buildWatchList() + // If file list changed, reconfigure watcher + if !reflect.DeepEqual(files, newFiles) || !reflect.DeepEqual(dirs, newDirs) { + configureWatcher(watcher, newFiles, newDirs) + files = newFiles + dirs = newDirs + } + Build() if conn != nil { if err := conn.WriteMessage(websocket.TextMessage, []byte("change")); err != nil { @@ -39,29 +98,7 @@ func Watch() { } } }() - var dirs = []string{ - filepath.Join(rootPath, "source"), - filepath.Join(themePath, "bundle"), - } - var files = []string{ - filepath.Join(rootPath, "config.yml"), - filepath.Join(themePath), - } - for _, source := range dirs { - symwalk.Walk(source, func(path string, f os.FileInfo, err error) error { - if f.IsDir() { - if err := watcher.Add(path); err != nil { - Warn(err.Error()) - } - } - return nil - }) - } - for _, source := range files { - if err := watcher.Add(source); err != nil { - Warn(err.Error()) - } - } + configureWatcher(watcher, files, dirs) } func Websocket(ctx *ink.Context) {