feat: Moves logging setup and generate-json for the create command to cli-client module.

This commit is contained in:
2024-12-12 11:16:22 -05:00
parent ce6eb3ec2f
commit 7b30b78b67
14 changed files with 449 additions and 230 deletions

View File

@@ -38,18 +38,17 @@ struct BuildCommand: AsyncParsableCommand {
}
private func _run() async throws {
try await withSetupLogger(commandName: Self.commandName, globals: globals) {
@Dependency(\.cliClient) var cliClient
@Dependency(\.cliClient) var cliClient
try await cliClient.runPlaybookCommand(
globals.playbookOptions(
arguments: [
"--tags", "build-project",
"--extra-vars", "project_dir=\(self.projectDir)"
],
configuration: nil
)
)
}
try await cliClient.runPlaybookCommand(
globals.playbookOptions(
arguments: [
"--tags", "build-project",
"--extra-vars", "project_dir=\(projectDir)"
],
configuration: nil
),
logging: globals.loggingOptions(commandName: Self.commandName)
)
}
}

View File

@@ -61,126 +61,46 @@ struct CreateCommand: AsyncParsableCommand {
}
private func _run() async throws {
try await withSetupLogger(commandName: Self.commandName, globals: globals) {
@Dependency(\.coders) var coders
@Dependency(\.cliClient) var cliClient
@Dependency(\.configurationClient) var configurationClient
@Dependency(\.coders) var coders
@Dependency(\.cliClient) var cliClient
@Dependency(\.configurationClient) var configurationClient
let loggingOptions = globals.loggingOptions(commandName: Self.commandName)
try await cliClient.withLogger(loggingOptions) {
@Dependency(\.logger) var logger
let encoder = coders.jsonEncoder()
let configuration = try await configurationClient.findAndLoad()
logger.debug("Configuration: \(configuration)")
let jsonData = try parseOptions(
command: self,
configuration: configuration,
logger: logger,
encoder: encoder
let json = try await cliClient.generateJSON(
generateJsonOptions,
logging: loggingOptions
)
guard let jsonString = String(data: jsonData, encoding: .utf8) else {
throw CreateError.encodingError
}
logger.debug("JSON string: \(jsonString)")
logger.debug("JSON string: \(json)")
let arguments = [
"--tags", "setup-project",
"--extra-vars", "project_dir=\(self.projectDir)",
"--extra-vars", "'\(jsonString)'"
"--extra-vars", "'\(json)'"
] + extraArgs
try await cliClient.runPlaybookCommand(
globals.playbookOptions(
arguments: arguments,
configuration: configuration
)
configuration: nil
),
logging: loggingOptions
)
// 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)'"
// )
}
}
}
private func parseOptions(
command: CreateCommand,
configuration: Configuration,
logger: Logger,
encoder: JSONEncoder
) throws -> Data {
let templateDir = command.templateDir ?? configuration.template.directory
let templateRepo = command.repo ?? configuration.template.url
let version = (command.branch ?? configuration.template.version) ?? "main"
logger.debug("""
(\(command.localTemplateDir), \(String(describing: templateDir)), \(String(describing: templateRepo)))
""")
switch (command.localTemplateDir, templateDir, templateRepo) {
case (true, .none, _):
// User supplied they wanted to use a local template directory, but we could not find
// the path set from command line or in configuration.
throw CreateError.templateDirNotFound
case let (false, _, .some(repo)):
// User did not supply they wanted to use a local template directory, and we found a repo url that was
// either set by the command line or found in the configuration.
logger.debug("Using repo.")
return try encoder.encode(TemplateRepo(repo: repo, version: version))
case let (true, .some(templateDir), _):
// User supplied they wanted to use a local template directory, and we found the template directory
// either set by the command line or in the configuration.
logger.debug("Using template directory.")
return try encoder.encode(TemplateDirJson(path: templateDir))
case let (false, .some(templateDir), _):
// User supplied they did not wanted to use a local template directory, and we found the template directory
// either set by the command line or in the configuration, and no repo was found / handled previously.
logger.debug("Using template directory.")
return try encoder.encode(TemplateDirJson(path: templateDir))
case (_, .none, .none):
// We could not find a repo or template directory.
throw CreateError.templateDirOrRepoNotSpecified
private extension CreateCommand {
var generateJsonOptions: CliClient.GenerateJsonOptions {
.init(
templateDirectory: templateDir,
templateRepo: repo,
version: branch,
useLocalTemplateDirectory: localTemplateDir
)
}
}
private struct TemplateDirJson: Encodable {
let template: Template
init(path: String) {
self.template = .init(path: path)
}
struct Template: Encodable {
let path: String
}
}
private struct TemplateRepo: Encodable {
let template: Template
init(repo: String, version: String?) {
self.template = .init(repo: repo, version: version ?? "main")
}
struct Template: Encodable {
let repo: String
let version: String
}
}
enum CreateError: Error {
case encodingError
case templateDirNotFound
case templateDirOrRepoNotSpecified
}

View File

@@ -1,4 +1,5 @@
import ArgumentParser
import CliClient
struct BasicGlobalOptions: ParsableArguments {
@Flag(
@@ -55,3 +56,21 @@ struct GlobalOptions: ParsableArguments {
}
}
extension GlobalOptions {
func loggingOptions(commandName: String) -> CliClient.LoggingOptions {
.init(
commandName: commandName,
logLevel: .init(globals: basic, quietOnlyPlaybook: quietOnlyPlaybook)
)
}
}
extension BasicGlobalOptions {
func loggingOptions(commandName: String) -> CliClient.LoggingOptions {
.init(
commandName: commandName,
logLevel: .init(globals: self, quietOnlyPlaybook: false)
)
}
}

View File

@@ -1,7 +1,5 @@
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.
@@ -22,34 +20,3 @@ extension Logger.Level {
self = .info
}
}
func withSetupLogger(
commandName: String,
globals: BasicGlobalOptions,
quietOnlyPlaybook: Bool = false,
dependencies setupDependencies: (inout DependencyValues) -> Void = { _ in },
operation: @escaping () async throws -> Void
) async rethrows {
try await withDependencies {
$0.logger = .init(label: "\("hpa".yellow)")
$0.logger.logLevel = .init(globals: globals, quietOnlyPlaybook: quietOnlyPlaybook)
$0.logger[metadataKey: "command"] = "\(commandName.blue)"
} operation: {
try await operation()
}
}
func withSetupLogger(
commandName: String,
globals: GlobalOptions,
dependencies setupDependencies: (inout DependencyValues) -> Void = { _ in },
operation: @escaping () async throws -> Void
) async rethrows {
try await withSetupLogger(
commandName: commandName,
globals: globals.basic,
quietOnlyPlaybook: globals.quietOnlyPlaybook,
dependencies: setupDependencies,
operation: operation
)
}

View File

@@ -50,9 +50,8 @@ struct GenerateConfigurationCommand: AsyncParsableCommand {
// FIX:
private func _run() async throws {
try await withSetupLogger(commandName: Self.commandName, globals: globals) {
@Dependency(\.cliClient) var cliClient
@Dependency(\.cliClient) var cliClient
try await cliClient.withLogger(globals.loggingOptions(commandName: Self.commandName)) {
let actualPath: String
// if let path {

View File

@@ -29,7 +29,8 @@ struct DecryptCommand: AsyncParsableCommand {
}
try await cliClient.runVaultCommand(
options.vaultOptions(arguments: args, configuration: nil)
options.vaultOptions(arguments: args, configuration: nil),
logging: options.loggingOptions(commandName: Self.commandName)
)
// try await runVault(

View File

@@ -28,7 +28,8 @@ struct EncryptCommand: AsyncParsableCommand {
args.append(contentsOf: ["--output", output])
}
try await cliClient.runVaultCommand(
options.vaultOptions(arguments: args, configuration: nil)
options.vaultOptions(arguments: args, configuration: nil),
logging: options.loggingOptions(commandName: Self.commandName)
)
// try await runVault(

View File

@@ -1,4 +1,5 @@
import ArgumentParser
import CliClient
// Holds the common options for vault commands, as they all share the
// same structure.
@@ -29,3 +30,9 @@ struct VaultOptions: ParsableArguments {
}
}
extension VaultOptions {
func loggingOptions(commandName: String) -> CliClient.LoggingOptions {
globals.loggingOptions(commandName: commandName)
}
}