Files
swift-hpa/Sources/PlaybookClient/PlaybookClient.swift

80 lines
2.2 KiB
Swift

import ConfigurationClient
import Dependencies
import DependenciesMacros
import FileClient
import Foundation
import ShellClient
// TODO: Add update checks and pull for the playbook.
public extension DependencyValues {
var playbookClient: PlaybookClient {
get { self[PlaybookClient.self] }
set { self[PlaybookClient.self] = newValue }
}
}
@DependencyClient
public struct PlaybookClient: Sendable {
// TODO: Remove the configuration and have it passed in.
public var installPlaybook: @Sendable (Configuration) async throws -> Void
public var playbookDirectory: @Sendable (Configuration) async throws -> String
}
extension PlaybookClient: DependencyKey {
public static let testValue: PlaybookClient = Self()
public static var liveValue: PlaybookClient {
.init {
try await install(config: $0.playbook)
} playbookDirectory: {
$0.playbook?.directory ?? Constants.defaultInstallationPath
}
}
}
private func install(config: Configuration.Playbook?) async throws {
@Dependency(\.fileClient) var fileClient
@Dependency(\.logger) var logger
@Dependency(\.asyncShellClient) var shell
let (path, version) = parsePlaybookPathAndVerion(config)
let parentDirectory = URL(filePath: path)
.deletingLastPathComponent()
let parentExists = try await fileClient.isDirectory(parentDirectory)
if !parentExists {
try await fileClient.createDirectory(parentDirectory)
}
let playbookExists = try await fileClient.isDirectory(URL(filePath: path))
if !playbookExists {
try await shell.foreground(.init([
"git", "clone",
"--branch", version,
PlaybookClient.Constants.playbookRepoUrl, path
]))
} else {
logger.debug("Playbook exists, ensuring it's up to date.")
try await shell.foreground(.init(
in: path,
["git", "pull", "--tags"]
))
try await shell.foreground(.init(
in: path,
["git", "checkout", version]
))
}
}
private func parsePlaybookPathAndVerion(_ configuration: Configuration.Playbook?) -> (path: String, version: String) {
return (
path: configuration?.directory ?? PlaybookClient.Constants.defaultInstallationPath,
version: configuration?.version ?? PlaybookClient.Constants.playbookRepoVersion
)
}