Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions view/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/base64"
"fmt"
"io"
"log"
"mime/quotedprintable"
"os"
"regexp"
Expand Down Expand Up @@ -268,22 +269,41 @@ func imageProtocolSupported() bool {
weztermSupported() || waystSupported() || warpSupported() || konsoleSupported()
}

type debugImageProtocolLogFile interface {
WriteString(string) (int, error)
Close() error
}

var (
debugImageProtocolOpenLogFile = func(path string) (debugImageProtocolLogFile, error) {
Comment thread
FromSi marked this conversation as resolved.
return os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
}
debugImageProtocolLogErrorf = log.Printf
)

func debugImageProtocol(format string, args ...interface{}) {
if os.Getenv("DEBUG_IMAGE_PROTOCOL") == "" && os.Getenv("DEBUG_KITTY_IMAGES") == "" {
return
}
msg := fmt.Sprintf("[img-protocol] "+format+"\n", args...)
fmt.Print(msg)
if path := os.Getenv("DEBUG_IMAGE_PROTOCOL_LOG"); path != "" {
if f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
_, _ = f.WriteString(msg)
_ = f.Close()
}
writeDebugImageProtocolLog(path, msg)
} else if path := os.Getenv("DEBUG_KITTY_LOG"); path != "" {
if f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
_, _ = f.WriteString(msg)
_ = f.Close()
}
writeDebugImageProtocolLog(path, msg)
}
}

func writeDebugImageProtocolLog(path, msg string) {
f, err := debugImageProtocolOpenLogFile(path)
if err != nil {
return
Comment thread
FromSi marked this conversation as resolved.
}
if _, err := f.WriteString(msg); err != nil {
debugImageProtocolLogErrorf("failed to write debug image protocol log %s: %v", path, err)
}
if err := f.Close(); err != nil {
debugImageProtocolLogErrorf("failed to close debug image protocol log %s: %v", path, err)
}
}

Expand Down
81 changes: 81 additions & 0 deletions view/html_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package view

import (
"errors"
"fmt"
"os"
"regexp"
Expand Down Expand Up @@ -32,6 +33,86 @@ func clearAllTerminalEnv() {
os.Setenv("TERM_PROGRAM", "basic")
}

type failingDebugImageProtocolLogFile struct {
writeErr error
closeErr error
}

func (f failingDebugImageProtocolLogFile) WriteString(s string) (int, error) {
if f.writeErr != nil {
return 0, f.writeErr
}
return len(s), nil
}

func (f failingDebugImageProtocolLogFile) Close() error {
return f.closeErr
}

func TestDebugImageProtocolReportsLogWriteError(t *testing.T) {
originalOpenLogFile := debugImageProtocolOpenLogFile
originalLogErrorf := debugImageProtocolLogErrorf
defer func() {
debugImageProtocolOpenLogFile = originalOpenLogFile
debugImageProtocolLogErrorf = originalLogErrorf
}()

writeErr := errors.New("write failed")
debugImageProtocolOpenLogFile = func(string) (debugImageProtocolLogFile, error) {
return failingDebugImageProtocolLogFile{writeErr: writeErr}, nil
}

var logged []string
debugImageProtocolLogErrorf = func(format string, args ...interface{}) {
logged = append(logged, fmt.Sprintf(format, args...))
}

t.Setenv("DEBUG_IMAGE_PROTOCOL", "1")
t.Setenv("DEBUG_IMAGE_PROTOCOL_LOG", "/tmp/matcha-debug.log")

debugImageProtocol("hello")

joined := strings.Join(logged, "\n")
if !strings.Contains(joined, "failed to write debug image protocol log") {
t.Fatalf("expected write error to be logged, got %q", joined)
}
if !strings.Contains(joined, writeErr.Error()) {
t.Fatalf("expected logged error to contain %q, got %q", writeErr, joined)
}
}

func TestDebugImageProtocolReportsLogCloseError(t *testing.T) {
originalOpenLogFile := debugImageProtocolOpenLogFile
originalLogErrorf := debugImageProtocolLogErrorf
defer func() {
debugImageProtocolOpenLogFile = originalOpenLogFile
debugImageProtocolLogErrorf = originalLogErrorf
}()

closeErr := errors.New("close failed")
debugImageProtocolOpenLogFile = func(string) (debugImageProtocolLogFile, error) {
return failingDebugImageProtocolLogFile{closeErr: closeErr}, nil
}

var logged []string
debugImageProtocolLogErrorf = func(format string, args ...interface{}) {
logged = append(logged, fmt.Sprintf(format, args...))
}

t.Setenv("DEBUG_IMAGE_PROTOCOL", "1")
t.Setenv("DEBUG_KITTY_LOG", "/tmp/matcha-kitty.log")

debugImageProtocol("hello")

joined := strings.Join(logged, "\n")
if !strings.Contains(joined, "failed to close debug image protocol log") {
t.Fatalf("expected close error to be logged, got %q", joined)
}
if !strings.Contains(joined, closeErr.Error()) {
t.Fatalf("expected logged error to contain %q, got %q", closeErr, joined)
}
}

func TestDecodeQuotedPrintable(t *testing.T) {
testCases := []struct {
name string
Expand Down
Loading