Skip to content

Commit edeee68

Browse files
committed
fix(docs): stabilize named range text output
1 parent 2da0b09 commit edeee68

2 files changed

Lines changed: 73 additions & 14 deletions

File tree

internal/cmd/docs_named_ranges.go

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,15 @@ func (c *DocsNamedRangesCreateCmd) Run(ctx context.Context, kctx *kong.Context,
227227
if createdID == "" {
228228
return fmt.Errorf("create named range: response missing namedRangeId")
229229
}
230-
return writeResult(ctx, ui.FromContext(ctx),
231-
kv("documentId", docID),
232-
kv("namedRange", docsNamedRangeItem{Name: name, NamedRangeID: createdID, Ranges: []docsNamedRangeSpan{span}}),
233-
)
230+
created := docsNamedRangeItem{Name: name, NamedRangeID: createdID, Ranges: []docsNamedRangeSpan{span}}
231+
if outfmt.IsJSON(ctx) {
232+
return outfmt.WriteJSON(ctx, os.Stdout, map[string]any{
233+
"documentId": docID,
234+
"namedRange": created,
235+
})
236+
}
237+
writeDocsNamedRangeTextResult(ui.FromContext(ctx), docID, created)
238+
return nil
234239
}
235240

236241
type DocsNamedRangesDeleteCmd struct {
@@ -280,10 +285,15 @@ func (c *DocsNamedRangesDeleteCmd) Run(ctx context.Context, flags *RootFlags) er
280285
if err != nil {
281286
return fmt.Errorf("delete named range: %w", err)
282287
}
283-
return writeResult(ctx, ui.FromContext(ctx),
284-
kv("documentId", docID),
285-
kv("deleted", map[string]any{"name": item.Name, "namedRangeId": item.NamedRangeID}),
286-
)
288+
if outfmt.IsJSON(ctx) {
289+
return outfmt.WriteJSON(ctx, os.Stdout, map[string]any{
290+
"documentId": docID,
291+
"deleted": map[string]any{"name": item.Name, "namedRangeId": item.NamedRangeID},
292+
})
293+
}
294+
writeDocsNamedRangeTextResult(ui.FromContext(ctx), docID, item)
295+
ui.FromContext(ctx).Out().Linef("deleted\ttrue")
296+
return nil
287297
}
288298

289299
type DocsNamedRangesReplaceCmd struct {
@@ -364,12 +374,19 @@ func (c *DocsNamedRangesReplaceCmd) Run(ctx context.Context, kctx *kong.Context,
364374
if !found {
365375
return fmt.Errorf("replaced named range not found (id=%q)", item.NamedRangeID)
366376
}
367-
return writeResult(ctx, ui.FromContext(ctx),
368-
kv("documentId", docID),
369-
kv("namedRange", updatedItem),
370-
kv("replaced", true),
371-
kv("textLength", utf16Len(text)),
372-
)
377+
if outfmt.IsJSON(ctx) {
378+
return outfmt.WriteJSON(ctx, os.Stdout, map[string]any{
379+
"documentId": docID,
380+
"namedRange": updatedItem,
381+
"replaced": true,
382+
"textLength": utf16Len(text),
383+
})
384+
}
385+
u := ui.FromContext(ctx)
386+
writeDocsNamedRangeTextResult(u, docID, updatedItem)
387+
u.Out().Linef("replaced\ttrue")
388+
u.Out().Linef("textLength\t%d", utf16Len(text))
389+
return nil
373390
}
374391

375392
type docsNamedRangeSpan struct {
@@ -516,3 +533,17 @@ func docsNamedRangeTSV(value string) string {
516533
"\n", `\n`,
517534
).Replace(value)
518535
}
536+
537+
func writeDocsNamedRangeTextResult(u *ui.UI, docID string, item docsNamedRangeItem) {
538+
u.Out().Linef("documentId\t%s", docsNamedRangeTSV(docID))
539+
u.Out().Linef("name\t%s", docsNamedRangeTSV(item.Name))
540+
u.Out().Linef("namedRangeId\t%s", docsNamedRangeTSV(item.NamedRangeID))
541+
u.Out().Linef("rangeCount\t%d", len(item.Ranges))
542+
for i, span := range item.Ranges {
543+
prefix := fmt.Sprintf("range%d", i+1)
544+
u.Out().Linef("%sStartIndex\t%d", prefix, span.StartIndex)
545+
u.Out().Linef("%sEndIndex\t%d", prefix, span.EndIndex)
546+
u.Out().Linef("%sTabId\t%s", prefix, docsNamedRangeTSV(span.TabID))
547+
u.Out().Linef("%sSegmentId\t%s", prefix, docsNamedRangeTSV(span.SegmentID))
548+
}
549+
}

internal/cmd/docs_named_ranges_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"google.golang.org/api/docs/v1"
1313

1414
"github.com/steipete/gogcli/internal/outfmt"
15+
"github.com/steipete/gogcli/internal/ui"
1516
)
1617

1718
type docsNamedRangeRecorder struct {
@@ -263,6 +264,33 @@ func TestDocsNamedRangeTSVPreservesUnicodeAndLiteralCharacters(t *testing.T) {
263264
}
264265
}
265266

267+
func TestWriteDocsNamedRangeTextResultIsStableTSV(t *testing.T) {
268+
ctx, out := newDocsCmdOutputContext(t)
269+
ctx = outfmt.WithMode(ctx, outfmt.Mode{Plain: true})
270+
writeDocsNamedRangeTextResult(ui.FromContext(ctx), "doc1", docsNamedRangeItem{
271+
Name: "Résumé\tline\nnext",
272+
NamedRangeID: "nr1",
273+
Ranges: []docsNamedRangeSpan{{
274+
StartIndex: 2,
275+
EndIndex: 5,
276+
TabID: "tab\t1",
277+
SegmentID: "header\n1",
278+
}},
279+
})
280+
want := "" +
281+
"documentId\tdoc1\n" +
282+
"name\tRésumé\\tline\\nnext\n" +
283+
"namedRangeId\tnr1\n" +
284+
"rangeCount\t1\n" +
285+
"range1StartIndex\t2\n" +
286+
"range1EndIndex\t5\n" +
287+
"range1TabId\ttab\\t1\n" +
288+
"range1SegmentId\theader\\n1\n"
289+
if got := out.String(); got != want {
290+
t.Fatalf("output = %q, want %q", got, want)
291+
}
292+
}
293+
266294
func TestResolveDocsNamedRangeRejectsAmbiguousName(t *testing.T) {
267295
items := []docsNamedRangeItem{
268296
{Name: "same", NamedRangeID: "nr2"},

0 commit comments

Comments
 (0)