Skip to content

Commit e20aca8

Browse files
authored
Normalize JSON output for network and volume resources. (apple#1624)
Normalize JSON output for network and volume resources. (apple#1624) - Reworks both JSON output presets to use sorted keys, ISO timestamps. `compact` is used for `ls` output, and `pretty` is used for `inspect`. - Extracts non-DRY option configuration into presets. - Closes apple#1623.
1 parent 34cff59 commit e20aca8

19 files changed

Lines changed: 207 additions & 60 deletions

File tree

Sources/APIServer/APIServer+Start.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ extension APIServer {
8080
await containersService.setNetworksService(networkService)
8181
initializeHealthCheckService(log: log, routes: &routes)
8282
try initializeKernelService(log: log, routes: &routes)
83-
let volumesService = try initializeVolumeService(containersService: containersService, log: log, routes: &routes)
83+
let volumesService = try await initializeVolumeService(containersService: containersService, log: log, routes: &routes)
8484
try initializeDiskUsageService(
8585
containersService: containersService,
8686
volumesService: volumesService,
@@ -359,11 +359,11 @@ extension APIServer {
359359
containersService: ContainersService,
360360
log: Logger,
361361
routes: inout [XPCRoute: XPCServer.RouteHandler]
362-
) throws -> VolumesService {
362+
) async throws -> VolumesService {
363363
log.info("initializing volume service")
364364

365365
let resourceRoot = appRoot.appending(FilePath.Component("volumes"))
366-
let service = try VolumesService(resourceRoot: resourceRoot, containersService: containersService, log: log)
366+
let service = try await VolumesService(resourceRoot: resourceRoot, containersService: containersService, log: log)
367367
let harness = VolumesHarness(service: service, log: log)
368368

369369
routes[XPCRoute.volumeCreate] = XPCServer.route(harness.create)

Sources/ContainerCommands/Container/ContainerInspect.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ extension Application {
5050
)
5151
}
5252

53-
try Output.emit(Output.renderJSON(containers.map { PrintableContainer($0) }))
53+
try Output.emit(Output.renderJSON(containers.map { PrintableContainer($0) }, options: .pretty))
5454
}
5555
}
5656
}

Sources/ContainerCommands/Image/ImageInspect.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,7 @@ extension Application {
6363
printable.append(ImageResource(config: image.description, index: resolved.index, manifests: resolved.manifests))
6464
}
6565

66-
let options = JSONOptions(
67-
outputFormatting: [.prettyPrinted, .sortedKeys],
68-
dateEncodingStrategy: .iso8601
69-
)
70-
try Output.emit(Output.renderJSON(printable, options: options))
66+
try Output.emit(Output.renderJSON(printable, options: .pretty))
7167
}
7268
}
7369
}

Sources/ContainerCommands/Image/ImageList.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ extension Application {
9999
}
100100

101101
private static func emitJSON(resources: [ImageResource]) throws {
102-
let options = JSONOptions(dateEncodingStrategy: .iso8601)
103-
try Output.emit(Output.renderJSON(resources, options: options))
102+
try Output.emit(Output.renderJSON(resources, options: .compact))
104103
}
105104
}
106105
}

Sources/ContainerCommands/Network/NetworkInspect.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extension Application {
4747
)
4848
}
4949

50-
try Output.emit(Output.renderJSON(items))
50+
try Output.emit(Output.renderJSON(items, options: .pretty))
5151
}
5252
}
5353
}

