From 9d12606e1dbbd818af66531fa4da3fb98b8d35d2 Mon Sep 17 00:00:00 2001 From: abdealijaroli Date: Thu, 8 Feb 2024 12:12:11 +0530 Subject: [PATCH] Add live server and file watcher functionality --- cmd/govert/main.go | 109 +++++++++++++++++++++++++++++++++------------ go.mod | 2 + go.sum | 4 ++ 3 files changed, 86 insertions(+), 29 deletions(-) diff --git a/cmd/govert/main.go b/cmd/govert/main.go index c7b73f2..6d64577 100644 --- a/cmd/govert/main.go +++ b/cmd/govert/main.go @@ -2,67 +2,118 @@ package main import ( "log" + "net/http" "os" "github.com/abdealijaroli/govert/pkg/converter" + "github.com/fsnotify/fsnotify" "github.com/spf13/cobra" ) var directoryFlag bool +var liveFlag bool var rootCmd = &cobra.Command{ Use: "govert", Short: "A CLI for converting Markdown to HTML", Long: `A Command Line Interface application for converting Markdown to HTML`, Run: func(cmd *cobra.Command, args []string) { - var inputFile, outputFile string - - if len(args) < 1 { - log.Fatalf("Not enough arguments: expected input and output file paths") - } else if len(args) == 1 { - inputFile = args[0] - outputFile = "output.html" + if liveFlag { + go startServer() + go watchFiles(args[0]) + select {} } else { - inputFile = args[0] - outputFile = args[1] - } + var inputFile, outputFile string + + if len(args) < 1 { + log.Fatalf("Not enough arguments: expected input and output file paths") + } else if len(args) == 1 { + inputFile = args[0] + outputFile = "output.html" + } else { + inputFile = args[0] + outputFile = args[1] + } - if directoryFlag { - var inputDirectory, outputDirectory string + if directoryFlag { + var inputDirectory, outputDirectory string - if len(args) == 1 { - inputDirectory = args[0] - outputDirectory = "outputDir" + if len(args) == 1 { + inputDirectory = args[0] + outputDirectory = "outputDir" - if _, err := os.Stat(outputDirectory); os.IsNotExist(err) { - if err := os.Mkdir(outputDirectory, 0755); err != nil { - log.Fatalf("Error creating output directory: %v", err) + if _, err := os.Stat(outputDirectory); os.IsNotExist(err) { + if err := os.Mkdir(outputDirectory, 0755); err != nil { + log.Fatalf("Error creating output directory: %v", err) + } } + } else { + inputDirectory = args[0] + outputDirectory = args[1] } - } else { - inputDirectory = args[0] - outputDirectory = args[1] + + err := converter.ConvertMarkdownToHTMLDirectory(inputDirectory, outputDirectory) + if err != nil { + log.Fatalf("Error converting Markdown to HTML: %v", err) + } + log.Printf("Directory %s converted to %s\n", inputDirectory, outputDirectory) + return } - err := converter.ConvertMarkdownToHTMLDirectory(inputDirectory, outputDirectory) + err := converter.ConvertMarkdownToHTML(inputFile, outputFile) if err != nil { log.Fatalf("Error converting Markdown to HTML: %v", err) } - log.Printf("Directory %s converted to %s\n", inputDirectory, outputDirectory) - return + + log.Printf("File %s converted to %s\n", inputFile, outputFile) } + }, +} - err := converter.ConvertMarkdownToHTML(inputFile, outputFile) - if err != nil { - log.Fatalf("Error converting Markdown to HTML: %v", err) +func startServer() { + http.Handle("/", http.FileServer(http.Dir("test"))) + log.Println("Starting server on :8080") + log.Fatal(http.ListenAndServe(":8080", nil)) +} + +func watchFiles(inputFile string) { + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + done := make(chan bool) + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + if event.Has(event.Op) { + log.Println("Modified file:", event.Name) + converter.ConvertMarkdownToHTML(event.Name, "test/output.html") + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("Error:", err) + } } + }() - log.Printf("File %s converted to %s\n", inputFile, outputFile) - }, + err = watcher.Add(inputFile) + if err != nil { + log.Fatal(err) + } + <-done } func init() { rootCmd.Flags().BoolVarP(&directoryFlag, "directory", "d", false, "Convert a directory of Markdown files to HTML") + rootCmd.Flags().BoolVarP(&liveFlag, "live", "l", false, "Start a live server and watch for changes") } func Execute() { diff --git a/go.mod b/go.mod index 80d4a80..9fb164e 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/abdealijaroli/govert go 1.21.6 require ( + github.com/fsnotify/fsnotify v1.7.0 github.com/russross/blackfriday/v2 v2.1.0 github.com/spf13/cobra v1.8.0 ) @@ -10,4 +11,5 @@ require ( require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/sys v0.4.0 // indirect ) diff --git a/go.sum b/go.sum index 1a1902d..ce8a0ec 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -7,5 +9,7 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=