feat: Working on moving commands to cli-client

This commit is contained in:
2024-12-12 07:46:26 -05:00
parent 8302ede99e
commit ce6eb3ec2f
13 changed files with 134 additions and 199 deletions

View File

@@ -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"

View File

@@ -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] }

View File

@@ -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
)
)
}
}
}

View File

@@ -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)'"
// )
}
}
}

View File

@@ -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.

View File

@@ -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
)
}
}

View File

@@ -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<GlobalOptions, String?>,
configurationKeyPath: KeyPath<Configuration, String?>
) 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
}

View File

@@ -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 {}

View File

@@ -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
)
}
}

View File

@@ -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
// )
}
}

View File

@@ -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)

View File

@@ -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
// )
}
}

View File

@@ -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
// )
}
}