From d9e91538fb0082a1093297934d88d7666920ebd9 Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Wed, 11 Dec 2024 17:03:43 -0500 Subject: [PATCH] feat: Adds more tests for cli-client. --- Sources/CliClient/CliClient+Commands.swift | 22 +++-- .../ConfigurationClient/Configuration.swift | 93 ------------------- Tests/CliClientTests/CliClientTests.swift | 67 ++++++++++++- 3 files changed, 79 insertions(+), 103 deletions(-) diff --git a/Sources/CliClient/CliClient+Commands.swift b/Sources/CliClient/CliClient+Commands.swift index 078c993..115ae43 100644 --- a/Sources/CliClient/CliClient+Commands.swift +++ b/Sources/CliClient/CliClient+Commands.swift @@ -58,7 +58,7 @@ public extension CliClient { try await runCommand( quiet: options.quiet, - shell: options.shell.shellOrDefault, + shell: options.shell.orDefault, arguments ) } @@ -95,13 +95,14 @@ public extension CliClient { try await runCommand( quiet: options.quiet, - shell: options.shell.shellOrDefault, + shell: options.shell.orDefault, arguments ) } } -private extension ConfigurationClient { +@_spi(Internal) +public extension ConfigurationClient { func ensuredConfiguration(_ optionalConfig: Configuration?) async throws -> Configuration { guard let config = optionalConfig else { return try await findAndLoad() @@ -110,7 +111,8 @@ private extension ConfigurationClient { } } -private extension Configuration { +@_spi(Internal) +public extension Configuration { func ensuredPlaybookDirectory(_ optionalDirectory: String?) throws -> String { guard let directory = optionalDirectory else { @@ -123,15 +125,16 @@ private extension Configuration { } } -private extension Optional where Wrapped == String { - - var shellOrDefault: ShellCommand.Shell { +@_spi(Internal) +public extension Optional where Wrapped == String { + var orDefault: ShellCommand.Shell { guard let shell = self else { return .zsh(useDashC: true) } return .custom(path: shell, useDashC: true) } } -private func ensuredInventoryPath( +@_spi(Internal) +public func ensuredInventoryPath( _ optionalInventoryPath: String?, configuration: Configuration, playbookDirectory: String @@ -145,7 +148,8 @@ private func ensuredInventoryPath( return path } -private extension FileClient { +@_spi(Internal) +public extension FileClient { func ensuredVaultFilePath(_ optionalPath: String?) async throws -> String { guard let path = optionalPath else { diff --git a/Sources/ConfigurationClient/Configuration.swift b/Sources/ConfigurationClient/Configuration.swift index 5840c07..6ab0a6e 100644 --- a/Sources/ConfigurationClient/Configuration.swift +++ b/Sources/ConfigurationClient/Configuration.swift @@ -93,96 +93,3 @@ public struct Configuration: Codable, Equatable, Sendable { } } } - -// public struct Configuration: Codable, Equatable, Sendable { -// -// public let playbookDir: String? -// public let inventoryPath: String? -// public let templateRepo: String? -// public let templateRepoVersion: String? -// public let templateDir: String? -// public let defaultPlaybookArgs: [String]? -// public let defaultVaultArgs: [String]? -// public let defaultVaultEncryptId: String? -// -// fileprivate enum CodingKeys: String, CodingKey { -// case playbookDir = "HPA_PLAYBOOK_DIR" -// case inventoryPath = "HPA_DEFAULT_INVENTORY" -// case templateRepo = "HPA_TEMPLATE_REPO" -// case templateRepoVersion = "HPA_TEMPLATE_VERSION" -// case templateDir = "HPA_TEMPLATE_DIR" -// case defaultPlaybookArgs = "HPA_DEFAULT_PLAYBOOK_ARGS" -// case defaultVaultArgs = "HPA_DEFAULT_VAULT_ARGS" -// case defaultVaultEncryptId = "HPA_DEFAULT_VAULT_ENCRYPT_ID" -// } -// -// public static func fromEnv( -// _ env: [String: String] -// ) throws -> Self { -// @Dependency(\.logger) var logger -// -// logger.trace("Creating configuration from env...") -// -// let hpaValues: [String: String] = env.filter { $0.key.contains("HPA") } -// logger.debug("HPA env vars: \(hpaValues)") -// -// return Configuration( -// playbookDir: hpaValues.value(for: .playbookDir), -// inventoryPath: hpaValues.value(for: .inventoryPath), -// templateRepo: hpaValues.value(for: .templateRepo), -// templateRepoVersion: hpaValues.value(for: .templateRepoVersion), -// templateDir: hpaValues.value(for: .templateDir), -// defaultPlaybookArgs: hpaValues.array(for: .defaultPlaybookArgs), -// defaultVaultArgs: hpaValues.array(for: .defaultVaultArgs), -// defaultVaultEncryptId: hpaValues.value(for: .defaultVaultEncryptId) -// ) -// } -// -// static var mock: Self { -// .init( -// playbookDir: "/path/to/playbook", -// inventoryPath: "/path/to/inventory.ini", -// templateRepo: "https://git.example.com/consult-template.git", -// templateRepoVersion: "main", -// templateDir: "/path/to/local/template", -// defaultPlaybookArgs: ["--tags", "debug"], -// defaultVaultArgs: ["--vault-id=myId@$SCRIPTS/vault-gopass-client"], -// defaultVaultEncryptId: "myId" -// ) -// } -// -// static var fileTemplate: String { -// """ -// # vi: ft=sh -// -// # Example configuration, uncomment the lines and set the values appropriate for your -// # usage. -// -// # Set this to the location of the ansible-hpa-playbook on your local machine. -// #HPA_PLAYBOOK_DIR="/path/to/ansible-hpa-playbook" -// -// # Set this to the location of a template repository, which is used to create new assessment projects. -// #HPA_TEMPLATE_REPO="https://git.example.com/your/template.git" -// -// # Specify a branch, version, or sha of the template repository. -// #HPA_TEMPLATE_VERSION="main" # branch, version, or sha -// -// # Set this to a location of a template directory to use to create new projects. -// #HPA_TEMPLATE_DIR="/path/to/local/template" -// -// # Extra arguments that get passed directly to the ansible-playbook command. -// #HPA_DEFAULT_PLAYBOOK_ARGS="--vault-id=consults@$SCRIPTS/vault-gopass-client" -// -// """ -// } -// } -// -// extension [String: String] { -// fileprivate func value(for codingKey: Configuration.CodingKeys) -> String? { -// self[codingKey.rawValue] -// } -// -// fileprivate func array(for codingKey: Configuration.CodingKeys) -> [String]? { -// value(for: codingKey).flatMap { $0.split(separator: ",").map(String.init) } -// } -// } diff --git a/Tests/CliClientTests/CliClientTests.swift b/Tests/CliClientTests/CliClientTests.swift index 310af56..e3f75e0 100644 --- a/Tests/CliClientTests/CliClientTests.swift +++ b/Tests/CliClientTests/CliClientTests.swift @@ -1,6 +1,7 @@ -import CliClient +@_spi(Internal) import CliClient import ConfigurationClient import Dependencies +import FileClient import Foundation import ShellClient import Testing @@ -91,6 +92,70 @@ struct CliClientTests: TestCase { } } + @Test + func ensuredPlaybookDirectory() throws { + let configuration = Configuration.mock + let playbookDir = try configuration.ensuredPlaybookDirectory("playbook") + #expect(playbookDir == "playbook") + + do { + _ = try configuration.ensuredPlaybookDirectory(nil) + #expect(Bool(false)) + } catch { + #expect(Bool(true)) + } + } + + @Test + func shellOrDefault() { + var shell: String? = "/bin/bash" + #expect(shell.orDefault == .custom(path: "/bin/bash", useDashC: true)) + + shell = nil + #expect(shell.orDefault == .zsh(useDashC: true)) + } + + @Test + func testEnsuredInventoryPath() { + let configuration = Configuration(playbook: .init(inventory: "inventory.ini")) + let playbookDir = "playbook" + let inventoryPath = "inventory.ini" + + var output = ensuredInventoryPath( + inventoryPath, + configuration: configuration, + playbookDirectory: playbookDir + ) + + #expect(output == "inventory.ini") + + output = ensuredInventoryPath( + nil, + configuration: configuration, + playbookDirectory: playbookDir + ) + #expect(output == "inventory.ini") + } + + @Test + func vaultFilePath() async throws { + var fileClient = FileClient.testValue + fileClient.findVaultFileInCurrentDirectory = { URL(string: "vault.yml") } + + var output = try await fileClient.ensuredVaultFilePath("vault.yml") + #expect(output == "vault.yml") + + output = try await fileClient.ensuredVaultFilePath(nil) + + fileClient.findVaultFileInCurrentDirectory = { nil } + do { + _ = try await fileClient.ensuredVaultFilePath(nil) + #expect(Bool(false)) + } catch { + #expect(Bool(true)) + } + } + func withMockConfiguration( _ capturing: CliClient.CapturingClient, configuration: Configuration = .mock,