Sources/ContainerCommands/OutputRendering.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public struct JSONOptions: Sendable {
2323
public var outputFormatting: JSONEncoder.OutputFormatting = []
2424
public var dateEncodingStrategy: JSONEncoder.DateEncodingStrategy = .deferredToDate
2525

26-
public static let compact = JSONOptions()
27-
public static let prettySorted = JSONOptions(outputFormatting: [.prettyPrinted, .sortedKeys])
26+
public static let compact = JSONOptions(outputFormatting: [.sortedKeys], dateEncodingStrategy: .iso8601)
27+
public static let pretty = JSONOptions(outputFormatting: [.prettyPrinted, .sortedKeys], dateEncodingStrategy: .iso8601)
2828

2929
public init(
3030
outputFormatting: JSONEncoder.OutputFormatting = [],
@@ -85,10 +85,10 @@ public enum Output {
8585
/// The JSON and display models may be the same type (e.g., `PrintableContainer`)
8686
/// or different types.
8787
public static func render<J: Encodable, D: ListDisplayable>(
88-
json: J, display: [D], format: ListFormat, quiet: Bool
88+
json: J, display: [D], format: ListFormat, quiet: Bool, jsonOptions: JSONOptions = .compact
8989
) throws {
9090
switch format {
91-
case .json: try emit(renderJSON(json))
91+
case .json: try emit(renderJSON(json, options: jsonOptions))
9292
case .yaml: try emit(renderYAML(json))
9393
case .table: emit(renderList(display, quiet: quiet))
9494
case .toml: try emit(renderTOML(json))

Sources/ContainerCommands/System/SystemDF.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ extension Application {
3737
let stats = try await ClientDiskUsage.get()
3838

3939
if format == .json {
40-
try Output.emit(Output.renderJSON(stats, options: .prettySorted))
40+
try Output.emit(Output.renderJSON(stats, options: .pretty))
4141
return
4242
}
4343

Sources/ContainerCommands/Volume/VolumeInspect.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extension Application.VolumeCommand {
3838
public func run() async throws {
3939
let uniqueNames = Set(names)
4040
let volumes = try await ClientVolume.list().filter { uniqueNames.contains($0.id) }
41-
let volumeResources = volumes.map { VolumeResource(config: $0) }
41+
let volumeResources = volumes.map { VolumeResource(configuration: $0) }
4242

4343
if volumes.count != uniqueNames.count {
4444
let found = Set(volumes.map { $0.id })
@@ -49,11 +49,7 @@ extension Application.VolumeCommand {
4949
)
5050
}
5151

52-
let options = JSONOptions(
53-
outputFormatting: [.prettyPrinted, .sortedKeys],
54-
dateEncodingStrategy: .iso8601
55-
)
56-
try Output.emit(Output.renderJSON(volumeResources, options: options))
52+
try Output.emit(Output.renderJSON(volumeResources, options: .pretty))
5753
}
5854
}
5955
}

Sources/ContainerCommands/Volume/VolumeList.swift

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,7 @@ extension Application.VolumeCommand {
4141

4242
public func run() async throws {
4343
let volumes = try await ClientVolume.list()
44-
let volumeResources = volumes.map { VolumeResource(config: $0) }
45-
46-
if format == .json {
47-
let options = JSONOptions(dateEncodingStrategy: .iso8601)
48-
try Output.emit(Output.renderJSON(volumeResources, options: options))
49-
return
50-
}
51-
44+
let volumeResources = volumes.map { VolumeResource(configuration: $0) }
5245
try Output.render(json: volumeResources, display: volumeResources, format: format, quiet: quiet)
5346
}
5447
}

Sources/ContainerCommands/Volume/VolumeResource+ListDisplayable.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ extension VolumeResource: ListDisplayable {
2525
[
2626
name,
2727
isAnonymous ? "anonymous" : "named",
28-
config.driver,
29-
config.options.isEmpty ? "" : config.options.sorted(by: { $0.key < $1.key }).map { "\($0.key)=\($0.value)" }.joined(separator: ","),
28+
configuration.driver,
29+
configuration.options.isEmpty ? "" : configuration.options.sorted(by: { $0.key < $1.key }).map { "\($0.key)=\($0.value)" }.joined(separator: ","),
3030
]
3131
}
3232

0 commit comments

Comments
 (0)