diff --git a/Sources/CliClient/Constants.swift b/Sources/CliClient/Constants.swift index d000029..7e179f9 100644 --- a/Sources/CliClient/Constants.swift +++ b/Sources/CliClient/Constants.swift @@ -1,4 +1,5 @@ enum Constants { + static let executableName = "hpa" static let playbookCommand = "ansible-playbook" static let playbookFileName = "main.yml" static let inventoryFileName = "inventory.ini" diff --git a/Sources/CliClient/Interface.swift b/Sources/CliClient/Interface.swift index 9979ce9..19efbba 100644 --- a/Sources/CliClient/Interface.swift +++ b/Sources/CliClient/Interface.swift @@ -4,6 +4,9 @@ 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] } diff --git a/Sources/hpa/BuildCommand.swift b/Sources/hpa/BuildCommand.swift index e278848..2252e1f 100644 --- a/Sources/hpa/BuildCommand.swift +++ b/Sources/hpa/BuildCommand.swift @@ -26,12 +26,30 @@ struct BuildCommand: AsyncParsableCommand { var extraArgs: [String] = [] mutating func run() async throws { - try await runPlaybook( - commandName: Self.commandName, - globals: globals, - extraArgs: extraArgs, - "--tags", "build-project", - "--extra-vars", "project_dir=\(projectDir)" - ) + try await _run() + +// try await runPlaybook( +// commandName: Self.commandName, +// globals: globals, +// extraArgs: extraArgs, +// "--tags", "build-project", +// "--extra-vars", "project_dir=\(projectDir)" +// ) + } + + private func _run() async throws { + try await withSetupLogger(commandName: Self.commandName, globals: globals) { + @Dependency(\.cliClient) var cliClient + + try await cliClient.runPlaybookCommand( + globals.playbookOptions( + arguments: [ + "--tags", "build-project", + "--extra-vars", "project_dir=\(self.projectDir)" + ], + configuration: nil + ) + ) + } } } diff --git a/Sources/hpa/CreateCommand.swift b/Sources/hpa/CreateCommand.swift index ce36657..13c5bdc 100644 --- a/Sources/hpa/CreateCommand.swift +++ b/Sources/hpa/CreateCommand.swift @@ -86,15 +86,28 @@ struct CreateCommand: AsyncParsableCommand { logger.debug("JSON string: \(jsonString)") - try await runPlaybook( - commandName: Self.commandName, - globals: self.globals, - configuration: configuration, - extraArgs: extraArgs, + let arguments = [ "--tags", "setup-project", "--extra-vars", "project_dir=\(self.projectDir)", "--extra-vars", "'\(jsonString)'" + ] + extraArgs + + try await cliClient.runPlaybookCommand( + globals.playbookOptions( + arguments: arguments, + configuration: configuration + ) ) + +// try await runPlaybook( +// commandName: Self.commandName, +// globals: self.globals, +// configuration: configuration, +// extraArgs: extraArgs, +// "--tags", "setup-project", +// "--extra-vars", "project_dir=\(self.projectDir)", +// "--extra-vars", "'\(jsonString)'" +// ) } } } diff --git a/Sources/hpa/Internal/LoggingExtensions.swift b/Sources/hpa/Internal/LoggingExtensions.swift index d749bad..1835682 100644 --- a/Sources/hpa/Internal/LoggingExtensions.swift +++ b/Sources/hpa/Internal/LoggingExtensions.swift @@ -1,6 +1,7 @@ import Dependencies import Logging +// TODO: Move some of this to the cli-client module. extension Logger.Level { /// Set the log level based on the user's options supplied. diff --git a/Sources/hpa/Internal/PlaybookOptions+Globals.swift b/Sources/hpa/Internal/PlaybookOptions+Globals.swift new file mode 100644 index 0000000..7969884 --- /dev/null +++ b/Sources/hpa/Internal/PlaybookOptions+Globals.swift @@ -0,0 +1,19 @@ +import CliClient +import ConfigurationClient + +extension GlobalOptions { + + func playbookOptions( + arguments: [String], + configuration: Configuration? + ) -> CliClient.PlaybookOptions { + .init( + arguments: arguments, + configuration: configuration, + inventoryFilePath: inventoryPath, + playbookDirectory: playbookDir, + quiet: quietOnlyPlaybook ? true : basic.quiet, + shell: basic.shell + ) + } +} diff --git a/Sources/hpa/Internal/RunPlaybook.swift b/Sources/hpa/Internal/RunPlaybook.swift deleted file mode 100644 index d3398ea..0000000 --- a/Sources/hpa/Internal/RunPlaybook.swift +++ /dev/null @@ -1,101 +0,0 @@ -import ArgumentParser -import CliClient -import ConfigurationClient -import Dependencies -import Foundation -import Logging -import Rainbow -import ShellClient - -func runPlaybook( - commandName: String, - globals: GlobalOptions, - configuration: Configuration? = nil, - extraArgs: [String], - _ args: [String] -) async throws { - try await withSetupLogger(commandName: commandName, globals: globals) { - @Dependency(\.cliClient) var cliClient - @Dependency(\.configurationClient) var configurationClient - @Dependency(\.logger) var logger - - logger.debug("Begin run playbook: \(globals)") - - let configuration = try await configurationClient.findAndLoad() - - logger.debug("Configuration: \(configuration)") - - let playbookDir = try ensureString( - globals: globals, - configuration: configuration, - globalsKeyPath: \.playbookDir, - configurationKeyPath: \.playbook?.directory - ) - let playbook = "\(playbookDir)/\(Constants.playbookFileName)" - - let inventory = (try? ensureString( - globals: globals, - configuration: configuration, - globalsKeyPath: \.inventoryPath, - configurationKeyPath: \.playbook?.inventory - )) ?? "\(playbookDir)/\(Constants.inventoryFileName)" - - let defaultArgs = (configuration.args ?? []) - + (configuration.useVaultArgs ? configuration.vault.args ?? [] : []) - - try await cliClient.runCommand( - quiet: globals.quietOnlyPlaybook ? true : globals.quiet, - shell: globals.shellOrDefault, - [ - "ansible-playbook", playbook, - "--inventory", inventory - ] + args - + extraArgs - + defaultArgs - ) - } -} - -func runPlaybook( - commandName: String, - globals: GlobalOptions, - configuration: Configuration? = nil, - extraArgs: [String], - _ args: String... -) async throws { - try await runPlaybook( - commandName: commandName, - globals: globals, - configuration: configuration, - extraArgs: extraArgs, - args - ) -} - -extension BasicGlobalOptions { - - var shellOrDefault: ShellCommand.Shell { - guard let shell else { return .zsh(useDashC: true) } - return .custom(path: shell, useDashC: true) - } -} - -func ensureString( - globals: GlobalOptions, - configuration: Configuration, - globalsKeyPath: KeyPath, - configurationKeyPath: KeyPath -) throws -> String { - if let global = globals[keyPath: globalsKeyPath] { - return global - } - guard let configuration = configuration[keyPath: configurationKeyPath] else { - throw RunPlaybookError.playbookNotFound - } - return configuration -} - -enum RunPlaybookError: Error { - case playbookNotFound - case configurationError -} diff --git a/Sources/hpa/Internal/RunVault.swift b/Sources/hpa/Internal/RunVault.swift deleted file mode 100644 index c2acef8..0000000 --- a/Sources/hpa/Internal/RunVault.swift +++ /dev/null @@ -1,57 +0,0 @@ -import ConfigurationClient -import Dependencies -import FileClient -import ShellClient - -func runVault( - commandName: String, - options: VaultOptions, - _ args: [String] -) async throws { - try await withSetupLogger(commandName: commandName, globals: options.globals) { - @Dependency(\.cliClient) var cliClient - @Dependency(\.configurationClient) var configurationClient - @Dependency(\.fileClient) var fileClient - @Dependency(\.logger) var logger - - logger.debug("Begin run vault: \(options)") - - let configuration = try await configurationClient.findAndLoad() - logger.debug("Configuration: \(configuration)") - - let path: String - if let file = options.file { - path = file - } else { - guard let url = try await fileClient.findVaultFileInCurrentDirectory() else { - throw VaultFileNotFound() - } - path = url.cleanFilePath - } - - logger.debug("Vault path: \(path)") - - let defaultArgs = configuration.vault.args ?? [] - - var vaultArgs = ["ansible-vault"] - + args - + defaultArgs - + options.extraArgs - + [path] - - if args.contains("encrypt"), - !vaultArgs.contains("--encrypt-vault-id"), - let id = configuration.vault.encryptId - { - vaultArgs.append(contentsOf: ["--encrypt-vault-id", id]) - } - - try await cliClient.runCommand( - quiet: options.quiet, - shell: options.shellOrDefault, - vaultArgs - ) - } -} - -struct VaultFileNotFound: Error {} diff --git a/Sources/hpa/Internal/VaultOptions+Globals.swift b/Sources/hpa/Internal/VaultOptions+Globals.swift new file mode 100644 index 0000000..35d7298 --- /dev/null +++ b/Sources/hpa/Internal/VaultOptions+Globals.swift @@ -0,0 +1,18 @@ +import CliClient +import ConfigurationClient + +extension VaultOptions { + + func vaultOptions( + arguments: [String], + configuration: Configuration? + ) -> CliClient.VaultOptions { + .init( + arguments: arguments, + configuration: configuration, + quiet: globals.quiet, + shell: globals.shell, + vaultFilePath: file + ) + } +} diff --git a/Sources/hpa/UtilsCommands/CreateTemplateCommand.swift b/Sources/hpa/UtilsCommands/CreateTemplateCommand.swift index 47beba9..86f4e72 100644 --- a/Sources/hpa/UtilsCommands/CreateTemplateCommand.swift +++ b/Sources/hpa/UtilsCommands/CreateTemplateCommand.swift @@ -36,6 +36,7 @@ struct GenerateProjectTemplateCommand: AsyncParsableCommand { ) var extraArgs: [String] = [] + // FIX: mutating func run() async throws { let varsDir = templateVars != nil ? ["--extra-vars", "repo_vars_dir=\(templateVars!)"] @@ -43,15 +44,15 @@ struct GenerateProjectTemplateCommand: AsyncParsableCommand { let vault = noVault ? ["--extra-vars", "use_vault=false"] : [] - try await runPlaybook( - commandName: Self.commandName, - globals: globals, - extraArgs: extraArgs, - [ - "--tags", "repo-template", - "--extra-vars", "output_dir=\(path)" - ] + varsDir - + vault - ) +// try await runPlaybook( +// commandName: Self.commandName, +// globals: globals, +// extraArgs: extraArgs, +// [ +// "--tags", "repo-template", +// "--extra-vars", "output_dir=\(path)" +// ] + varsDir +// + vault +// ) } } diff --git a/Sources/hpa/UtilsCommands/GenerateConfigCommand.swift b/Sources/hpa/UtilsCommands/GenerateConfigCommand.swift index 2a304b7..81e2eba 100644 --- a/Sources/hpa/UtilsCommands/GenerateConfigCommand.swift +++ b/Sources/hpa/UtilsCommands/GenerateConfigCommand.swift @@ -55,17 +55,17 @@ struct GenerateConfigurationCommand: AsyncParsableCommand { let actualPath: String - if let path { - actualPath = "\(path)/config" - } else { - let path = "~/.config/hpa-playbook/" - try await cliClient.runCommand( - quiet: false, - shell: globals.shellOrDefault, - "mkdir", "-p", path - ) - actualPath = "\(path)/config" - } +// if let path { +// actualPath = "\(path)/config" +// } else { +// let path = "~/.config/hpa-playbook/" +// try await cliClient.runCommand( +// quiet: false, +// shell: globals.shellOrDefault, +// "mkdir", "-p", path +// ) +// actualPath = "\(path)/config" +// } fatalError() // try cliClient.createConfiguration(actualPath, json) diff --git a/Sources/hpa/VaultCommands/DecryptCommand.swift b/Sources/hpa/VaultCommands/DecryptCommand.swift index 95c8124..2cc9aea 100644 --- a/Sources/hpa/VaultCommands/DecryptCommand.swift +++ b/Sources/hpa/VaultCommands/DecryptCommand.swift @@ -1,4 +1,6 @@ import ArgumentParser +import CliClient +import Dependencies struct DecryptCommand: AsyncParsableCommand { @@ -17,15 +19,23 @@ struct DecryptCommand: AsyncParsableCommand { ) var output: String? + // FIX: mutating func run() async throws { + @Dependency(\.cliClient) var cliClient + var args = ["decrypt"] if let output { args.append(contentsOf: ["--output", output]) } - try await runVault( - commandName: Self.commandName, - options: options, - args + + try await cliClient.runVaultCommand( + options.vaultOptions(arguments: args, configuration: nil) ) + +// try await runVault( +// commandName: Self.commandName, +// options: options, +// args +// ) } } diff --git a/Sources/hpa/VaultCommands/EncryptCommand.swift b/Sources/hpa/VaultCommands/EncryptCommand.swift index 2d24a2a..f8a325d 100644 --- a/Sources/hpa/VaultCommands/EncryptCommand.swift +++ b/Sources/hpa/VaultCommands/EncryptCommand.swift @@ -1,4 +1,6 @@ import ArgumentParser +import CliClient +import Dependencies struct EncryptCommand: AsyncParsableCommand { @@ -17,15 +19,22 @@ struct EncryptCommand: AsyncParsableCommand { ) var output: String? + // FIX: mutating func run() async throws { + @Dependency(\.cliClient) var cliClient + var args = ["encrypt"] if let output { args.append(contentsOf: ["--output", output]) } - try await runVault( - commandName: Self.commandName, - options: options, - args + try await cliClient.runVaultCommand( + options.vaultOptions(arguments: args, configuration: nil) ) + +// try await runVault( +// commandName: Self.commandName, +// options: options, +// args +// ) } }