diff --git a/pkg/api/api_impl.go b/pkg/api/api_impl.go index f695e6430bf..ebe7df7a3d2 100644 --- a/pkg/api/api_impl.go +++ b/pkg/api/api_impl.go @@ -1106,8 +1106,11 @@ func (ctx *internalContext) Watch(options WatchOptions) error { return errors.New("Watch mode has already been enabled") } + logLevel := ctx.args.logOptions.LogLevel ctx.watcher = &watcher{ - fs: ctx.realFS, + fs: ctx.realFS, + shouldLog: logLevel == logger.LevelInfo || logLevel == logger.LevelDebug || logLevel == logger.LevelVerbose, + useColor: ctx.args.logOptions.Color, rebuild: func() fs.WatchData { return ctx.rebuild().watchData }, @@ -1117,7 +1120,7 @@ func (ctx *internalContext) Watch(options WatchOptions) error { ctx.args.options.WatchMode = true // Start the file watcher goroutine - ctx.watcher.start(ctx.args.logOptions.LogLevel, ctx.args.logOptions.Color) + ctx.watcher.start() // Do the first watch mode build on another goroutine go func() { diff --git a/pkg/api/watcher.go b/pkg/api/watcher.go index d140df07301..efe62776dba 100644 --- a/pkg/api/watcher.go +++ b/pkg/api/watcher.go @@ -56,12 +56,22 @@ type watcher struct { mutex sync.Mutex itemsPerIteration int shouldStop int32 + shouldLog bool + useColor logger.UseColor stopWaitGroup sync.WaitGroup } func (w *watcher) setWatchData(data fs.WatchData) { defer w.mutex.Unlock() w.mutex.Lock() + + // Print something for the end of the first build + if w.shouldLog && w.data.Paths == nil { + logger.PrintTextWithColor(os.Stderr, w.useColor, func(colors logger.Colors) string { + return fmt.Sprintf("%s[watch] build finished, watching for changes...%s\n", colors.Dim, colors.Reset) + }) + } + w.data = data w.itemsToScan = w.itemsToScan[:0] // Reuse memory @@ -76,30 +86,22 @@ func (w *watcher) setWatchData(data fs.WatchData) { w.recentItems = w.recentItems[:end] } -func (w *watcher) start(logLevel logger.LogLevel, useColor logger.UseColor) { +func (w *watcher) start() { w.stopWaitGroup.Add(1) go func() { - shouldLog := logLevel == logger.LevelInfo || logLevel == logger.LevelDebug || logLevel == logger.LevelVerbose - // Note: Do not change these log messages without a breaking version change. // People want to run regexes over esbuild's stderr stream to look for these // messages instead of using esbuild's API. - if shouldLog { - logger.PrintTextWithColor(os.Stderr, useColor, func(colors logger.Colors) string { - return fmt.Sprintf("%s[watch] build finished, watching for changes...%s\n", colors.Dim, colors.Reset) - }) - } - for atomic.LoadInt32(&w.shouldStop) == 0 { // Sleep for the watch interval time.Sleep(watchIntervalSleep) // Rebuild if we're dirty if absPath := w.tryToFindDirtyPath(); absPath != "" { - if shouldLog { - logger.PrintTextWithColor(os.Stderr, useColor, func(colors logger.Colors) string { + if w.shouldLog { + logger.PrintTextWithColor(os.Stderr, w.useColor, func(colors logger.Colors) string { prettyPath := resolver.PrettyPath(w.fs, logger.Path{Text: absPath, Namespace: "file"}) return fmt.Sprintf("%s[watch] build started (change: %q)%s\n", colors.Dim, prettyPath, colors.Reset) }) @@ -108,8 +110,8 @@ func (w *watcher) start(logLevel logger.LogLevel, useColor logger.UseColor) { // Run the build w.setWatchData(w.rebuild()) - if shouldLog { - logger.PrintTextWithColor(os.Stderr, useColor, func(colors logger.Colors) string { + if w.shouldLog { + logger.PrintTextWithColor(os.Stderr, w.useColor, func(colors logger.Colors) string { return fmt.Sprintf("%s[watch] build finished%s\n", colors.Dim, colors.Reset) }) }