Support optional JSON output for config, list, lookup/info, outdated & search; improve tabular output#1230
Support optional JSON output for config, list, lookup/info, outdated & search; improve tabular output#1230rgoldberg wants to merge 3 commits intomas-cli:mainfrom
config, list, lookup/info, outdated & search; improve tabular output#1230Conversation
Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
ecf7ab1 to
b8c8eb5
Compare
…outdated` & `search`. Update `README.md`. Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
b8c8eb5 to
210425a
Compare
|
There was a problem hiding this comment.
Code Review
This pull request introduces native JSON output support for the list, outdated, search, lookup, and config commands. This is achieved through the integration of a new swift-json library and a Zsh wrapper script that uses jq and column for terminal formatting. The implementation includes a significant refactor of the CatalogApp and InstalledApp models to handle metadata key mapping and JSON serialization. Feedback highlights several performance and architectural concerns, including inefficient JSON re-parsing in the outdated command, high memory overhead from storing raw JSON strings in models, and potential performance degradation due to disk I/O during canonical path resolution. Additionally, the review points out the tight coupling created by using a magic file descriptor (FD 3) for communication between the binary and the wrapper script, and the bypass of terminal detection logic via hardcoded ANSI escape sequences.
| "(" + $version + " " * ($max_version_length - ($version | length)) + " -> " + .newVersion + ")" | ||
| ] | | ||
| join("\u001f") | ||
| ) catch ("\u001B[4;31mError:\u001B[0m Invalid data from mas: \(.)\n" | halt_error(1)) |
There was a problem hiding this comment.
| outdatedApps.compactMap { installedApp, newVersion in | ||
| do { | ||
| let newVersionKey = "newVersion" | ||
| var json = try JSON.Object(parsing: .init(describing: installedApp)) |
There was a problem hiding this comment.
Parsing the JSON string back into a JSON.Object just to insert a single field is inefficient, especially when processing a large list of outdated apps. Since InstalledApp already computes and stores its JSON representation, consider exposing the JSON.Object directly or providing a method to extend it without full re-parsing.
References
- Avoid unnecessary loops, iterations, or calculations. Identify performance bottlenecks and optimize for efficiency.
| var displayPrice: String { | ||
| formattedPrice ?? "?" | ||
| private let jsonObject: JSON.Object | ||
| private let json: String |
There was a problem hiding this comment.
| } | ||
|
|
||
| fileprivate init(for item: NSMetadataItem) { | ||
| let valueByAttribute = item.values(forAttributes: item.attributes + [NSMetadataItemPathKey]) ?? .init() |
There was a problem hiding this comment.
| return (try? URL(filePath: path, directoryHint: .isDirectory).resourceValues(forKeys: [.canonicalPathKey]))? | ||
| .canonicalPath // swiftformat:disable:this indent |



Support optional JSON output for
config,list,lookup/info,outdated&search; improve tabular output.Resolve #190
Resolve #412
Resolve #1091