79 lines
2.1 KiB
Swift
79 lines
2.1 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 {
|
|
|
|
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
|
|
)
|
|
}
|