3.1 KiB
+++ title = "Add --xml output format that wraps each ticket section in XML tags" priority = 4 status = "todo" ticket_type = "feature" dependencies = [] +++
Background
From nbd/TODO.md:
Add a
--xmloutput format that prints tickets with XML around each section to make it easier to parse metadata.
Unlike --json (which is a complete, structured parse), the XML format adds lightweight tags around each metadata field in the human-readable output. This makes it trivial for scripts to extract specific fields using simple text tools (e.g., grep, sed, XPath) without pulling in a full JSON parser.
Intended XML format
For a single ticket (nbd read <id> --xml):
<ticket>
<id>a3f9c2</id>
<title>Fix login bug</title>
<priority>8</priority>
<status>in_progress</status>
<type>bug</type>
<dependencies>
<dep>b7d41e</dep>
<dep>c9e823</dep>
</dependencies>
<body>Users cannot log in with email addresses containing +</body>
</ticket>
For a list (nbd list --xml):
<tickets>
<ticket>...</ticket>
<ticket>...</ticket>
</tickets>
Implementation
src/main.rs
Add a global --xml flag to the Cli struct, parallel to --json:
/// Output XML instead of a human-readable table.
#[arg(long, global = true)]
xml: bool,
Precedence: if both --json and --xml are supplied, --json wins (or return an error — TBD, but JSON-first is simpler).
Pass cli.xml through dispatch to every command handler, alongside cli.json.
Each command handler signature gains an xml: bool parameter. When xml is true and json is false, call the new display::print_ticket_xml / display::print_list_xml functions.
src/display.rs
Add:
format_ticket_xml(ticket: &Ticket) -> String— serialises a single ticket as XMLprint_ticket_xml(ticket: &Ticket)— wrapsformat_ticket_xml+println!format_list_xml(tickets: &[Ticket]) -> String— wraps list in<tickets>print_list_xml(tickets: &[Ticket])
XML escaping: at minimum, escape &, <, >, ", ' in field values. Use a small helper xml_escape(s: &str) -> String rather than pulling in an XML crate.
For dependencies: render each as a <dep> child element.
src/tests.rs
Add unit tests:
format_ticket_xmlwith a ticket that has special characters in the title and body (&,<,>)format_ticket_xmlwith empty dependenciesformat_ticket_xmlwith multiple dependenciesformat_list_xmlwith zero and multiple tickets
tests/integration.rs
Add integration tests:
nbd read <id> --xmlreturns valid XML containing the ticket's fieldsnbd list --xmlreturns valid XML wrapping multiple ticketsnbd create ... --xmlreturns the created ticket as XMLnbd update ... --xmlreturns the updated ticket as XML
Scope
All commands that support --json should also support --xml:
nbd createnbd readnbd listnbd updatenbd readynbd nextnbd archivenbd migratenbd graph(the JSON graph format has a defined structure; XML should mirror it)nbd claude-md(wrap snippet in<snippet>tag)nbd init(wrap root path in<init>)