feat: Working create command.
This commit is contained in:
@@ -7,30 +7,47 @@ import Rainbow
|
||||
import ShellClient
|
||||
|
||||
extension CommandConfiguration {
|
||||
static func playbookCommandConfiguration(commandName: String, abstract: String) -> Self {
|
||||
Self(
|
||||
static func playbookCommandConfiguration(
|
||||
commandName: String,
|
||||
abstract: String,
|
||||
examples: (label: String, example: String)...
|
||||
) -> Self {
|
||||
guard examples.count > 0 else {
|
||||
fatalError("Did not supply any examples.")
|
||||
}
|
||||
return Self(
|
||||
commandName: commandName,
|
||||
abstract: "\(abstract.blue)",
|
||||
discussion: """
|
||||
\("IMPORTANT NOTE:".red) Any extra arguments to pass to the playbook invocation have to
|
||||
be at the end with `--` before any arguments otherwise there will
|
||||
be an "Unkown option" error.
|
||||
\("NOTE:".yellow) Most options are not required if you have a configuration file setup.
|
||||
|
||||
\("Example of passing extra args to the playbook:".yellow)
|
||||
\("Examples:".yellow)
|
||||
|
||||
$ hpa \(commandName) /my/project -- --vault-id "myId@$SCRIPTS/vault-gopass-client"
|
||||
\(examples.map { "\($0.label.green.italic)\n $ hpa \($0.example)" }.joined(separator: "\n"))
|
||||
|
||||
\("See Also:".yellow)
|
||||
\("Passing extra args to the playbook.".green.italic)
|
||||
$ hpa \(examples[0].example) -- --vault-id "myId@$SCRIPTS/vault-gopass-client"
|
||||
|
||||
You can run the following command to see the options that can be passed to the playbook
|
||||
invocation.
|
||||
\("See Also:".yellow) \("Ansible playbook options.".italic)
|
||||
|
||||
$ ansible-playbook --help
|
||||
|
||||
\("IMPORTANT NOTE:".red) Any extra arguments to pass to the playbook invocation have to
|
||||
be at the end with `--` before any arguments otherwise there will
|
||||
be an "Unkown option" error. See examples above.
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension GlobalOptions {
|
||||
|
||||
var shellOrDefault: ShellCommand.Shell {
|
||||
guard let shell else { return .zsh(useDashC: true) }
|
||||
return .custom(path: shell, useDashC: true)
|
||||
}
|
||||
}
|
||||
|
||||
func ensureString(
|
||||
globals: GlobalOptions,
|
||||
configuration: Configuration,
|
||||
@@ -41,37 +58,78 @@ func ensureString(
|
||||
return global
|
||||
}
|
||||
guard let configuration = configuration[keyPath: configurationKeyPath] else {
|
||||
throw PlaybookNotFound()
|
||||
throw RunPlaybookError.playbookNotFound
|
||||
}
|
||||
return configuration
|
||||
}
|
||||
|
||||
func withSetupLogger(
|
||||
commandName: String,
|
||||
globals: GlobalOptions,
|
||||
dependencies setupDependencies: (inout DependencyValues) -> Void = { _ in },
|
||||
operation: @escaping () async throws -> Void
|
||||
) async rethrows {
|
||||
try await withDependencies {
|
||||
$0.logger = .init(label: "\("hpa".yellow)")
|
||||
if globals.quietOnlyPlaybook || !globals.quiet {
|
||||
switch globals.verbose {
|
||||
case 0:
|
||||
$0.logger.logLevel = .info
|
||||
case 1:
|
||||
$0.logger.logLevel = .debug
|
||||
case 2...:
|
||||
$0.logger.logLevel = .trace
|
||||
default:
|
||||
$0.logger.logLevel = .info
|
||||
}
|
||||
}
|
||||
$0.logger[metadataKey: "command"] = "\(commandName.blue)"
|
||||
} operation: {
|
||||
try await operation()
|
||||
}
|
||||
}
|
||||
|
||||
func runPlaybook(
|
||||
commandName: String,
|
||||
globals: GlobalOptions,
|
||||
args: [String]
|
||||
configuration: Configuration? = nil,
|
||||
extraArgs: [String],
|
||||
_ args: String...
|
||||
) async throws {
|
||||
try await withDependencies {
|
||||
$0.logger = .init(label: "\("hpa".yellow)")
|
||||
switch globals.verbose {
|
||||
case 0:
|
||||
$0.logger.logLevel = .info
|
||||
case 1:
|
||||
$0.logger.logLevel = .debug
|
||||
case 2:
|
||||
$0.logger.logLevel = .trace
|
||||
default:
|
||||
$0.logger.logLevel = .info
|
||||
try await runPlaybook(
|
||||
commandName: commandName,
|
||||
globals: globals,
|
||||
configuration: configuration,
|
||||
extraArgs: extraArgs,
|
||||
args
|
||||
)
|
||||
}
|
||||
|
||||
private extension CliClient {
|
||||
func ensuredConfiguration(_ configuration: Configuration?) throws -> Configuration {
|
||||
guard let configuration else {
|
||||
return try loadConfiguration()
|
||||
}
|
||||
$0.logger[metadataKey: "command"] = "\(commandName.blue)"
|
||||
} operation: {
|
||||
return configuration
|
||||
}
|
||||
}
|
||||
|
||||
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(\.logger) var logger
|
||||
@Dependency(\.asyncShellClient) var shellClient
|
||||
|
||||
logger.debug("Begin run playbook: \(globals)")
|
||||
let configuration = try cliClient.loadConfiguration()
|
||||
logger.debug("Loaded configuration: \(configuration)")
|
||||
|
||||
let configuration = try cliClient.ensuredConfiguration(configuration)
|
||||
|
||||
logger.debug("Configuration: \(configuration)")
|
||||
|
||||
let playbookDir = try ensureString(
|
||||
globals: globals,
|
||||
@@ -91,19 +149,21 @@ func runPlaybook(
|
||||
var playbookArgs = [
|
||||
"ansible-playbook", playbook,
|
||||
"--inventory", inventory
|
||||
] + args
|
||||
]
|
||||
|
||||
if let defaultArgs = configuration.defaultPlaybookArgs {
|
||||
playbookArgs.append(defaultArgs)
|
||||
}
|
||||
|
||||
try await shellClient.foreground(.init(
|
||||
shell: .zsh(useDashC: true),
|
||||
environment: ProcessInfo.processInfo.environment,
|
||||
in: nil,
|
||||
playbookArgs
|
||||
))
|
||||
try await cliClient.runCommand(
|
||||
quiet: globals.quietOnlyPlaybook ? true : globals.quiet,
|
||||
shell: globals.shellOrDefault,
|
||||
playbookArgs + args + extraArgs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct PlaybookNotFound: Error {}
|
||||
enum RunPlaybookError: Error {
|
||||
case playbookNotFound
|
||||
case configurationError
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user