fix --watch

This commit is contained in:
nvms 2025-04-08 20:01:59 -04:00
parent 4041957a01
commit d9ee9739c2
5 changed files with 93 additions and 47 deletions

BIN
esr

Binary file not shown.

View File

@ -33,40 +33,25 @@ func (b *Builder) Build(buildOptions *api.BuildOptions) error {
b.BuiltCSS = []string{}
for _, file := range result.OutputFiles {
dir := filepath.Dir(file.Path)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("esr :: failed to create directory: %v", err)
}
}
if err := os.WriteFile(file.Path, file.Contents, os.ModePerm); err != nil {
return fmt.Errorf("esr :: failed to write file: %v", err)
}
if filepath.Ext(file.Path) != ".map" {
dir := filepath.Dir(file.Path)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("esr :: failed to create directory: %v", err)
}
}
if err := os.WriteFile(file.Path, file.Contents, os.ModePerm); err != nil {
return fmt.Errorf("esr :: failed to write file: %v", err)
}
// fmt.Printf("esr :: wrote: %s\n", filepath.Join(b.Config.Outdir, filepath.Base(file.Path)))
fmt.Printf("esr :: wrote: %s\n", filepath.Join(filepath.Dir(file.Path), filepath.Base(file.Path)))
// fmt.Printf("esr :: wrote: %s\n", file.Path)
if filepath.Ext(file.Path) == ".js" {
if filepath.Ext(file.Path) == ".js" || filepath.Ext(file.Path) == ".mjs" {
b.BuiltJS = append(b.BuiltJS, file.Path)
}
if filepath.Ext(file.Path) == ".css" {
b.BuiltCSS = append(b.BuiltCSS, file.Path)
}
} else {
dir := filepath.Dir(file.Path)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("esr :: failed to create directory: %v", err)
}
}
if err := os.WriteFile(file.Path, file.Contents, os.ModePerm); err != nil {
return fmt.Errorf("esr :: failed to write file: %v", err)
}
}
}

View File

@ -3,6 +3,9 @@ package esr
import (
"esr/internal/config"
"fmt"
"os"
"os/signal"
"syscall"
"github.com/evanw/esbuild/pkg/api"
)
@ -47,15 +50,57 @@ func ExecuteTask(esr *Esr, build, serve, run, watch bool) {
}
if run {
esr.Runner.Run(entryPoint)
}
if watch && !(serve || run) {
if watch {
// Special case for --run --watch: we start watching and re-run on changes
opts := ModeOptions(esr.Config, ModeRunner, entryPoint, esr.Runner.TempFilePath)
if err := esr.Builder.Build(opts); err != nil {
fmt.Println("Build error:", err)
return
}
// Enter alt screen for watch mode
EnterAltScreen()
ClearScreen()
// Run once initially
esr.Runner.Run(entryPoint)
// Then set up watching
err := esr.Builder.StartWatch(opts, func() {
ClearScreen()
esr.Runner.Run(entryPoint)
})
if err != nil {
fmt.Println("Watch error:", err)
ExitAltScreen()
return
}
// Block main thread with a signal handler to keep the process alive
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
// Ensure we exit the alternate buffer when shutting down
ExitAltScreen()
} else {
// Normal run case (no watch) - don't use alt screen
esr.Runner.Run(entryPoint)
}
} else if watch && !serve {
// Watch-only mode (not combined with serve or run)
opts := ModeOptions(esr.Config, ModeServer, entryPoint, "")
err := esr.Builder.StartWatch(opts, esr.generalCallback(run, entryPoint))
err := esr.Builder.StartWatch(opts, esr.generalCallback(false, entryPoint))
if err != nil {
fmt.Println("Watch error:", err)
return
}
// Block main thread with a signal handler to keep the process alive
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
}
}

View File

@ -40,21 +40,35 @@ func newTempFilePath(entry string) string {
func (r *Runner) Run(entryPoint string) {
opts := ModeOptions(r.Config, ModeRunner, entryPoint, r.TempFilePath)
opts.Outfile = r.TempFilePath
defer func() {
filesToCleanup := []string{r.TempFilePath}
if r.Config.Run.Sourcemap {
filesToCleanup = append(filesToCleanup, r.TempFilePath+".map")
}
for _, file := range filesToCleanup {
if err := os.Remove(file); err != nil {
if !os.IsNotExist(err) {
// Silently ignore cleanup errors
}
}
}
}()
if err := r.Builder.Build(opts); err != nil {
fmt.Println("Build error:", err)
return
}
fmt.Printf("esr :: running: \"%s %s\"\n", r.Config.Run.Runtime, r.TempFilePath)
cmd := exec.Command(r.Config.Run.Runtime, r.TempFilePath)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
if err := cmd.Start(); err != nil {
fmt.Println("Error starting process:", err)
os.Exit(1)
return
}
var wg sync.WaitGroup
@ -62,20 +76,10 @@ func (r *Runner) Run(entryPoint string) {
go func() {
defer wg.Done()
if err := cmd.Wait(); err != nil {
fmt.Printf("Process finished with error: %v\n", err)
} else {
fmt.Println("Process finished successfully")
}
cmd.Wait()
}()
wg.Wait()
// Finally, remove the temp file we created
if err := os.Remove(r.TempFilePath); err != nil {
fmt.Printf("Failed to remove temp file: %v\n", err)
}
}
func (r *Runner) Stop(cmd *exec.Cmd) error {

View File

@ -15,3 +15,15 @@ func ShowHelpMessage() {
fmt.Println(`Usage:
esr [init] [--config <path>] [--serve] [--build] [--watch] <entrypoint>`)
}
func EnterAltScreen() {
fmt.Print("\033[?1049h")
}
func ExitAltScreen() {
fmt.Print("\033[?1049l")
}
func ClearScreen() {
fmt.Print("\033[H\033[2J")
}