feat: implement serve mode with file watching
- Add fsnotify for file watching in serve mode - Create watcher.go for content directory monitoring - Update serve mode to generate initial output and watch for changes - Add route to serve generated HTML files from output directory - File changes trigger automatic regeneration Co-Authored-By: Claude (glm-5) <noreply@anthropic.com>
This commit is contained in:
6
go.mod
6
go.mod
@@ -7,4 +7,8 @@ require (
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require github.com/yuin/goldmark v1.7.16 // indirect
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/yuin/goldmark v1.7.16 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
)
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,7 +1,11 @@
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE=
|
||||
github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
||||
17
main.go
17
main.go
@@ -52,6 +52,21 @@ func runCLIMode() {
|
||||
func runServeMode() {
|
||||
fmt.Println("Running in Serve mode...")
|
||||
|
||||
// Generate initial output
|
||||
fmt.Println("Generating initial output...")
|
||||
if err := generateOutput(); err != nil {
|
||||
fmt.Printf("Error generating initial output: %s\n", err)
|
||||
}
|
||||
|
||||
// Start file watcher for live reload
|
||||
watcher, err := startWatcher()
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: Failed to start file watcher: %s\n", err)
|
||||
}
|
||||
if watcher != nil {
|
||||
defer watcher.Close()
|
||||
}
|
||||
|
||||
// Create a channel to receive the OS signals
|
||||
sc := make(chan os.Signal, 1)
|
||||
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM)
|
||||
@@ -68,7 +83,7 @@ func runServeMode() {
|
||||
defer shCancel()
|
||||
|
||||
// Shutdown the HTTP server
|
||||
err := ws.HTTPServer.Shutdown(shCtx)
|
||||
err = ws.HTTPServer.Shutdown(shCtx)
|
||||
if err != nil {
|
||||
fmt.Printf("Server shutdown error: %s", err)
|
||||
os.Exit(1)
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
package main
|
||||
|
||||
import "github.com/gorilla/mux"
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (s *WebServer) Routes(r *mux.Router) {
|
||||
r.HandleFunc("/version", handleVersion).Methods("GET")
|
||||
|
||||
// Serve generated HTML files from output directory
|
||||
r.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir(outputPath))))
|
||||
}
|
||||
|
||||
51
watcher.go
Normal file
51
watcher.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
// startWatcher starts watching the content directory for changes
|
||||
func startWatcher() (*fsnotify.Watcher, error) {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create watcher: %w", err)
|
||||
}
|
||||
|
||||
// Add content directory to watcher
|
||||
err = watcher.Add(contentPath)
|
||||
if err != nil {
|
||||
watcher.Close()
|
||||
return nil, fmt.Errorf("failed to watch content directory: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Watching %s for changes...\n", contentPath)
|
||||
|
||||
// Start goroutine to handle events
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
// Only process write and create events for .md files
|
||||
if event.Has(fsnotify.Write) || event.Has(fsnotify.Create) {
|
||||
fmt.Printf("File changed: %s\n", event.Name)
|
||||
// Regenerate output
|
||||
if err := generateOutput(); err != nil {
|
||||
fmt.Printf("Error regenerating: %s\n", err)
|
||||
}
|
||||
}
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
fmt.Printf("Watcher error: %s\n", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return watcher, nil
|
||||
}
|
||||
Reference in New Issue
Block a user