Skip to content

fix(slides): reindent xml-get output for readability#1987

Merged
tianyouskrrr merged 10 commits into
mainfrom
codex/cli-xml-pretty-print
Jul 22, 2026
Merged

fix(slides): reindent xml-get output for readability#1987
tianyouskrrr merged 10 commits into
mainfrom
codex/cli-xml-pretty-print

Conversation

@tianyouskrrr

@tianyouskrrr tianyouskrrr commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • slides +xml-get now reindents presentation/slide XML (via etree) before writing it to --output files and --raw stdout — the text surfaces a human or line tool reads directly
  • The default JSON envelope carries the server's original XML verbatim: inside a JSON string every newline is escaped to \n, so formatting there adds no readability while inflating the payload; passthrough also keeps that read path byte-exact without even parsing the content (no pretty_printed field, no fallback needed on this path)
  • Schema-documented whitespace character references such as  /	 (and CR/LF forms 
/
, incl. hex/zero-padded spellings) are preserved lexically across the parse/write pass on the formatted surfaces
  • --raw means formatted XML stdout without the JSON envelope; for the unmodified server payload, use the default envelope
  • If formatting fails on --raw/--output, the command returns the original server content, writes an explicit warning to stderr, and (for --output) reports pretty_printed: false in file metadata
  • Adds github.com/beevik/etree as a direct dependency

Why

The API returns XML as a single unindented line, which is unreadable for decks with many shapes (for example, PPTX-imported presentations). Reformatting client-side in this read-only command keeps the change contained while preserving whitespace references that can be significant in later SML write operations.

Formatting is deliberately scoped to the file/stdout text surfaces: agents consuming the JSON envelope pay per token and gain nothing from escaped newlines, and the untouched envelope doubles as a byte-exact escape hatch that needs no fidelity machinery at all.

The fallback on the formatted surfaces remains best-effort by design: unusual or non-strict XML from the service is still retrievable, but callers are no longer left unaware that formatting was skipped.

Test plan

  • make unit-test
  • go vet ./...
  • gofmt -l .
  • go mod tidy (no additional changes)
  • make build
  • Regression coverage for decimal/hex/zero-padded whitespace character references, mixed-content sibling boundaries, non-mixed text leaves, idempotency, --raw help semantics, explicit fallback signaling for raw/file output, and verbatim envelope passthrough (well-formed and malformed content, both scopes)
  • go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 run --new-from-rev=origin/main
  • Manual PPTX import/read/write validation with repeated spaces, a tab, and a whitespace-only rich-text run
  • Mutation-tested the output wiring: re-adding envelope formatting, or dropping formatting from --raw/--output, each breaks pinned tests

The API always returns presentation/slide XML as a single unindented
line. slides +xml-get now reformats it with etree before writing to
--output, stdout, or the JSON envelope, so decks with many shapes
(e.g. PPTX-imported presentations) are readable without a separate
formatting step. There is no flag to disable this: the command has
no purpose other than handing a human readable XML.
@CLAassistant

CLAassistant commented Jul 21, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Fetched slide and presentation XML is formatted before being returned or written, while failed formatting falls back to the original XML and reports status. Tests cover formatting, preservation, output paths, and fallback behavior. A base record E2E workflow now skips without tenant credentials.

Changes

Slide XML formatting

Layer / File(s) Summary
XML formatting helper and dependency
go.mod, shortcuts/slides/slides_xml_get.go
Adds etree and implements structural XML formatting while preserving text-bearing content, CDATA, attributes, empty tags, and escaped whitespace.
Fetch path integration and fallback behavior
shortcuts/slides/slides_xml_get.go
Applies formatting to slide and presentation responses, reports pretty_printed in envelopes and file metadata, and returns original XML with a warning when formatting fails.
Formatted output and fallback validation
shortcuts/slides/slides_xml_get_test.go
Updates output expectations and tests formatting preservation, idempotency, malformed input, metadata, and fallback behavior.

