Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions Sources/tart/Commands/Get.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ fileprivate struct VMInfo: Encodable {
let OS: OS
let CPU: Int
let Memory: UInt64
let Disk: Int
let Disk: HumanReadableByteCount
let DiskFormat: String
let Size: String
let Size: HumanReadableByteCount
let Display: String
let Running: Bool
let State: String
Expand All @@ -27,7 +27,20 @@ struct Get: AsyncParsableCommand {
let vmConfig = try VMConfig(fromURL: vmDir.configURL)
let memorySizeInMb = vmConfig.memorySize / 1024 / 1024

let info = VMInfo(OS: vmConfig.os, CPU: vmConfig.cpuCount, Memory: memorySizeInMb, Disk: try vmDir.sizeGB(), DiskFormat: vmConfig.diskFormat.rawValue, Size: String(format: "%.3f", Float(try vmDir.allocatedSizeBytes()) / 1000 / 1000 / 1000), Display: vmConfig.display.description, Running: try vmDir.running(), State: try vmDir.state().rawValue)
let info = VMInfo(
OS: vmConfig.os,
CPU: vmConfig.cpuCount,
Memory: memorySizeInMb,
Disk: HumanReadableByteCount(try vmDir.sizeBytes()) { $0 / 1000 / 1000 / 1000 },
DiskFormat: vmConfig.diskFormat.rawValue,
Size: HumanReadableByteCount(try vmDir.allocatedSizeBytes()) {
String(format: "%.3f", Float($0) / 1000 / 1000 / 1000)
},
Display: vmConfig.display.description,
Running: try vmDir.running(),
State: try vmDir.state().rawValue
)

print(format.renderSingle(info))
}
}
12 changes: 6 additions & 6 deletions Sources/tart/Commands/List.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import SwiftUI
fileprivate struct VMInfo: Encodable {
let Source: String
let Name: String
let Disk: Int
let Size: Int
let Disk: HumanReadableByteCount
let Size: HumanReadableByteCount
let Accessed: String
let Running: Bool
let State: String
Expand Down Expand Up @@ -42,8 +42,8 @@ struct List: AsyncParsableCommand {
try VMInfo(
Source: "local",
Name: name,
Disk: vmDir.sizeGB(),
Size: vmDir.allocatedSizeGB(),
Disk: HumanReadableByteCount(try vmDir.sizeBytes()) { $0 / 1000 / 1000 / 1000 },
Size: HumanReadableByteCount(try vmDir.allocatedSizeBytes()) { $0 / 1000 / 1000 / 1000 },
Accessed: formatAccessDate(try vmDir.accessDate()),
Running: vmDir.running(),
State: vmDir.state().rawValue
Expand All @@ -56,8 +56,8 @@ struct List: AsyncParsableCommand {
try VMInfo(
Source: "OCI",
Name: name,
Disk: vmDir.sizeGB(),
Size: vmDir.allocatedSizeGB(),
Disk: HumanReadableByteCount(try vmDir.sizeBytes()) { $0 / 1000 / 1000 / 1000 },
Size: HumanReadableByteCount(try vmDir.allocatedSizeBytes()) { $0 / 1000 / 1000 / 1000 },
Accessed: formatAccessDate(try vmDir.accessDate()),
Running: vmDir.running(),
State: vmDir.state().rawValue
Expand Down
26 changes: 26 additions & 0 deletions Sources/tart/Formatter/HumanReadableByteCount.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

struct HumanReadableByteCount: Encodable, CustomStringConvertible {
private let byteCount: Int
private let jsonValue: any Encodable

init<JSONValue: Encodable>(_ byteCount: Int, encodedAs: (Int) -> JSONValue) {
self.byteCount = byteCount
self.jsonValue = encodedAs(byteCount)
}

var description: String {
let formatter = MeasurementFormatter()
formatter.unitOptions = .naturalScale
formatter.unitStyle = .medium
formatter.numberFormatter.maximumFractionDigits = 0

return formatter.string(
from: Measurement(value: Double(byteCount), unit: UnitInformationStorage.bytes)
)
}

func encode(to encoder: Encoder) throws {
try jsonValue.encode(to: encoder)
}
}
15 changes: 15 additions & 0 deletions Tests/TartTests/HumanReadableByteCountTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation
import XCTest
@testable import tart

final class HumanReadableByteCountTests: XCTestCase {
func testTextAndJSONRepresentations() throws {
let integer = HumanReadableByteCount(51_400_000_000) { _ in 51 }
let string = HumanReadableByteCount(17_234_000_000) { _ in "17.234" }
let encoder = JSONEncoder()

XCTAssertEqual(string.description.compactMap(\.wholeNumberValue), [1, 7])
XCTAssertEqual(try JSONDecoder().decode(Int.self, from: encoder.encode(integer)), 51)
XCTAssertEqual(try JSONDecoder().decode(String.self, from: encoder.encode(string)), "17.234")
}
}