aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/api
diff options
context:
space:
mode:
authorJP Appel <jeanpierre.appel01@gmail.com>2024-10-08 13:11:40 -0400
committerJP Appel <jeanpierre.appel01@gmail.com>2024-10-08 13:11:40 -0400
commit3b0e5c790ff51756c1317f4af83a2f0b0e66efd9 (patch)
treeea014fd5ab6634ba948da915c0747de5d9fe8017 /api
parentcb30fbbf8a1d5680595ed3841ef75cebad433ca1 (diff)
Refactor ansi stripper to be synchronous
Diffstat (limited to 'api')
-rw-r--r--api/docker.go67
-rw-r--r--api/docker_test.go4
2 files changed, 35 insertions, 36 deletions
diff --git a/api/docker.go b/api/docker.go
index 0968a11..c79b76d 100644
--- a/api/docker.go
+++ b/api/docker.go
@@ -1,7 +1,6 @@
package api
import (
- "bufio"
"context"
"fmt"
"io"
@@ -17,37 +16,34 @@ const vttContainerId string = "foundry-foundry-1"
// Strip ansi control characters from source
//
-// The source reader is automatically closed when stripped reader is
-func StripAnsi(source io.ReadCloser) io.ReadCloser {
-
- regex := regexp.MustCompile(`\x1b[[0-9;]*m`)
- reader, writer := io.Pipe()
-
- go func() {
- bufReader := bufio.NewReader(source)
- defer source.Close()
- defer writer.Close()
-
- cleanSource:
- for {
- line, err := bufReader.ReadBytes('\n')
- switch {
- case err == io.EOF:
- if len(line) > 0 {
- cleaned := regex.ReplaceAll(line, []byte(""))
- writer.Write(cleaned)
- }
- break cleanSource
- case err != nil:
- panic(err)
- default:
- cleaned := regex.ReplaceAll(line, []byte(""))
- writer.Write(cleaned)
- }
- }
- }()
-
- return reader
+// The source reader is automatically closed when stripper reader is
+type ansiStripper struct {
+ regex regexp.Regexp
+ source io.ReadCloser
+}
+
+func NewAnsiStripper(source io.ReadCloser) *ansiStripper {
+ striper := new(ansiStripper)
+ striper.regex = *regexp.MustCompile(`\x1b[[0-9;]*m`)
+ striper.source = source
+
+ return striper
+}
+
+func (rc ansiStripper) Read(p []byte) (int, error) {
+ n, err := rc.source.Read(p)
+ if err != io.EOF && err != nil {
+ return n, err
+ }
+
+ stripped := rc.regex.ReplaceAll(p[:n], []byte(""))
+ n = copy(p, stripped)
+
+ return n, err
+}
+
+func (rc ansiStripper) Close() error {
+ return rc.source.Close()
}
func stopVtt(ctx context.Context) error {
@@ -56,6 +52,7 @@ func stopVtt(ctx context.Context) error {
Logger.ErrorContext(ctx, "Failed to get docker api client", slog.Any("err", err))
return err
}
+ defer apiClient.Close()
Logger.InfoContext(ctx, "Stopping foundry container")
err = apiClient.ContainerStop(ctx, vttContainerId, container.StopOptions{})
@@ -75,10 +72,11 @@ func vttLogs(ctx context.Context, lines uint) (io.ReadCloser, error) {
Logger.ErrorContext(ctx, "Failed to get docker api client", slog.Any("err", err))
return nil, err
}
+ defer apiClient.Close()
opts := container.LogsOptions{
ShowStdout: true,
- ShowStderr: true,
+ // ShowStderr: true,
}
if lines != 0 {
opts.Tail = fmt.Sprint(lines)
@@ -91,7 +89,7 @@ func vttLogs(ctx context.Context, lines uint) (io.ReadCloser, error) {
return nil, err
}
- return StripAnsi(r), nil
+ return r, nil
}
func vttStatus(ctx context.Context) ServerStatus {
@@ -104,6 +102,7 @@ func vttStatus(ctx context.Context) ServerStatus {
Logger.ErrorContext(ctx, "Failed to get docker api client", slog.Any("err", err))
return status
}
+ defer apiClient.Close()
json, err := apiClient.ContainerInspect(ctx, vttContainerId)
if err != nil {
diff --git a/api/docker_test.go b/api/docker_test.go
index acd92bc..7d85803 100644
--- a/api/docker_test.go
+++ b/api/docker_test.go
@@ -24,7 +24,7 @@ func (stringReadCloser) Close() error {
func testAnsiStripper(t *testing.T, input string, expected string) {
reader := newStringReadCloser(input)
- cleanReader := api.StripAnsi(reader)
+ cleanReader := api.NewAnsiStripper(reader)
defer cleanReader.Close()
buf := new(strings.Builder)
@@ -46,5 +46,5 @@ func testAnsiStripper(t *testing.T, input string, expected string) {
func TestStripAnsiColors(t *testing.T) {
testAnsiStripper(t, "a\x1b[31mbc", "abc")
- testAnsiStripper(t, "[\x1b[32minfo\x1b[39m]", "[info]")
+ testAnsiStripper(t, "[\x1b[32minfo\x1b[39m]", "[info]")
}