[CLI] Migrate buckets commands to out singleton#4111
Conversation
Consistent with `out.table()` and `out.result()`, `out.dict()` now accepts an `id_key` param. When set and mode is quiet, prints just that value instead of the full JSON.
Part of #3979. Migrates create, list, info, delete, remove, move, and cp to the unified `--format` flag and `out.*` methods. Preserves the ls-like flat table format for file listing.
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
Wauplin
left a comment
There was a problem hiding this comment.
Made a first pass, especially on the tests. Might be the worst CLI to migrate, sorry about that^^
sync left as-is (passes quiet/verbose to library)
Agree with this.
Just as a nit I think in the --plan mode we should output the --apply method just after as a hint.
| """ | ||
| if dataclasses.is_dataclass(data) and not isinstance(data, type): | ||
| data = _dataclass_to_dict(data) | ||
| if self.mode == OutputFormatWithAuto.quiet and id_key is not None: |
There was a problem hiding this comment.
if --quiet but no id_key provided, what should we do? Currently we default to printing the full JSON (not a problem from this PR but this addition highlights it^^)
There was a problem hiding this comment.
I don't know, for now full json is a reasonable fallback imo, quiet without id_key means the caller didn't specify what to extract, so printing everything is safer maybe ? 😄
|
|
||
| if recursive: | ||
| status = StatusLine(enabled=not quiet) | ||
| status = StatusLine(enabled=out.mode == OutputFormatWithAuto.human) |
There was a problem hiding this comment.
maybe we should make the StatusLine __init__ check the out.mode singleton by default instead of passing enabled=out.mode == OutputFormatWithAuto.human like here (i.e. remove the enabled parameter entirely)
There was a problem hiding this comment.
agreed, but it lives in utils/_terminal.py which doesn't currently import from cli/_output.py. doing it here would create a dependency from utils -> cli. i'd rather tackle this in a followup when we implement out.status()
There was a problem hiding this comment.
fine for me to do it in a later PR 👍
…ep tree --quiet behavior - Tests use --quiet instead of --format quiet (alias handled by TyperGroup) - _check_list_output uses result.stdout instead of filtering stderr lines - Restore quiet param on _build_tree so --tree --quiet shows structure only - Tree prints directly instead of mutating out.mode - Revert :>19 formatting back to explicit spaces in test expectations
Wauplin
left a comment
There was a problem hiding this comment.
Looks good to me! I've resolved the merge conflicts so we should be good to merge
(and let's not forget about #4111 (comment))
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 387dcfe. Configure here.
| } | ||
| for bucket in api.list_buckets(namespace=namespace, search=search) | ||
| ] | ||
| out.table(items, alignments={"size": "right", "total_files": "right"}) |
There was a problem hiding this comment.
Human-readable size formatting contaminates JSON output
Medium Severity
In _list_buckets, the size field is pre-formatted at dict construction time via _format_size(bucket.size, human_readable) if human_readable else bucket.size. When -h is passed, this converts the integer size to a human-readable string (e.g., "1.5 MB") in the items dict before passing it to out.table(). This means JSON output gets "size": "1.5 MB" instead of "size": 1500000, changing the field type from number to string. In the old code, _format_size was called only inside row_fn for table display, so JSON output always received raw integer values regardless of -h.
Reviewed by Cursor Bugbot for commit 387dcfe. Configure here.
| api = get_hf_api(token=token) | ||
|
|
||
| if recursive: | ||
| status = StatusLine(enabled=not quiet) |
There was a problem hiding this comment.
Dry-run produces no output in json/quiet modes
Low Severity
The remove command's --dry-run path uses out.text() to display what would be deleted. Since out.text() is a no-op in json and quiet modes, running hf buckets rm ... --dry-run --format json (or --format quiet) produces zero output and returns silently. The old code always printed dry-run details regardless of the --quiet flag, so this is a behavioral regression where users get no indication of what would be deleted.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 387dcfe. Configure here.
|
This PR has been shipped as part of the v1.12.0 release. |


Part of #3979. Migrates
bucketscommands (create,list,info,delete,remove,move,cp) to the unified--format [auto|human|agent|json|quiet]flag andout.*methods.--quietwith--formaton all migrated commandsout.result()for success messages,out.dict()for info,out.table()for bucket listing,out.confirm()for confirmations,out.hint()for hintsid_keyparam toout.dict()for quiet mode (consistent without.table())syncleft as-is (passes quiet/verbose to library)_list_filesand_list_bucketskeep their existing output format — thels-like flat table,-hfor human-readable sizes,--tree, and the json/quiet branches are preserved as-is. Only the flag changes (--quiet→--format quiet,--format table→--format auto). The existing output worked well and we didn't want to change it unnecessarily by routing everything throughout.table().Note
Medium Risk
Moderate risk because it changes CLI flags and stdout/stderr output formatting for multiple
hf bucketscommands, which may break user scripts relying on previous messages or--quietbehavior.Overview
Migrates
hf bucketscommands (create,list,info,delete,rm,move,cp) from ad-hoc printing and--quiet/--format table|jsonto the unifiedoutoutput framework with--format [auto|human|agent|json|quiet].Adds
id_keysupport toout.dict()to make--format quietprint a single identifier (used bybuckets info), routes bucket listing throughout.table()(including standardized empty-results messaging), and adjusts hints/confirmations/results accordingly; tests and generated CLI docs are updated to match the new outputs and flags.Reviewed by Cursor Bugbot for commit 387dcfe. Bugbot is set up for automated code reviews on this repo. Configure here.