E2E access guard

Layer / File(s) Summary
Tenant token prerequisite
tests/cli_e2e/base/base_record_batch_update_workflow_test.go
Skips the batch-update workflow when no tenant access token is available.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SlidesXMLGet
  participant prettyPrintXMLOrOriginal
  participant etree
  SlidesXMLGet->>prettyPrintXMLOrOriginal: fetched slide or presentation XML
  prettyPrintXMLOrOriginal->>etree: parse and serialize XML
  etree-->>prettyPrintXMLOrOriginal: formatted XML or parse error
  prettyPrintXMLOrOriginal-->>SlidesXMLGet: XML and pretty_printed status
Loading

Suggested reviewers: ethan-zhx

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.59% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: reindenting Slides XML output for readability.
Description check ✅ Passed It includes the required summary, rationale, and test details, but omits the template's Changes and Related Issues sections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cli-xml-pretty-print

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the size/M Single-domain feat or fix with limited business impact label Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@bb10b03215de6ed72c96c980e91b65b81c644a08

🧩 Skill update

npx skills add larksuite/cli#codex/cli-xml-pretty-print -y -g

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.14607% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.08%. Comparing base (12ca42c) to head (6ebe565).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/slides/slides_xml_get.go 83.14% 10 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1987      +/-   ##
==========================================
+ Coverage   75.05%   75.08%   +0.03%     
==========================================
  Files         901      901              
  Lines       95391    95647     +256     
==========================================
+ Hits        71591    71812     +221     
- Misses      18307    18328      +21     
- Partials     5493     5507      +14     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

etree's Indent() decodes and strips whitespace-only text nodes
indiscriminately, which collides with the SML schema's own convention of
using  /	 character references to preserve deliberate spaces/tabs
inside <p> and inline formatting elements (span/strong/em/etc.) - those
decode to plain whitespace indistinguishable from formatting whitespace,
so the reindent was silently deleting them. Reformatting now only
recurses into structural elements (presentation/slide/shape/style/...)
and leaves any schema-mixed text-bearing subtree exactly as parsed.
CDATA is also now preserved via ReadSettings.PreserveCData instead of
being flattened into escaped text.

Tests: replaced self-referential wantXML expectations (computed by
calling prettyPrintXML itself) with independent golden strings, and
added coverage for the specific whitespace/CDATA loss patterns plus the
previously-uncovered reformat-error path through the full command.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@tianyouskrrr
tianyouskrrr requested a review from ethan-zhx July 21, 2026 12:57
@tianyouskrrr tianyouskrrr self-assigned this Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/cli_e2e/base/base_record_batch_update_workflow_test.go (1)

110-111: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Assert failure for missing record update.

When a batch update request contains a non-existent record ID (recZZZZZZZZZZZ), the API rejects the atomic request. Asserting a successful exit code (0) and a true stdout status is incorrect and appears to have been copy-pasted from the success case. Please update these assertions to expect a command failure (e.g., a non-zero exit code and false stdout status).

