Skip to content

fix(plugins): #1738 follow-ups: fuzz lock, one notice part for cut trees, a UI test for the note (#1546) - #1754

Merged
giswqs merged 1 commit into
opengeos:mainfrom
elpidioassinaturas:fix/1546-followups
Nov 11, 2026
Merged

giswqs merged 1 commit into
opengeos:mainfrom
elpidioassinaturas:fix/1546-followups

Conversation

@elpidioassinaturas

@elpidioassinaturas elpidioassinaturas commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #1738 (#1546), which was merged before its last review round. This carries the points from that round.

What changes

  1. fuzz/Cargo.lock is updated. fix(plugins): a panel tree holds 20,000 nodes and says when it cuts (#1546) #1738 moved unicode-normalization from rustgis-ui-egui to rustgis-plugins, and the fuzz lock still listed rustgis-plugins without it (review thread). The fuzz workflow's first job runs cargo deny --manifest-path fuzz/Cargo.toml --locked …, and --locked refuses a lock that needs updating. With the lock on main, cargo metadata --manifest-path fuzz/Cargo.toml --locked fails ("cannot update the lock file … because --locked was passed"), and with this one it passes. cargo update -p rustgis-plugins in fuzz/ also adds quick-xml under rustgis-data, which the lock had lost track of on main before fix(plugins): a panel tree holds 20,000 nodes and says when it cuts (#1546) #1738. cargo check --locked --bins in fuzz/ builds.
  2. Trees cut in one answer are said in one part of the warning. AGENTS.md ("Never silent") asks for one notice per kind, with a count. fix(plugins): a panel tree holds 20,000 nodes and says when it cuts (#1546) #1738 added one part per cut tree, so two trees cut in one answer gave two parts (review thread). They now share one part, with the count, the limit once and each tree with the nodes it was given (up to 10 named, as the other parts do): 2 tree(s) cut: only the first 20000 nodes are kept, the most a tree holds: catalogue (20001 nodes given), places (20002 nodes given).
  3. The note under a cut tree has a UI test (review thread). a_cut_tree_says_so_under_its_rows_and_an_empty_search (kittest) opens a plugin's panel, gives its tree MAX_TREE_NODES + 1 nodes, and finds the note, with the count given and the limit twice, under the rows and under a search for the node left out ("Nothing matches."). A tree given 3 nodes after that shows no note.

Measurement: applying a 20,000-node answer

This answers the performance question: PanelState::apply runs on the thread that ran the plugin's command, which on the desktop is the UI thread. The measurement used a throwaway test, not in this PR, in the workspace's test profile on Windows. It ran three times over 25 branches of municipality-like labels with accents, with ids and counts.

answer parse the JSON apply total
5,000 nodes (0.3 MB) 3.7 / 6.3 / 4.0 ms 15.6 / 17.3 / 10.7 ms 15–24 ms
20,000 nodes (1.2 MB) 17.9 / 15.0 / 18.2 ms 40.2 / 37.9 / 36.3 ms 53–58 ms

So the largest answer a tree takes costs about three 60 fps frames, once, when the plugin sends it (usually as the panel opens), not at every frame. Folding the labels takes about 12 ms of the 38. A path that skips decomposition for ASCII characters would save about 6 ms of that, which is too little to be worth a second folding function, so it isn't done. The work is bounded by the limit. Moving apply off the UI thread would change how every plugin command's answer reaches the panel, a larger change and not part of this PR.

Screenshots

These are rendered with the same wgpu renderer the ui_shot example uses, by a throwaway test (not in this PR), over a tree of 5 regions, 27 states and 800 municipalities each (21,632 nodes). The warning in the status bar is the new single part.

The note under the rows:

A search for a municipality of the last state, left out at the limit:

Tests

  • a_tree_cut_at_its_limit_says_so (plugins) now also cuts two trees in one answer and checks the single part.
  • a_cut_tree_says_so_under_its_rows_and_an_empty_search (ui-egui) is new.

Locally (Windows): cargo fmt --check passes, and so does cargo clippy -p rustgis-plugins -p rustgis-engine -p rustgis-ui-egui --all-targets -- -D warnings. The tests of rustgis-plugins and of the rustgis-ui-egui library pass too. cargo deny isn't installed here, so the lock was checked with cargo metadata --locked as described above. Main doesn't build at the moment: crates/engine/src/cmd/layout.rs passes &[] to legend_sizes_mm, whose signature changed in #1739. #1751 fixes that. The clippy run and the test runs above had #1751's one-line change applied locally, which this PR doesn't include, so this PR's CI fails on main's error until #1751 is merged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • When multiple trees exceed the retained-node limit in one panel response, they now appear together in a single notice instead of generating separate notices. The notice includes each listed tree’s node count and indicates when additional trees were cut off.
  • Tests
    • Added coverage for notices involving multiple cut trees and for tree truncation notes shown during searches, including searches with no matches.

…r cut trees, a UI test for the note (opengeos#1546)

- fuzz/Cargo.lock lists unicode-normalization under rustgis-plugins (and
  quick-xml under rustgis-data), so `cargo deny --locked` in the fuzz
  workflow takes it again.
- Trees cut in one answer share one part of the warning, with the count,
  the limit once and each tree's given nodes ("Never silent").
- A kittest finds the note under a cut tree's rows and under an empty
  search, and none under a tree within its limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Tree cutoff notices now combine details for multiple cut trees. Tests check the aggregate notice and verify when the UI displays the truncation note.

Changes: Tree cutoff notices

Layer / File(s) Summary
Aggregate cutoff notice
crates/plugins/src/panel.rs, crates/plugins/src/tests.rs
Dropped::notice reports cut trees in one notice, with up to MAX_NAMED tree IDs, supplied node counts, an ellipsis when needed, the total cut-tree count, and the limit. A test checks the notice for two cut trees.
UI truncation note
crates/ui-egui/src/pluginpanel.rs
A UI test checks that the truncation note appears below visible rows and when a search returns no matches. It also checks that the note is absent for a tree with three nodes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related issues

Possibly related PRs

Suggested reviewers: giswqs

Merge Risk: Minimal · up to e42d7

The cutoff notice and UI-note changes have no identified merge-blocking issue; they are ready for normal merge checks.

Pre-merge checks: Passed 5

Check name Status Explanation
Title check Passed The title identifies the follow-up and its main changes: the combined notice for cut trees, a UI test, and a fuzz lockfile update. It is longer than needed, but it is specific and related to the chang…
Description check Passed The description gives a detailed summary, testing information, related issue context, and UI screenshots. It is mostly complete, but the screenshots show only the updated UI; the template requests bef…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
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.
Full details: Title check

Explanation

The title identifies the follow-up and its main changes: the combined notice for cut trees, a UI test, and a fuzz lockfile update. It is longer than needed, but it is specific and related to the changeset.

Full details: Description check

Explanation

The description gives a detailed summary, testing information, related issue context, and UI screenshots. It is mostly complete, but the screenshots show only the updated UI; the template requests before-and-after screenshots for changes to existing UI.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 3 files.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

A rabbit counts the branches trimmed,
One note gathers every limb.
Search high, search low, the message stays,
Short trees pass through uncut ways.
The rabbit hops, content with the display.

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: f5981382-b655-4a92-b966-dba19a4b27c4
Commits

Reviewing files that changed from the base of the PR and between a411d53 and e42d7cb.

Files ignored due to path filters: 1

  • fuzz/Cargo.lock is excluded by !**/*.lock
Files selected for processing: 3

  • crates/plugins/src/panel.rs
  • crates/plugins/src/tests.rs
  • crates/ui-egui/src/pluginpanel.rs

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 5 remain after this review.

@github-actions

Copy link
Copy Markdown
Contributor

Code review

I read the full diff, the base-branch AGENTS.md, and the surrounding code in panel.rs, pluginpanel.rs, the plugin tests, docs/plugins.md, the fuzz and root lockfiles, and render/src/layout.rs. prior-reviews.json has no threads, so nothing was left out as already raised. I found no defects on the changed lines, so I posted no inline comments.

Bugs

  • None found in the changed lines. The combined "tree(s) cut" part keeps the existing test assertions true (one catalogue mention, 20001 nodes, first 20000), and the new text matches the UI note exactly (panel.rs:562-575, pluginpanel.rs:1364). Confidence: high.
  • Build break on this head, not from this PR: crates/engine/src/cmd/layout.rs:1992 passes &[] to legend_sizes_mm, which takes a (&[String], &BTreeMap) tuple (crates/render/src/layout.rs:1968-1973). So rustgis-engine and rustgis-ui-egui don't compile here, and the new UI test can't run on this head. The plugins change is verified only by reading. The PR body already names fix(layout): main builds again: pass legend_sizes_mm its excluded layers and labels #1751 as the fix. Confidence: high.

Security

  • None. The notice still uses diagnostic_name and bounded name samples.

Performance

  • None new. The change only reformats the notice and keeps at most ten names. PanelState::apply still runs on the UI thread, as it did before this PR. The timing table in the PR body comes from a throwaway test that isn't in the repo, so I could not check it. Confidence: medium.

Quality

  • Dropped::cut (panel.rs:497-498) keeps one entry per cut tree, and the struct doc only describes bounds for the other fields. The count is bounded by the manifest's 32-item limit, so this is only a doc gap. Quality point, for the release quality pass. Confidence: high.
  • The single-tree wording is now 1 tree(s) cut: … catalogue (20001 nodes given). It is accurate but reads a little clumsily. Quality point, for the release quality pass. Confidence: medium.

AGENTS.md

  • Never silent: complies. One part with a count replaces one part per tree, and the plugins test covers both lossy (two trees) and clean (three nodes, no note) input. The UI test covers the note under rows and under an empty search.
  • Lockfile: the fuzz/Cargo.lock additions look right. There is one quick-xml and one unicode-normalization entry, both dependency lines are sorted, and rustgis-data has a non-optional quick-xml dependency. I could not run cargo metadata --locked without a shell, so the PR's claim is unverified. Confidence: medium.
  • Tests: the UI test loads a plugin into the global registry and unloads it only on success, the same pattern as the existing plugin UI tests. Nit, not a rule break. Confidence: high.

Prior concerns left alone: 0 (no prior review threads).

Change size

Compared: the whole PR against main (merge base 0c44ff6 to PR head e42d7cb).

Measure Value
Files changed 4 (added 0, modified 4, removed 0, renamed 0)
Size before 401.7 KB
Size after 406.0 KB
Total size change +4.3 KB
Path Before After Change
crates/ui-egui/src/pluginpanel.rs 106.9 KB 109.8 KB +2.9 KB
crates/plugins/src/tests.rs 125.9 KB 126.9 KB +1.0 KB
crates/plugins/src/panel.rs 66.5 KB 66.8 KB +338 B
fuzz/Cargo.lock 102.5 KB 102.5 KB +40 B

@github-actions

Copy link
Copy Markdown
Contributor

📖 Docs preview

Item Value
Preview https://preview.rustgis.app/pr-1754/
Web app https://preview.rustgis.app/pr-1754/app/
Commit e42d7cb

GitHub Pages takes a minute or two to publish a new commit.

@giswqs
giswqs merged commit 2ce3d75 into opengeos:main Nov 11, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants