84 lines
2.6 KiB
Swift
84 lines
2.6 KiB
Swift
import Foundation
|
|
|
|
final class RemotePush: ObservableObject {
|
|
|
|
@Published
|
|
var isTransmittingToRemote = false
|
|
|
|
@Published
|
|
var lastPushWasSuccessful = true
|
|
|
|
func transmitToRemote(settings: GeneralSettings, outputFolder: String, outputHandler: @escaping (String) -> Void) {
|
|
guard !isTransmittingToRemote else { return }
|
|
DispatchQueue.main.async {
|
|
self.isTransmittingToRemote = true
|
|
}
|
|
DispatchQueue.global().async {
|
|
let success = self.transmit(
|
|
outputFolder: outputFolder,
|
|
remoteUser: settings.remoteUserForUpload,
|
|
remotePort: settings.remotePortForUpload,
|
|
remoteDomain: settings.url,
|
|
remotePath: settings.remotePathForUpload,
|
|
excludedItems: [".git"],
|
|
outputHandler: outputHandler)
|
|
DispatchQueue.main.async {
|
|
self.isTransmittingToRemote = false
|
|
self.lastPushWasSuccessful = success
|
|
}
|
|
}
|
|
}
|
|
|
|
private func transmit(
|
|
outputFolder: String,
|
|
remoteUser: String,
|
|
remotePort: Int,
|
|
remoteDomain: String,
|
|
remotePath: String,
|
|
excludedItems: [String],
|
|
outputHandler: @escaping (String) -> Void
|
|
) -> Bool {
|
|
let remoteDomain = remoteDomain.withHttpPrefixRemoved
|
|
let remotePath = remotePath.withLeadingSlash.withTrailingSlash
|
|
let outputFolder = outputFolder.withLeadingSlash.withTrailingSlash
|
|
|
|
let process = Process()
|
|
process.executableURL = URL(fileURLWithPath: "/bin/bash")
|
|
let arguments = [
|
|
"/opt/homebrew/bin/rsync",
|
|
"-hrutv",
|
|
"--info=progress2"]
|
|
+ excludedItems.reduce(into: []) { $0 += ["--exclude", $1] }
|
|
+ [
|
|
"-e", "\"/opt/homebrew/bin/ssh -p \(remotePort)\"",
|
|
outputFolder,
|
|
"\(remoteUser)@\(remoteDomain):\(remotePath)"
|
|
]
|
|
|
|
let argument = arguments.joined(separator: " ")
|
|
|
|
process.arguments = ["-c", argument]
|
|
|
|
let pipe = Pipe()
|
|
process.standardOutput = pipe
|
|
process.standardError = pipe
|
|
|
|
let fileHandle = pipe.fileHandleForReading
|
|
|
|
// Use a DispatchQueue to read output asynchronously
|
|
fileHandle.readabilityHandler = { fileHandle in
|
|
if let output = String(data: fileHandle.availableData, encoding: .utf8), !output.isEmpty {
|
|
outputHandler(output)
|
|
}
|
|
}
|
|
|
|
process.launch()
|
|
process.waitUntilExit()
|
|
|
|
if process.terminationStatus == 0 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
}
|