143 lines
3.4 KiB
Swift
143 lines
3.4 KiB
Swift
import ConfigurationClient
|
|
import Dependencies
|
|
import DependenciesMacros
|
|
import Foundation
|
|
import ShellClient
|
|
|
|
// TODO: Add logging options and setup in this module and remove from the
|
|
// executable `hpa` module.
|
|
|
|
public extension DependencyValues {
|
|
var cliClient: CliClient {
|
|
get { self[CliClient.self] }
|
|
set { self[CliClient.self] = newValue }
|
|
}
|
|
}
|
|
|
|
@DependencyClient
|
|
public struct CliClient: Sendable {
|
|
|
|
public var runCommand: @Sendable (RunCommandOptions) async throws -> Void
|
|
}
|
|
|
|
public extension CliClient {
|
|
struct PlaybookOptions: Sendable, Equatable {
|
|
let arguments: [String]
|
|
let configuration: Configuration?
|
|
let inventoryFilePath: String?
|
|
let playbookDirectory: String?
|
|
let quiet: Bool
|
|
let shell: String?
|
|
|
|
public init(
|
|
arguments: [String],
|
|
configuration: Configuration? = nil,
|
|
inventoryFilePath: String? = nil,
|
|
playbookDirectory: String? = nil,
|
|
quiet: Bool,
|
|
shell: String? = nil
|
|
) {
|
|
self.arguments = arguments
|
|
self.configuration = configuration
|
|
self.inventoryFilePath = inventoryFilePath
|
|
self.playbookDirectory = playbookDirectory
|
|
self.quiet = quiet
|
|
self.shell = shell
|
|
}
|
|
}
|
|
|
|
struct RunCommandOptions: Sendable, Equatable {
|
|
public let arguments: [String]
|
|
public let quiet: Bool
|
|
public let shell: ShellCommand.Shell
|
|
|
|
public init(
|
|
arguments: [String],
|
|
quiet: Bool,
|
|
shell: ShellCommand.Shell
|
|
) {
|
|
self.arguments = arguments
|
|
self.quiet = quiet
|
|
self.shell = shell
|
|
}
|
|
}
|
|
|
|
struct VaultOptions: Equatable, Sendable {
|
|
let arguments: [String]
|
|
let configuration: Configuration?
|
|
let quiet: Bool
|
|
let shell: String?
|
|
let vaultFilePath: String?
|
|
|
|
public init(
|
|
arguments: [String],
|
|
configuration: Configuration? = nil,
|
|
quiet: Bool,
|
|
shell: String?,
|
|
vaultFilePath: String? = nil
|
|
) {
|
|
self.arguments = arguments
|
|
self.configuration = configuration
|
|
self.quiet = quiet
|
|
self.shell = shell
|
|
self.vaultFilePath = vaultFilePath
|
|
}
|
|
}
|
|
}
|
|
|
|
extension CliClient: DependencyKey {
|
|
|
|
public static func live(
|
|
env: [String: String]
|
|
) -> Self {
|
|
@Dependency(\.logger) var logger
|
|
|
|
return .init { options in
|
|
@Dependency(\.asyncShellClient) var shellClient
|
|
if !options.quiet {
|
|
try await shellClient.foreground(.init(
|
|
shell: options.shell,
|
|
environment: ProcessInfo.processInfo.environment,
|
|
in: nil,
|
|
options.arguments
|
|
))
|
|
} else {
|
|
try await shellClient.background(.init(
|
|
shell: options.shell,
|
|
environment: ProcessInfo.processInfo.environment,
|
|
in: nil,
|
|
options.arguments
|
|
))
|
|
}
|
|
}
|
|
}
|
|
|
|
public static var liveValue: CliClient {
|
|
.live(env: ProcessInfo.processInfo.environment)
|
|
}
|
|
|
|
public static let testValue: CliClient = Self()
|
|
|
|
public static func capturing(_ client: CapturingClient) -> Self {
|
|
.init { options in
|
|
await client.set(options)
|
|
}
|
|
}
|
|
|
|
public actor CapturingClient: Sendable {
|
|
public private(set) var quiet: Bool?
|
|
public private(set) var shell: ShellCommand.Shell?
|
|
public private(set) var arguments: [String]?
|
|
|
|
public init() {}
|
|
|
|
public func set(
|
|
_ options: RunCommandOptions
|
|
) {
|
|
quiet = options.quiet
|
|
shell = options.shell
|
|
arguments = options.arguments
|
|
}
|
|
}
|
|
}
|