Developer views¶
Four views added in 0.0.16 show the things a developer reads every day:
a file's merge conflicts, one record of a data set, a crate's supply chain,
and what changed between two schemas. Each is a renderable in a library
crate and a flag of an existing rich command, so it reads the same in a
program, a script and a terminal. This page says what each is for and links
to its detailed section.
| View | Library | Command | Detail |
|---|---|---|---|
| Merge conflicts | rich_ext::diff::ConflictView |
rich diff --conflicts FILE |
Merge conflicts |
| One record | rich_ext::data::RecordView |
The record inspector | |
| The supply chain | rich_ext::deps::{duplicates, features, timings, audit, licenses} |
rich deps --duplicates, --features, --timings, --audit, --licenses |
Supply-chain reports |
| Schema changes | rich_ext::schema::{SchemaDiff, SchemaTimeline} |
rich schema OLD NEW |
Schemas |
None of them needs colour to be read: markers (< | > for conflict
sides, + - ~ for changes) and words (breaking, FAIL, a severity)
carry the meaning, and every style comes from a theme key a theme can
override.
Merge conflicts¶
ConflictFile::parse reads the markers git merge leaves in a file,
including diff3 bases and the longer markers of nested conflicts and
conflict-marker-size, and ConflictView shows each conflict numbered,
with ours, base and theirs side by side or stacked, syntax highlighted, and
a few lines of context. Line numbers are the file's, so they lead back to
the markers. Malformed markers are an error naming the line.
const MERGED: &str = "\
fn timeout() -> u64 {
<<<<<<< HEAD
30
||||||| merged common ancestors
10
=======
env_or(\"TIMEOUT\", 10)
>>>>>>> feature/env
}
";
fn show_conflicts(console: &Console) {
let file = ConflictFile::parse(MERGED).expect("well-formed markers");
let conflict = &file.conflicts()[0];
assert_eq!(file.text(&conflict.ours), " 30");
assert_eq!(conflict.theirs.label.as_deref(), Some("feature/env"));
// Side by side when every column fits, stacked otherwise.
console.print(&ConflictView::new(file).path("src/config.rs"));
}
For a file on disk, ConflictView::parse(&std::fs::read_to_string(path)?)?
parses and wraps it in one step, and .layout(ConflictLayout::Stacked) (or
SideBySide) overrides the automatic choice.
The record inspector¶
RecordView shows one record (a parsed JSON, YAML or TOML document, or any
serde value) as a field | type | value table, with nested values as
trees opened a few levels deep, long strings and containers cut, and
expand(path) / collapse(path) to open or fold a branch by path. Redact
before display with redact(…). It is the static half of
rich_interact's data explorer: both implement OpenBranch.
fn show_record(console: &Console) {
let record = parse(
Format::Json,
r#"{"id": 7, "name": "web", "password": "hunter2",
"ports": [80, 443, 8080, 8443],
"owner": {"team": "infra", "oncall": {"primary": "ana", "backup": "bo"}}}"#,
)
.unwrap();
let view = RecordView::new(&record)
.depth(1) // a nested value's own children show (the default)
.expand("owner.oncall".parse().unwrap()) // and this branch, however deep
.max_items(3) // then `… N more`
.redact(&Redaction::secrets());
console.print(&view);
}
The supply chain¶
Five reports beside rich deps' dependency tree read what Cargo already
wrote, and never run a scanner or reach the network:
- Duplicates: the crates in the graph at more than one version, the branches that pull each in, and a consolidation summary (detail).
- Features: each crate's enabled features, what they turn on and who asked for them (detail).
- Build times: the slowest units of a
cargo build --timingsreport as bars and a table (detail). - Advisories:
cargo audit --jsonoutput grouped by severity (detail). - Licences: crates grouped by licence, with copyleft, unknown and missing licences marked (detail).
The advisories report, from a cargo audit --json file:
fn audit(console: &Console) -> Result {
// `cargo audit --json > audit.json`
let report = AdvisoryReport::from_cargo_audit(&fixture("supply-chain/cargo-audit.json"))?;
console.print(&report);
Ok(())
}
Schema changes¶
SchemaDiff lists what changed between two schemas (JSON Schema, SQL DDL
or Arrow, through one model), marking breaking the changes that may
refuse data the old schema accepted; SchemaTimeline lays several versions
side by side. The schema guide covers both, with the tree and
ER views.
fn diff(console: &Console) -> Result {
let v1 = sql::parse(V1)?.schema;
let v2 = sql::parse(V2)?.schema;
console.print(&SchemaDiff::models(&v1, &v2).names("v1", "v2"));
Ok(())
}
From Python¶
ConflictView and RecordView are in
rs_rich.data
(and in rs_rich.ext.diff and rs_rich.ext.data), with the schema views.
The Cargo reports are the rich deps command, which python -m rs_rich
runs.