🐛 Proposed fix
-	missingResult.AssertExitCode(t, 0)
-	missingResult.AssertStdoutStatus(t, true)
+	require.NotEqual(t, 0, missingResult.ExitCode, "Expected non-zero exit code for missing record update")
+	missingResult.AssertStdoutStatus(t, false)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli_e2e/base/base_record_batch_update_workflow_test.go` around lines
110 - 111, Update the missing-record batch update assertions in the
missingResult workflow to expect command failure: use a non-zero exit code and a
false stdout status, matching the API’s rejection of the atomic request and
leaving success-case assertions unchanged.
🧹 Nitpick comments (1)
tests/cli_e2e/base/base_record_batch_update_workflow_test.go (1)

19-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove redundant parentT variable.

parentT is an alias for t and is passed alongside it. If createTableWithRetry requires two *testing.T arguments (e.g., for passing both a parent test and subtest context), you can safely pass t directly for both arguments and remove the intermediate variable.

♻️ Proposed refactor
-	parentT := t
-	ctx, cancel := context.WithTimeout(context.Background(), 4*time.Minute)
-	t.Cleanup(cancel)
-
-	baseToken := createBaseWithRetry(t, ctx, "lark-cli-e2e-batch-update-"+clie2e.GenerateSuffix())
-	tableID, _, _ := createTableWithRetry(
-		t,
-		parentT,
+	ctx, cancel := context.WithTimeout(context.Background(), 4*time.Minute)
+	t.Cleanup(cancel)
+
+	baseToken := createBaseWithRetry(t, ctx, "lark-cli-e2e-batch-update-"+clie2e.GenerateSuffix())
+	tableID, _, _ := createTableWithRetry(
+		t,
+		t,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli_e2e/base/base_record_batch_update_workflow_test.go` around lines 19
- 26, Remove the redundant parentT alias in the batch update workflow test and
pass t directly to both arguments of createTableWithRetry, preserving the
existing test context and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tests/cli_e2e/base/base_record_batch_update_workflow_test.go`:
- Around line 110-111: Update the missing-record batch update assertions in the
missingResult workflow to expect command failure: use a non-zero exit code and a
false stdout status, matching the API’s rejection of the atomic request and
leaving success-case assertions unchanged.

---

Nitpick comments:
In `@tests/cli_e2e/base/base_record_batch_update_workflow_test.go`:
- Around line 19-26: Remove the redundant parentT alias in the batch update
workflow test and pass t directly to both arguments of createTableWithRetry,
preserving the existing test context and behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b315255f-cad1-4c25-9a24-69545fc6cf0d

📥 Commits

Reviewing files that changed from the base of the PR and between 4478d7b and 091a982.

📒 Files selected for processing (1)
  • tests/cli_e2e/base/base_record_batch_update_workflow_test.go

@fangshuyu-768

Copy link
Copy Markdown
Collaborator

One behavior risk worth tightening: prettyPrintXML currently parses entity references and serializes them back as literal characters. In particular, SML documents whitespace-sensitive text by using &#32; / &#9; inside <p> and inline text-bearing elements, but after this pass those become literal spaces/tabs in the slides +xml-get output.

That is usually equivalent at the XML layer, but +xml-get is also used as the read step in read-modify-write slide workflows. If a user saves the pretty-printed XML and feeds it back into replace/create, the server may treat those literal spaces/tabs according to the normal SML text whitespace rules, potentially collapsing or dropping whitespace that was originally preserved by numeric character references.

Could we either preserve/re-escape sensitive whitespace inside text-bearing subtrees, or add a regression test proving that a readback containing &#32; / &#9; remains safe to round-trip through the write APIs?

Comment thread shortcuts/slides/slides_xml_get.go
Comment thread shortcuts/slides/slides_xml_get_test.go Outdated
Comment thread shortcuts/slides/slides_xml_get.go Outdated
Comment thread go.mod Outdated
Comment thread shortcuts/slides/slides_xml_get.go Outdated
Comment thread shortcuts/slides/slides_xml_get.go Outdated
fangshuyu-768
fangshuyu-768 previously approved these changes Jul 22, 2026
The JSON envelope now carries the server's original XML verbatim: inside
a JSON string every newline is escaped anyway, so reindenting there buys
no readability while inflating the payload, and passthrough restores a
byte-exact read path without even parsing the content (the pretty_printed
field and the fallback warning disappear from this path along with the
parse). --raw stdout and --output files keep the reindented form with the
fidelity machinery unchanged; pretty_printed stays in --output file
metadata where formatting is still attempted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tianyouskrrr
tianyouskrrr merged commit 8ba910e into main Jul 22, 2026
23 checks passed
@tianyouskrrr
tianyouskrrr deleted the codex/cli-xml-pretty-print branch July 22, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants