feat: Merges dev
All checks were successful
CI / Run Tests (push) Successful in 2m43s

This commit is contained in:
2024-12-17 15:55:36 -05:00
parent 857177032c
commit faa28749bc
88 changed files with 4513 additions and 2301 deletions

View File

@@ -1,57 +0,0 @@
import ArgumentParser
struct CreateProjectTemplateCommand: AsyncParsableCommand {
static let commandName = "create-template"
static let configuration = CommandConfiguration.playbook(
commandName: commandName,
abstract: "Create a home performance assesment project template.",
parentCommand: UtilsCommand.commandName,
examples: (label: "Create Template", example: "\(commandName) /path/to/project-template")
)
@OptionGroup var globals: GlobalOptions
@Option(
name: .shortAndLong,
help: "Customize the directory where template variables are stored."
)
var templateVars: String?
@Flag(
name: .long,
help: "Do not generate ansible-vault variables file."
)
var noVault: Bool = false
@Argument(
help: "Path to the project template directory.",
completion: .directory
)
var path: String
@Argument(
help: "Extra arguments passed to the playbook."
)
var extraArgs: [String] = []
mutating func run() async throws {
let varsDir = templateVars != nil
? ["--extra-vars", "repo_vars_dir=\(templateVars!)"]
: []
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
)
}
}

View File

@@ -0,0 +1,27 @@
import ArgumentParser
import CliDoc
import ConfigurationClient
import CustomDump
import Dependencies
struct DumpConfigCommand: AsyncParsableCommand {
static let commandName = "dump-config"
static let configuration = CommandConfiguration(
commandName: commandName,
abstract: createAbstract("Show the current configuration."),
usage: .default(commandName: commandName, parentCommand: "utils", usesArguments: false, usesExtraArguments: false),
discussion: Discussion {
"Useful to debug your configuration settings / make sure they load properly."
}
)
func run() async throws {
@Dependency(\.configurationClient) var configurationClient
let configuration = try await configurationClient.findAndLoad()
customDump(configuration)
}
}

View File

@@ -1,5 +1,7 @@
import ArgumentParser
import CliClient
import CliDoc
import CommandClient
import ConfigurationClient
import Dependencies
struct GenerateConfigurationCommand: AsyncParsableCommand {
@@ -9,18 +11,23 @@ struct GenerateConfigurationCommand: AsyncParsableCommand {
static let configuration = CommandConfiguration(
commandName: commandName,
abstract: createAbstract("Generate a local configuration file."),
discussion: """
\("NOTE:".yellow) If a directory is not supplied then a configuration file will be created
at \("'~/.config/hpa-playbook/config'".yellow).
\("Example:".yellow)
\("Create a directory and generate the configuration file.".green)
$ mkdir -p ~/.config/hpa-playbook
$ hpa generate-config --path ~/.config/hpa-playbook
"""
discussion: Discussion {
VStack {
Note {
"""
If a directory is not supplied then a configuration file will be created
at \("'~/.config/hpa/config.toml'".yellow).
"""
}
VStack {
"EXAMPLE:".yellow.bold
"Create a directory and generate the configuration".green
ShellCommand("mkdir -p ~/.config/hpa")
ShellCommand("hpa generate-config --path ~/.config/hpa")
}
}
.separator(.newLine(count: 2))
}
)
@Option(
@@ -32,10 +39,16 @@ struct GenerateConfigurationCommand: AsyncParsableCommand {
@Flag(
name: .shortAndLong,
help: "Generate a json file, instead of default env style"
help: "Generate a json file, instead of the default toml style"
)
var json: Bool = false
@Flag(
name: .shortAndLong,
help: "Force generation, overwriting a file if it exists."
)
var force: Bool = false
@OptionGroup var globals: BasicGlobalOptions
mutating func run() async throws {
@@ -43,24 +56,18 @@ struct GenerateConfigurationCommand: AsyncParsableCommand {
}
private func _run() async throws {
try await withSetupLogger(commandName: Self.commandName, globals: globals) {
@Dependency(\.cliClient) var cliClient
@Dependency(\.configurationClient) var configurationClient
let actualPath: String
try await globals.loggingOptions(commandName: Self.commandName).withLogger {
@Dependency(\.logger) var logger
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"
}
let output = try await configurationClient.generate(.init(
force: force,
json: json,
path: path != nil ? .directory(path!) : nil
))
try cliClient.createConfiguration(actualPath, json)
print(output)
}
}
}

View File

@@ -0,0 +1,56 @@
import ArgumentParser
import Dependencies
import PlaybookClient
struct GenerateProjectTemplateCommand: AsyncParsableCommand {
static let commandName = "generate-template"
static let configuration = CommandConfiguration.playbook(
commandName: commandName,
abstract: "Generate a home performance assesment project template.",
parentCommand: UtilsCommand.commandName,
examples: (label: "Generate Template", example: "\(commandName) /path/to/project-template")
)
@OptionGroup var globals: GlobalOptions
@Option(
name: .shortAndLong,
help: "Customize the directory where template variables are stored."
)
var templateVars: String?
@Flag(
name: .long,
help: "Do not generate ansible-vault variables file."
)
var noVault: Bool = false
@Argument(
help: "Path to the project template directory.",
completion: .directory
)
var path: String
@Argument(
help: "Extra arguments / options passed to the playbook."
)
var extraOptions: [String] = []
mutating func run() async throws {
@Dependency(\.playbookClient) var playbookClient
let output = try await playbookClient.run.generateTemplate(.init(
shared: globals.sharedPlaybookRunOptions(
commandName: Self.commandName,
extraOptions: extraOptions
),
templateDirectory: path,
templateVarsDirectory: templateVars,
useVault: !noVault
))
print(output)
}
}

View File

@@ -0,0 +1,52 @@
import ArgumentParser
import CliDoc
import CommandClient
import Dependencies
struct InstallDependenciesCommand: AsyncParsableCommand {
static let commandName: String = "install-dependencies"
static let configuration = CommandConfiguration(
commandName: commandName,
abstract: createAbstract("Ensure required dependencies are installed"),
usage: .default(commandName: commandName, parentCommand: "utils", usesArguments: false),
discussion: Discussion {
VStack {
Note {
"Homebrew is required to install dependencies."
}
HStack {
"See Also:".yellow.bold.underline
"https://brew.sh"
}
ImportantNote.passingExtraArgs
}
.separator(.newLine(count: 2))
}
)
@OptionGroup var globals: BasicGlobalOptions
@Argument(
help: "Extra arguments / options to pass to the homebrew command."
)
var extraOptions: [String] = []
mutating func run() async throws {
@Dependency(\.commandClient) var commandClient
@Dependency(\.playbookClient) var playbookClient
let arguments = [
"brew", "install"
] + Constants.brewPackages
+ extraOptions
try await commandClient.run(
quiet: globals.quiet,
shell: globals.shell,
arguments
)
try await playbookClient.repository.install()
}
}

View File

@@ -5,12 +5,15 @@ struct UtilsCommand: AsyncParsableCommand {
static let configuration = CommandConfiguration(
commandName: commandName,
abstract: "\("Utility commands.".blue)",
abstract: createAbstract("Utility commands."),
discussion: """
These are commands that are generally only run on occasion / less frequently used.
""",
subcommands: [
CreateProjectTemplateCommand.self, GenerateConfigurationCommand.self
DumpConfigCommand.self,
GenerateProjectTemplateCommand.self,
GenerateConfigurationCommand.self,
InstallDependenciesCommand.self
]
)