import CommandClient import ConfigurationClient import Dependencies import FileClient import Foundation import ShellClient extension PlaybookClient.Repository { static func findDirectory( configuration: Configuration? = nil ) async throws -> String { @Dependency(\.configurationClient) var configurationClient var configuration: Configuration! = configuration if configuration == nil { configuration = try await configurationClient.findAndLoad() } return configuration.playbook?.directory ?? PlaybookClient.Constants.defaultInstallationPath } static func installPlaybook( configuration: Configuration? ) async throws { @Dependency(\.commandClient) var commandClient @Dependency(\.configurationClient) var configurationClient @Dependency(\.fileClient) var fileClient @Dependency(\.logger) var logger var configuration: Configuration! = configuration if configuration == nil { configuration = try await configurationClient.findAndLoad() } let (path, version) = parsePlaybookPathAndVerion( configuration?.playbook ) 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 { logger.debug("Cloning playbook to: \(path)") try await commandClient.run( "git", "clone", "--branch", version, PlaybookClient.Constants.playbookRepoUrl, path ) } else { logger.debug("Playbook exists, ensuring it's up to date.") try await commandClient.run( in: path, "git", "pull", "--tags" ) try await commandClient.run( in: path, "git", "checkout", version ) } } static func parsePlaybookPathAndVerion( _ configuration: Configuration.Playbook? ) -> (path: String, version: String) { return ( path: configuration?.directory ?? PlaybookClient.Constants.defaultInstallationPath, version: configuration?.version ?? PlaybookClient.Constants.playbookRepoVersion ) } }