You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.2 KiB
Markdown
108 lines
3.2 KiB
Markdown
---
|
|
# nbd-mkkm
|
|
title: Add --xml output format that wraps each ticket section in XML tags
|
|
status: todo
|
|
type: feature
|
|
priority: low
|
|
created_at: 2026-03-10T23:30:30Z
|
|
updated_at: 2026-03-10T23:30:30Z
|
|
---
|
|
|
|
## Background
|
|
|
|
From `nbd/TODO.md`:
|
|
|
|
> Add a `--xml` output 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`):
|
|
|
|
```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`):
|
|
|
|
```xml
|
|
<tickets>
|
|
<ticket>...</ticket>
|
|
<ticket>...</ticket>
|
|
</tickets>
|
|
```
|
|
|
|
## Implementation
|
|
|
|
### `src/main.rs`
|
|
|
|
Add a global `--xml` flag to the `Cli` struct, parallel to `--json`:
|
|
|
|
```rust
|
|
/// 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 XML
|
|
- `print_ticket_xml(ticket: &Ticket)` — wraps `format_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_xml` with a ticket that has special characters in the title and body (`&`, `<`, `>`)
|
|
- `format_ticket_xml` with empty dependencies
|
|
- `format_ticket_xml` with multiple dependencies
|
|
- `format_list_xml` with zero and multiple tickets
|
|
|
|
### `tests/integration.rs`
|
|
|
|
Add integration tests:
|
|
- `nbd read <id> --xml` returns valid XML containing the ticket's fields
|
|
- `nbd list --xml` returns valid XML wrapping multiple tickets
|
|
- `nbd create ... --xml` returns the created ticket as XML
|
|
- `nbd update ... --xml` returns the updated ticket as XML
|
|
|
|
## Scope
|
|
|
|
All commands that support `--json` should also support `--xml`:
|
|
- `nbd create`
|
|
- `nbd read`
|
|
- `nbd list`
|
|
- `nbd update`
|
|
- `nbd ready`
|
|
- `nbd next`
|
|
- `nbd archive`
|
|
- `nbd migrate`
|
|
- `nbd 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>`)
|