feat(cli): add bfabric-cli workunit diff command - #568
Merged
Conversation
Compare two workunits side by side (name, parameters, output/input resources, status, application, container, input dataset), highlighting differences in rich tables. Each reference is an entity URI or a numeric workunit ID; --only-diff collapses output to the differing rows.
Replace the EntityUri validation regex with urllib.parse-based parsing and add EntityUri.from_web_url, which normalizes a URL as copied from the browser into the canonical entity URI: extra query parameters (e.g. &tab=details) and the fragment are dropped, host case and a default port are normalized. The result compares and hashes equal to the entity's canonical EntityUri, so a pasted URL works as an EntityResult/cache key. The EntityUri constructor stays strict and now hints at from_web_url when it rejects such a URL; its other rejections name the actual problem (scheme/host, path, query) instead of a blanket "Invalid Entity URI". Credentials in the URL are now rejected outright and the localhost exemption is case-insensitive. bfabric-cli workunit diff parses its references leniently, so a workunit URL pasted from the browser resolves instead of erroring out.
EntityUri.from_web_url becomes EntityUri.normalize, naming the guarantee it gives (a canonical URI) rather than the shape of its input, and trims its docstring to the repo's terser convention. _parse_uri_components drops from 48 to 37 lines with no change to what it accepts: strict mode now reuses the lenient parse and then requires the URI to have been canonical, the components model is constructed directly instead of via model_validate on a dict, and the instance is rebuilt from netloc instead of reassembling host and port (which also fixes IPv6 hosts). Two error messages move: a strict-mode non-numeric or missing id now reports that specifically instead of the generic "expected query 'id=<entity_id>'" hint, and a malformed port surfaces as a pydantic ValidationError.
The existing guidance only covered restating default values, so nothing said which style to write (Sphinx :param: dominates; a handful of older modules still carry Google-style Args:/Returns: blocks) or how much to write. Add both, plus the trap that a cyclopts command docstring is its --help text and must not be trimmed like an internal helper's.
_resolve_workunit mapped a failed URI parse to a None sentinel and then re-branched on it, spreading one decision over two conditionals. Test the numeric case first instead, so the URI branch can raise directly; the parse error is translated so a typo'd reference still reports that an ID would also be accepted.
leoschwarz
marked this pull request as ready for review
July 31, 2026 11:56
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.
bfabric-cli workunit diffcommand to compare to workunits including their parameters.EntityUri.normalizeto normalize e.g. a pastedhttps://…/bfabric/workunit/show.html?id=346001&tab=detailsto anEntityUri.🤖 Prepared with assistance from Claude Opus 5 via Claude Code.