diff --git a/Sources/tart/Commands/Rename.swift b/Sources/tart/Commands/Rename.swift new file mode 100644 index 0000000..8caccfe --- /dev/null +++ b/Sources/tart/Commands/Rename.swift @@ -0,0 +1,40 @@ +import ArgumentParser +import Foundation + +struct Rename: AsyncParsableCommand { + static var configuration = CommandConfiguration(abstract: "Rename a VM") + + @Argument(help: "VM name") + var name: String + + @Argument(help: "new VM name") + var newName: String + + func validate() throws { + if newName.contains("/") { + throw ValidationError(" should be a local name") + } + } + + func run() async throws { + do { + let localStorage = VMStorageLocal() + + if !localStorage.exists(name) { + throw ValidationError("failed to rename a non-existent VM: \(name)") + } + + if localStorage.exists(newName) { + throw ValidationError("failed to rename VM \(name), target VM \(name) already exists, delete it first!") + } + + try localStorage.rename(name, newName) + + Foundation.exit(0) + } catch { + print(error) + + Foundation.exit(1) + } + } +} diff --git a/Sources/tart/Root.swift b/Sources/tart/Root.swift index 530afbd..ea55472 100644 --- a/Sources/tart/Root.swift +++ b/Sources/tart/Root.swift @@ -17,6 +17,7 @@ struct Root: AsyncParsableCommand { Pull.self, Push.self, Prune.self, + Rename.self, Delete.self, ]) diff --git a/Sources/tart/VMStorageLocal.swift b/Sources/tart/VMStorageLocal.swift index b94f942..811a33b 100644 --- a/Sources/tart/VMStorageLocal.swift +++ b/Sources/tart/VMStorageLocal.swift @@ -32,6 +32,10 @@ class VMStorageLocal { _ = try FileManager.default.replaceItemAt(vmURL(name), withItemAt: from.baseURL) } + func rename(_ name: String, _ newName: String) throws { + _ = try FileManager.default.replaceItemAt(vmURL(newName), withItemAt: vmURL(name)) + } + func delete(_ name: String) throws { try FileManager.default.removeItem(at: vmURL(name)) }