From b44dcf31b0b092e7606441bd387c3aa7ed8155ae Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Fri, 20 Feb 2026 22:41:26 +0100 Subject: [PATCH] tart list: introduce "Accessed" field to show last accessed date of a VM --- Sources/tart/Commands/List.swift | 35 ++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/Sources/tart/Commands/List.swift b/Sources/tart/Commands/List.swift index c1a24b4..2af0317 100644 --- a/Sources/tart/Commands/List.swift +++ b/Sources/tart/Commands/List.swift @@ -8,6 +8,7 @@ fileprivate struct VMInfo: Encodable { let Disk: Int let Size: Int let SizeOnDisk: Int + let Accessed: String let Running: Bool let State: String } @@ -39,13 +40,31 @@ struct List: AsyncParsableCommand { if source == nil || source == "local" { infos += sortedInfos(try VMStorageLocal().list().map { (name, vmDir) in - try VMInfo(Source: "local", Name: name, Disk: vmDir.sizeGB(), Size: vmDir.allocatedSizeGB(), SizeOnDisk: vmDir.allocatedSizeGB() - vmDir.deduplicatedSizeGB(), Running: vmDir.running(), State: vmDir.state().rawValue) + try VMInfo( + Source: "local", + Name: name, + Disk: vmDir.sizeGB(), + Size: vmDir.allocatedSizeGB(), + SizeOnDisk: vmDir.allocatedSizeGB() - vmDir.deduplicatedSizeGB(), + Accessed: formatAccessDate(try vmDir.accessDate()), + Running: vmDir.running(), + State: vmDir.state().rawValue + ) }) } if source == nil || source == "oci" { infos += sortedInfos(try VMStorageOCI().list().map { (name, vmDir, _) in - try VMInfo(Source: "OCI", Name: name, Disk: vmDir.sizeGB(), Size: vmDir.allocatedSizeGB(), SizeOnDisk: vmDir.allocatedSizeGB() - vmDir.deduplicatedSizeGB(), Running: vmDir.running(), State: vmDir.state().rawValue) + try VMInfo( + Source: "OCI", + Name: name, + Disk: vmDir.sizeGB(), + Size: vmDir.allocatedSizeGB(), + SizeOnDisk: vmDir.allocatedSizeGB() - vmDir.deduplicatedSizeGB(), + Accessed: formatAccessDate(try vmDir.accessDate()), + Running: vmDir.running(), + State: vmDir.state().rawValue + ) }) } @@ -61,4 +80,16 @@ struct List: AsyncParsableCommand { private func sortedInfos(_ infos: [VMInfo]) -> [VMInfo] { infos.sorted(by: { left, right in left.Name < right.Name }) } + + private func formatAccessDate(_ accessDate: Date) -> String { + switch format { + case .text: + let formatter = RelativeDateTimeFormatter() + formatter.unitsStyle = .full + return formatter.localizedString(for: accessDate, relativeTo: Date()) + case .json: + let formatter = ISO8601DateFormatter() + return formatter.string(from: accessDate) + } + } }