summaryrefslogtreecommitdiff
path: root/cmd/home
diff options
context:
space:
mode:
authora73x <[email protected]>2024-12-22 12:12:50 +0000
committera73x <[email protected]>2024-12-22 12:12:50 +0000
commitf1cc5903f84fe41c1e9566768d53d95f6be20236 (patch)
treee642dd7dd19df924aa0345fffc2b89f28d6186a0 /cmd/home
parent6beea1d4127d2d51bfdc75162423407c198d19da (diff)
hack in some hotreloading
Diffstat (limited to 'cmd/home')
-rw-r--r--cmd/home/main.go196
1 files changed, 181 insertions, 15 deletions
diff --git a/cmd/home/main.go b/cmd/home/main.go
index 3f04b39..6854299 100644
--- a/cmd/home/main.go
+++ b/cmd/home/main.go
@@ -1,32 +1,198 @@
package main
import (
+ "errors"
+ "fmt"
+ "log"
+ "net/http"
"os"
- "os/signal"
- "syscall"
+ "path"
+ "path/filepath"
+ "strings"
+ "time"
- "git.sr.ht/~a73x/home/web"
+ "git.sr.ht/~a73x/home/pages"
+ "github.com/fsnotify/fsnotify"
"go.uber.org/zap"
)
-func main() {
- logger, _ := zap.NewProduction()
- server, err := web.New(logger)
+func Build(directory string) error {
+ pages, err := pages.Collect(directory)
+ if err != nil {
+ return err
+ }
+
+ var errs []error
+ for _, page := range pages {
+ fmt.Println("building", page.Path)
+ err = writeFile(path.Join("public", page.Path), []byte(page.Content))
+ if err != nil {
+ errs = append(errs, err)
+ }
+ }
+
+ if errs != nil {
+ return errors.Join(errs...)
+ }
+
+ return nil
+}
+
+func Serve() error {
+ logger, err := zap.NewProduction()
if err != nil {
- logger.Fatal("failed to start webserver", zap.Error(err))
+ return err
+ }
+
+ loggingMiddleware := func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ start := time.Now()
+ next.ServeHTTP(w, r)
+ logger.Info("request received",
+ zap.String("url", r.URL.Path),
+ zap.String("method", r.Method),
+ zap.Duration("duration", time.Since(start)),
+ zap.String("user-agent", r.UserAgent()),
+ )
+ })
+ }
+
+ mux := http.NewServeMux()
+
+ mux.HandleFunc("GET /", serveFile)
+
+ server := http.Server{
+ Addr: ":8080",
+ Handler: loggingMiddleware(mux),
+ }
+
+ return server.ListenAndServe()
+}
+
+func serveFile(w http.ResponseWriter, r *http.Request) {
+ fsPath := strings.TrimRight(r.URL.Path, "/")
+
+ if fsPath == "" {
+ fsPath = "index"
+ }
+
+ if ext := filepath.Ext(fsPath); ext == "" {
+ fsPath += ".html"
}
- done := make(chan os.Signal, 0)
- signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
- logger.Info("Starting web server")
+ http.ServeFile(w, r, path.Join("public", fsPath))
+}
+
+func watchDir(watchDir string) error {
+ // Directory to watch
+
+ // Ensure the directory exists
+ if _, err := os.Stat(watchDir); os.IsNotExist(err) {
+ return err
+ }
+ // Create a new watcher
+ watcher, err := fsnotify.NewWatcher()
+ if err != nil {
+ return err
+ }
+
+ // Start a goroutine to process events
go func() {
- if err := server.ListenAndServe(); err != nil {
- logger.Error("fail running web server", zap.Error(err))
+ defer watcher.Close()
+
+ for {
+ select {
+ case event, ok := <-watcher.Events:
+ if !ok {
+ return
+ }
+ log.Printf("Event: %s", event)
+
+ // Trigger a command when a change is detected
+ if event.Op&fsnotify.Write == fsnotify.Write ||
+ event.Op&fsnotify.Create == fsnotify.Create ||
+ event.Op&fsnotify.Remove == fsnotify.Remove {
+ err := Build(watchDir)
+ if err != nil {
+ fmt.Println(err)
+ } else {
+ fmt.Println("built")
+ }
+
+ }
+
+ case err, ok := <-watcher.Errors:
+ if !ok {
+ return
+ }
+ log.Printf("Error: %v", err)
+ }
}
- done <- nil
}()
- <-done
- logger.Info("Stopping web server")
+ // Add the directory to the watcher
+ err = filepath.Walk(watchDir, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if info.IsDir() {
+ log.Printf("Watching directory: %s", path)
+ return watcher.Add(path)
+ }
+ return nil
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+func Run() error {
+ contentDir := "content"
+ actualPath, err := filepath.EvalSymlinks(contentDir)
+ if err != nil {
+ return err
+ }
+
+ if err := Build(actualPath); err != nil {
+ return err
+ }
+
+ // watcher
+ if err := watchDir(actualPath); err != nil {
+ return err
+ }
+
+ if err := Serve(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func writeFile(name string, contents []byte) error {
+ folders := path.Dir(name)
+ _, err := os.Stat(folders)
+ if os.IsNotExist(err) {
+ if err := os.MkdirAll(folders, 0744); err != nil {
+ return fmt.Errorf("failed to mkdir %s\n%w", folders, err)
+ }
+ } else if err != nil {
+ return fmt.Errorf("failed to stat folder %s\n%w", folders, err)
+ }
+
+ err = os.WriteFile(name, contents, 0666)
+ if err != nil {
+ return fmt.Errorf("failed to write file %s\n%w", name, err)
+ }
+
+ return nil
+}
+
+func main() {
+ if err := Run(); err != nil {
+ log.Panic(err)
+ }
}