mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
cmd/loop: avoid escaped session text
Disable JSON HTML escaping for recorded session files and for the nested session payloads rewritten by bless mode. This keeps CLI text such as "> 1 sat/vByte" readable instead of turning it into "\u003e". Keep the metadata field order aligned with existing fixtures so a bless pass does not rewrite unrelated sessions just because the encoder changed.
This commit is contained in:
parent
72a38c535b
commit
8d5cc2168a
2 changed files with 24 additions and 7 deletions
|
|
@ -85,6 +85,7 @@ func writeSessionFilePath(path string, fixture sessionFile) error {
|
|||
defer file.Close()
|
||||
|
||||
encoder := json.NewEncoder(file)
|
||||
encoder.SetEscapeHTML(false)
|
||||
encoder.SetIndent("", " ")
|
||||
|
||||
return encoder.Encode(fixture)
|
||||
|
|
@ -152,7 +153,7 @@ func rewriteSessionFixture(fixture sessionFile,
|
|||
func rewriteExitEventRunError(events []sessionEvent, runError *string,
|
||||
changed bool) ([]sessionEvent, bool, error) {
|
||||
|
||||
data, err := json.Marshal(exitPayload{
|
||||
data, err := marshalSessionJSON(exitPayload{
|
||||
RunError: cloneOptionalString(runError),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -338,7 +339,7 @@ func buildReplacementTextEvents(events []sessionEvent, indices []int,
|
|||
|
||||
replacements := make([]sessionEvent, 0, len(chunks))
|
||||
for i, chunk := range chunks {
|
||||
data, err := json.Marshal(newTextPayload(chunk))
|
||||
data, err := marshalSessionJSON(newTextPayload(chunk))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -571,7 +572,7 @@ func TestRewriteSessionFixtureSkipsNormalizedTimestampNoise(t *testing.T) {
|
|||
func textEvent(t *testing.T, timeMS int64, kind, text string) sessionEvent {
|
||||
t.Helper()
|
||||
|
||||
data, err := json.Marshal(newTextPayload(text))
|
||||
data, err := marshalSessionJSON(newTextPayload(text))
|
||||
require.NoError(t, err)
|
||||
|
||||
return sessionEvent{
|
||||
|
|
@ -585,7 +586,7 @@ func textEvent(t *testing.T, timeMS int64, kind, text string) sessionEvent {
|
|||
func exitEvent(t *testing.T, timeMS int64, runError *string) sessionEvent {
|
||||
t.Helper()
|
||||
|
||||
data, err := json.Marshal(exitPayload{
|
||||
data, err := marshalSessionJSON(exitPayload{
|
||||
RunError: cloneOptionalString(runError),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
|
@ -48,6 +49,20 @@ var grpcMarshalOptions = protojson.MarshalOptions{
|
|||
EmitUnpopulated: true,
|
||||
}
|
||||
|
||||
// marshalSessionJSON encodes nested session payloads without HTML escaping so
|
||||
// recorded fixture strings stay byte-for-byte close to the CLI text.
|
||||
func marshalSessionJSON(value any) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
encoder := json.NewEncoder(&buf)
|
||||
encoder.SetEscapeHTML(false)
|
||||
if err := encoder.Encode(value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bytes.TrimSuffix(buf.Bytes(), []byte("\n")), nil
|
||||
}
|
||||
|
||||
// sessionRecorder captures CLI IO and gRPC traffic for replay.
|
||||
type sessionRecorder struct {
|
||||
mu sync.Mutex
|
||||
|
|
@ -80,9 +95,9 @@ type sessionMetadata struct {
|
|||
Args []string `json:"args"`
|
||||
Env map[string]string `json:"env"`
|
||||
Version string `json:"version"`
|
||||
ClockStartUnix int64 `json:"clock_start_unix"`
|
||||
RunError *string `json:"run_error,omitempty"`
|
||||
Duration *time.Duration `json:"duration,omitempty"`
|
||||
ClockStartUnix int64 `json:"clock_start_unix"`
|
||||
}
|
||||
|
||||
// sessionEvent records a single timestamped payload entry.
|
||||
|
|
@ -262,7 +277,7 @@ func ensureSessionBaseDir(baseDir string) error {
|
|||
|
||||
// logEvent records a new event with the elapsed timestamp.
|
||||
func (r *sessionRecorder) logEvent(kind string, payload any) {
|
||||
data, err := json.Marshal(payload)
|
||||
data, err := marshalSessionJSON(payload)
|
||||
if err != nil {
|
||||
r.mu.Lock()
|
||||
if r.eventErr == nil {
|
||||
|
|
@ -434,6 +449,7 @@ func (r *sessionRecorder) finalize(runErr error) error {
|
|||
defer file.Close()
|
||||
|
||||
encoder := json.NewEncoder(file)
|
||||
encoder.SetEscapeHTML(false)
|
||||
encoder.SetIndent("", " ")
|
||||
if err := encoder.Encode(fileContent); err != nil {
|
||||
finalizeErr = errors.Join(err, eventErr, hookErr)
|
||||
|
|
@ -563,7 +579,7 @@ func (r *sessionRecorder) logGRPCMessage(method, event string, msg any,
|
|||
payload.Payload = data
|
||||
}
|
||||
} else {
|
||||
data, err := json.Marshal(msg)
|
||||
data, err := marshalSessionJSON(msg)
|
||||
if err == nil {
|
||||
payload.Payload = data
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue