mirror of https://github.com/cirruslabs/tart.git
tart {list,get}: display humanized byte units (#1301)
This commit is contained in:
parent
160b7cd692
commit
a438e2d031
|
|
@ -5,9 +5,9 @@ fileprivate struct VMInfo: Encodable {
|
||||||
let OS: OS
|
let OS: OS
|
||||||
let CPU: Int
|
let CPU: Int
|
||||||
let Memory: UInt64
|
let Memory: UInt64
|
||||||
let Disk: Int
|
let Disk: HumanReadableByteCount
|
||||||
let DiskFormat: String
|
let DiskFormat: String
|
||||||
let Size: String
|
let Size: HumanReadableByteCount
|
||||||
let Display: String
|
let Display: String
|
||||||
let Running: Bool
|
let Running: Bool
|
||||||
let State: String
|
let State: String
|
||||||
|
|
@ -27,7 +27,20 @@ struct Get: AsyncParsableCommand {
|
||||||
let vmConfig = try VMConfig(fromURL: vmDir.configURL)
|
let vmConfig = try VMConfig(fromURL: vmDir.configURL)
|
||||||
let memorySizeInMb = vmConfig.memorySize / 1024 / 1024
|
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))
|
print(format.renderSingle(info))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import SwiftUI
|
||||||
fileprivate struct VMInfo: Encodable {
|
fileprivate struct VMInfo: Encodable {
|
||||||
let Source: String
|
let Source: String
|
||||||
let Name: String
|
let Name: String
|
||||||
let Disk: Int
|
let Disk: HumanReadableByteCount
|
||||||
let Size: Int
|
let Size: HumanReadableByteCount
|
||||||
let Accessed: String
|
let Accessed: String
|
||||||
let Running: Bool
|
let Running: Bool
|
||||||
let State: String
|
let State: String
|
||||||
|
|
@ -42,8 +42,8 @@ struct List: AsyncParsableCommand {
|
||||||
try VMInfo(
|
try VMInfo(
|
||||||
Source: "local",
|
Source: "local",
|
||||||
Name: name,
|
Name: name,
|
||||||
Disk: vmDir.sizeGB(),
|
Disk: HumanReadableByteCount(try vmDir.sizeBytes()) { $0 / 1000 / 1000 / 1000 },
|
||||||
Size: vmDir.allocatedSizeGB(),
|
Size: HumanReadableByteCount(try vmDir.allocatedSizeBytes()) { $0 / 1000 / 1000 / 1000 },
|
||||||
Accessed: formatAccessDate(try vmDir.accessDate()),
|
Accessed: formatAccessDate(try vmDir.accessDate()),
|
||||||
Running: vmDir.running(),
|
Running: vmDir.running(),
|
||||||
State: vmDir.state().rawValue
|
State: vmDir.state().rawValue
|
||||||
|
|
@ -56,8 +56,8 @@ struct List: AsyncParsableCommand {
|
||||||
try VMInfo(
|
try VMInfo(
|
||||||
Source: "OCI",
|
Source: "OCI",
|
||||||
Name: name,
|
Name: name,
|
||||||
Disk: vmDir.sizeGB(),
|
Disk: HumanReadableByteCount(try vmDir.sizeBytes()) { $0 / 1000 / 1000 / 1000 },
|
||||||
Size: vmDir.allocatedSizeGB(),
|
Size: HumanReadableByteCount(try vmDir.allocatedSizeBytes()) { $0 / 1000 / 1000 / 1000 },
|
||||||
Accessed: formatAccessDate(try vmDir.accessDate()),
|
Accessed: formatAccessDate(try vmDir.accessDate()),
|
||||||
Running: vmDir.running(),
|
Running: vmDir.running(),
|
||||||
State: vmDir.state().rawValue
|
State: vmDir.state().rawValue
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue