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
|
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 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
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 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE=
|
||||||
github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
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 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
|||||||
17
main.go
17
main.go
@@ -52,6 +52,21 @@ func runCLIMode() {
|
|||||||
func runServeMode() {
|
func runServeMode() {
|
||||||
fmt.Println("Running in Serve mode...")
|
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
|
// Create a channel to receive the OS signals
|
||||||
sc := make(chan os.Signal, 1)
|
sc := make(chan os.Signal, 1)
|
||||||
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM)
|
||||||
@@ -68,7 +83,7 @@ func runServeMode() {
|
|||||||
defer shCancel()
|
defer shCancel()
|
||||||
|
|
||||||
// Shutdown the HTTP server
|
// Shutdown the HTTP server
|
||||||
err := ws.HTTPServer.Shutdown(shCtx)
|
err = ws.HTTPServer.Shutdown(shCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Server shutdown error: %s", err)
|
fmt.Printf("Server shutdown error: %s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/gorilla/mux"
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
func (s *WebServer) Routes(r *mux.Router) {
|
func (s *WebServer) Routes(r *mux.Router) {
|
||||||
r.HandleFunc("/version", handleVersion).Methods("GET")
|
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