Make spacetime describe support human-readable versions - #5947
Open
krisajenkins wants to merge 1 commit into
Open
krisajenkins wants to merge 1 commit into
krisajenkins wants to merge 1 commit into
Conversation
spacetime describe print a human-readable schema by defaultspacetime describe support human-readable versions
…uired
flag, and its help text promises that "in the future, omitting this will give
human-readable output". This patch brings that glorious future. 😁
`spacetime describe [db]` now prints the module as readable text, in the
sections Tables, Views, Reducers, Procedures, and Types:
```
page_previews (public)
Columns:
title String primary key
page_id U64
rev_id U64
display_title String
description Option<String>
extract String
thumbnail Option<Thumbnail>
fetched_at Timestamp
Indexes:
page_previews_title_idx_btree btree (title)
```
You can narrow it to every entity of one kind, or to one entity by name. The
entity types are `tables`, `reducers`, `procedures` and `types`, matching the
section headings:
```
$ spacetime describe wikiwatch procedures
fetch_edits(timer: FetchEditsSchedule) [private]
fetch_previews(timer: FetchPreviewsSchedule) [private]
$ spacetime describe wikiwatch types Thumbnail
Thumbnail = { url: String, width: U32, height: U32 }
```
The singular forms (`table person`) still work, since that's what the
JSON-only command accepted. `--format json`, or the existing `--json`
shorthand, prints the raw definitions instead: the whole module, an array for
a listing, or a single def. Text is styled like the migration plan that
`spacetime publish` prints, and is coloured only when stdout is a terminal and
`NO_COLOR` is unset.
The renderer is a new `describe` module in the schema crate, next to the
migration printer whose look it shares.
- `StyledWriter`: the colour scheme, colour/no-colour buffer and indent
helpers move out of `TermColorFormatter` into a `pub(crate)` writer that
both printers use. Migration output is unchanged, and its snapshots pass
untouched.
- `type_name` spells types language-neutrally: `U64`, `Array<T>`,
`Option<T>`, `Timestamp`, and named types by their scoped name joined with
`.`. It reads the "for generate" typespace, which keeps special types and
refs intact.
- Field and variant names come from the case-converted typespace, because
`typespace_for_generate` keeps source names (`imageUrl`, not `image_url`).
Column defaults are formatted through `WithTypespace`, so a sum prints as
`(red = ())` rather than `( = ())`.
- Reducer names arrive already qualified with their submodule
(`lib.end_session`), while table, view, procedure and type names are local
and have the prefix added. Prefixing reducers too would print
`lib.lib.end_session`, and a test pins that.
- Types lists only named types reachable from a column or a signature, and
leaves out table row types, which their table's block already shows.
`types <name>` searches every named type, so a row type seen in a signature
(`FetchEditsSchedule`) can still be looked up.
- Each listing (`describe_tables` and friends) shares its sorted source with
the whole-module renderer, and tests pin each one to its module section.
- CLI: `--format text|json` defaults to `text`, using a `Format` enum now
shared with `sql` and `logs` in `common_args`. `--json` conflicts with an
explicit `--format`. Whole-module JSON is still the raw, unvalidated def,
returned before validation, so a module that fails validation can still be
dumped for debugging. Existing JSON output is byte-for-byte unchanged.
- Tests: insta snapshots of a fixture covering every section, submodules,
indexes, constraints, defaults and schedules. The `describe` smoketest now
checks the text output, exact single-entity output, `--json` against
`--format json`, and the flag conflict.
- Docs: the regenerated CLI reference, the cheat sheet, and the CLI agent
skill, plus its codex-plugin copy, which must match byte for byte.
- Known gap: inside a submodule table, a column whose type is defined in that
submodule prints the bare type name, while Types prefixes it with `lib.`.
# API and ABI breaking changes
None. `spacetime describe <db>` without `--json` used to be an error, so no
existing invocation changes meaning, and JSON output is byte-for-byte
unchanged. `--json` combined with an explicit `--format` is now rejected as a
conflict, but `--format` is new to this command.
# Rollback safety impact
n/a
# Expected complexity level and risk
2. The diff is large, but most of it is the new, self-contained renderer and
its snapshots. The parts that touch existing code are the `StyledWriter`
extraction from the migration printer (its snapshots pass untouched) and
the shared `Format` enum now used by `sql` and `logs`.
# Testing
- [x] Insta snapshots for the renderer: whole module (colour and no colour), a single table, a single reducer.
- [x] Unit tests pinning each listing to its module section, and submodule reducer names not being double-prefixed.
- [x] `describe` smoketest covers text output, exact single-entity output, `--json` vs `--format json`, and the flag conflict.
- [ ] Reviewer: run `spacetime describe` against a real module of your own and check the output reads well.
krisajenkins
force-pushed
the
describe-human-readable
branch
from
September 16, 2026 08:31
3e48393 to
e1ca570
Compare
krisajenkins
marked this pull request as ready for review
September 16, 2026 09:28
krisajenkins
enabled auto-merge
September 16, 2026 09:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Run
spacetime describe mydbtoday and it refuses:--jsonis a requiredflag, and its help text promises that "in the future, omitting this will give
human-readable output". This patch brings that glorious future. 😁
spacetime describe [db]now prints the module as readable text, in thesections Tables, Views, Reducers, Procedures, and Types:
You can narrow it to every entity of one kind, or to one entity by name. The
entity types are
tables,reducers,proceduresandtypes, matching thesection headings:
The singular forms (
table person) still work, since that's what theJSON-only command accepted.
--format json, or the existing--jsonshorthand, prints the raw definitions instead: the whole module, an array for
a listing, or a single def. Text is styled like the migration plan that
spacetime publishprints, and is coloured only when stdout is a terminal andNO_COLORis unset.The renderer is a new
describemodule in the schema crate, next to themigration printer whose look it shares.
StyledWriter: the colour scheme, colour/no-colour buffer and indenthelpers move out of
TermColorFormatterinto apub(crate)writer thatboth printers use. Migration output is unchanged, and its snapshots pass
untouched.
type_namespells types language-neutrally:U64,Array<T>,Option<T>,Timestamp, and named types by their scoped name joined with.. It reads the "for generate" typespace, which keeps special types andrefs intact.
typespace_for_generatekeeps source names (imageUrl, notimage_url).Column defaults are formatted through
WithTypespace, so a sum prints as(red = ())rather than( = ()).(
lib.end_session), while table, view, procedure and type names are localand have the prefix added. Prefixing reducers too would print
lib.lib.end_session, and a test pins that.leaves out table row types, which their table's block already shows.
types <name>searches every named type, so a row type seen in a signature(
FetchEditsSchedule) can still be looked up.describe_tablesand friends) shares its sorted source withthe whole-module renderer, and tests pin each one to its module section.
--format text|jsondefaults totext, using aFormatenum nowshared with
sqlandlogsincommon_args.--jsonconflicts with anexplicit
--format. Whole-module JSON is still the raw, unvalidated def,returned before validation, so a module that fails validation can still be
dumped for debugging. Existing JSON output is byte-for-byte unchanged.
indexes, constraints, defaults and schedules. The
describesmoketest nowchecks the text output, exact single-entity output,
--jsonagainst--format json, and the flag conflict.skill, plus its codex-plugin copy, which must match byte for byte.
submodule prints the bare type name, while Types prefixes it with
lib..API and ABI breaking changes
None.
spacetime describe <db>without--jsonused to be an error, so noexisting invocation changes meaning, and JSON output is byte-for-byte
unchanged.
--jsoncombined with an explicit--formatis now rejected as aconflict, but
--formatis new to this command.Rollback safety impact
n/a
Expected complexity level and risk
its snapshots. The parts that touch existing code are the
StyledWriterextraction from the migration printer (its snapshots pass untouched) and
the shared
Formatenum now used bysqlandlogs.Testing
describesmoketest covers text output, exact single-entity output,--jsonvs--format json, and the flag conflict.spacetime describeagainst a real module of your own and check the output reads well.