feat: Moves commands into cli-client module, adds tests, needs implemented in the executable.
This commit is contained in:
@@ -5,34 +5,25 @@ import FileClient
|
||||
import Foundation
|
||||
import ShellClient
|
||||
|
||||
public extension DependencyValues {
|
||||
var cliClient: CliClient {
|
||||
get { self[CliClient.self] }
|
||||
set { self[CliClient.self] = newValue }
|
||||
}
|
||||
}
|
||||
public extension CliClient {
|
||||
|
||||
@DependencyClient
|
||||
public struct CliClient: Sendable {
|
||||
public var runCommand: @Sendable ([String], Bool, ShellCommand.Shell) async throws -> Void
|
||||
|
||||
public func runCommand(
|
||||
func runCommand(
|
||||
quiet: Bool,
|
||||
shell: ShellCommand.Shell,
|
||||
_ args: [String]
|
||||
) async throws {
|
||||
try await runCommand(args, quiet, shell)
|
||||
try await runCommand(.init(arguments: args, quiet: quiet, shell: shell))
|
||||
}
|
||||
|
||||
public func runCommand(
|
||||
func runCommand(
|
||||
quiet: Bool,
|
||||
shell: ShellCommand.Shell,
|
||||
_ args: String...
|
||||
) async throws {
|
||||
try await runCommand(args, quiet, shell)
|
||||
try await runCommand(quiet: quiet, shell: shell, args)
|
||||
}
|
||||
|
||||
public func runPlaybookCommand(_ options: PlaybookOptions) async throws {
|
||||
func runPlaybookCommand(_ options: PlaybookOptions) async throws {
|
||||
@Dependency(\.configurationClient) var configurationClient
|
||||
@Dependency(\.logger) var logger
|
||||
|
||||
@@ -46,7 +37,7 @@ public struct CliClient: Sendable {
|
||||
let inventoryPath = ensuredInventoryPath(
|
||||
options.inventoryFilePath,
|
||||
configuration: configuration,
|
||||
playboodDirectory: playbookDirectory
|
||||
playbookDirectory: playbookDirectory
|
||||
)
|
||||
logger.trace("Inventory path: \(inventoryPath)")
|
||||
|
||||
@@ -72,7 +63,7 @@ public struct CliClient: Sendable {
|
||||
)
|
||||
}
|
||||
|
||||
public func runVaultCommand(_ options: VaultOptions) async throws {
|
||||
func runVaultCommand(_ options: VaultOptions) async throws {
|
||||
@Dependency(\.configurationClient) var configurationClient
|
||||
@Dependency(\.fileClient) var fileClient
|
||||
@Dependency(\.logger) var logger
|
||||
@@ -98,6 +89,10 @@ public struct CliClient: Sendable {
|
||||
arguments.append(contentsOf: ["--encrypt-vault-id", id])
|
||||
}
|
||||
|
||||
arguments.append(vaultFilePath)
|
||||
|
||||
logger.trace("Running vault command with arguments: \(arguments)")
|
||||
|
||||
try await runCommand(
|
||||
quiet: options.quiet,
|
||||
shell: options.shell.shellOrDefault,
|
||||
@@ -106,89 +101,6 @@ public struct CliClient: Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
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 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 { args, quiet, shell in
|
||||
@Dependency(\.asyncShellClient) var shellClient
|
||||
if !quiet {
|
||||
try await shellClient.foreground(.init(
|
||||
shell: shell,
|
||||
environment: ProcessInfo.processInfo.environment,
|
||||
in: nil,
|
||||
args
|
||||
))
|
||||
} else {
|
||||
try await shellClient.background(.init(
|
||||
shell: shell,
|
||||
environment: ProcessInfo.processInfo.environment,
|
||||
in: nil,
|
||||
args
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static var liveValue: CliClient {
|
||||
.live(env: ProcessInfo.processInfo.environment)
|
||||
}
|
||||
|
||||
public static let testValue: CliClient = Self()
|
||||
}
|
||||
|
||||
private extension ConfigurationClient {
|
||||
func ensuredConfiguration(_ optionalConfig: Configuration?) async throws -> Configuration {
|
||||
guard let config = optionalConfig else {
|
||||
@@ -222,11 +134,11 @@ private extension Optional where Wrapped == String {
|
||||
private func ensuredInventoryPath(
|
||||
_ optionalInventoryPath: String?,
|
||||
configuration: Configuration,
|
||||
playboodDirectory: String
|
||||
playbookDirectory: String
|
||||
) -> String {
|
||||
guard let path = optionalInventoryPath else {
|
||||
guard let path = configuration.playbook?.inventory else {
|
||||
return "\(playboodDirectory)/\(Constants.inventoryFileName)"
|
||||
return "\(playbookDirectory)/\(Constants.inventoryFileName)"
|
||||
}
|
||||
return path
|
||||
}
|
||||
@@ -250,3 +162,5 @@ enum CliClientError: Error {
|
||||
case playbookDirectoryNotFound
|
||||
case vaultFileNotFound
|
||||
}
|
||||
|
||||
extension ShellCommand.Shell: @retroactive @unchecked Sendable {}
|
||||
139
Sources/CliClient/Interface.swift
Normal file
139
Sources/CliClient/Interface.swift
Normal file
@@ -0,0 +1,139 @@
|
||||
import ConfigurationClient
|
||||
import Dependencies
|
||||
import DependenciesMacros
|
||||
import Foundation
|
||||
import ShellClient
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user