feat: Updates configuration commands and parsing strategy.
All checks were successful
CI / Ubuntu (push) Successful in 2m59s
All checks were successful
CI / Ubuntu (push) Successful in 2m59s
This commit is contained in:
171
Sources/bump-version/Commands/ConfigCommand.swift
Normal file
171
Sources/bump-version/Commands/ConfigCommand.swift
Normal file
@@ -0,0 +1,171 @@
|
||||
import ArgumentParser
|
||||
import CliClient
|
||||
import ConfigurationClient
|
||||
import CustomDump
|
||||
import Dependencies
|
||||
import FileClient
|
||||
import Foundation
|
||||
|
||||
struct ConfigCommand: AsyncParsableCommand {
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "config",
|
||||
abstract: "Configuration commands",
|
||||
subcommands: [
|
||||
DumpConfig.self,
|
||||
GenerateConfig.self
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
extension ConfigCommand {
|
||||
|
||||
struct DumpConfig: AsyncParsableCommand {
|
||||
static let commandName = "dump"
|
||||
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: Self.commandName,
|
||||
abstract: "Inspect the parsed configuration.",
|
||||
discussion: """
|
||||
This will load any configuration and merge the options passed in. Then print it to stdout.
|
||||
The default style is to print the output in `swift`, however you can use the `--print` flag to
|
||||
print the output in `json`.
|
||||
""",
|
||||
aliases: ["d"]
|
||||
)
|
||||
|
||||
@OptionGroup var globals: ConfigCommandOptions
|
||||
|
||||
func run() async throws {
|
||||
let configuration = try await globals
|
||||
.shared(command: Self.commandName)
|
||||
.runClient(\.parsedConfiguration)
|
||||
|
||||
try globals.printConfiguration(configuration)
|
||||
}
|
||||
}
|
||||
|
||||
struct GenerateConfig: AsyncParsableCommand {
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
commandName: "generate",
|
||||
abstract: "Generate a configuration file.",
|
||||
aliases: ["g"]
|
||||
)
|
||||
|
||||
@Flag(
|
||||
help: "The style of the configuration."
|
||||
)
|
||||
var style: ConfigCommand.Style = .semvar
|
||||
|
||||
@OptionGroup var globals: ConfigCommandOptions
|
||||
|
||||
func run() async throws {
|
||||
try await withSetupDependencies {
|
||||
@Dependency(\.configurationClient) var configurationClient
|
||||
|
||||
let configuration = try style.parseConfiguration(
|
||||
configOptions: globals.configOptions,
|
||||
extraOptions: globals.extraOptions
|
||||
)
|
||||
|
||||
switch globals.printJson {
|
||||
case true:
|
||||
try globals.handlePrintJson(configuration)
|
||||
case false:
|
||||
let url = globals.configFileUrl
|
||||
try await configurationClient.write(configuration, url)
|
||||
print(url.cleanFilePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension ConfigCommand {
|
||||
enum Style: EnumerableFlag {
|
||||
case branch, semvar
|
||||
|
||||
func parseConfiguration(
|
||||
configOptions: ConfigurationOptions,
|
||||
extraOptions: [String]
|
||||
) throws -> Configuration {
|
||||
let strategy: Configuration.VersionStrategy
|
||||
|
||||
switch self {
|
||||
case .branch:
|
||||
strategy = .branch(includeCommitSha: configOptions.commitSha)
|
||||
case .semvar:
|
||||
strategy = try .semvar(configOptions.semvarOptions(extraOptions: extraOptions))
|
||||
}
|
||||
|
||||
return try Configuration(
|
||||
target: configOptions.target(),
|
||||
strategy: strategy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@dynamicMemberLookup
|
||||
struct ConfigCommandOptions: ParsableArguments {
|
||||
|
||||
@Flag(
|
||||
name: .customLong("print"),
|
||||
help: "Print style to stdout."
|
||||
)
|
||||
var printJson: Bool = false
|
||||
|
||||
@OptionGroup var configOptions: ConfigurationOptions
|
||||
|
||||
@Argument(
|
||||
help: """
|
||||
Arguments / options used for custom pre-release, options / flags must proceed a '--' in
|
||||
the command. These are ignored if the `--custom-command` or `--custom-pre-release` flag is not set.
|
||||
"""
|
||||
)
|
||||
var extraOptions: [String] = []
|
||||
|
||||
subscript<T>(dynamicMember keyPath: KeyPath<ConfigurationOptions, T>) -> T {
|
||||
configOptions[keyPath: keyPath]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension ConfigCommand.ConfigCommandOptions {
|
||||
|
||||
func shared(command: String) throws -> CliClient.SharedOptions {
|
||||
try configOptions.shared(command: command, extraOptions: extraOptions)
|
||||
}
|
||||
|
||||
func handlePrintJson(_ configuration: Configuration) throws {
|
||||
@Dependency(\.coders) var coders
|
||||
@Dependency(\.logger) var logger
|
||||
|
||||
let data = try coders.jsonEncoder().encode(configuration)
|
||||
guard let string = String(bytes: data, encoding: .utf8) else {
|
||||
logger.error("Error encoding configuration to json.")
|
||||
throw ConfigurationEncodingError()
|
||||
}
|
||||
print(string)
|
||||
}
|
||||
|
||||
func printConfiguration(_ configuration: Configuration) throws {
|
||||
guard printJson else {
|
||||
customDump(configuration)
|
||||
return
|
||||
}
|
||||
try handlePrintJson(configuration)
|
||||
}
|
||||
}
|
||||
|
||||
private extension ConfigurationOptions {
|
||||
var configFileUrl: URL {
|
||||
switch configurationFile {
|
||||
case let .some(path):
|
||||
return URL(filePath: path)
|
||||
case .none:
|
||||
return URL(filePath: ".bump-version.json")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ConfigurationEncodingError: Error {}
|
||||
@@ -1,97 +0,0 @@
|
||||
import ArgumentParser
|
||||
import ConfigurationClient
|
||||
import CustomDump
|
||||
import Dependencies
|
||||
import FileClient
|
||||
import Foundation
|
||||
|
||||
struct UtilsCommand: AsyncParsableCommand {
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "utils",
|
||||
abstract: "Utility commands",
|
||||
subcommands: [
|
||||
DumpConfig.self,
|
||||
GenerateConfig.self
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
extension UtilsCommand {
|
||||
struct DumpConfig: AsyncParsableCommand {
|
||||
static let commandName = "dump-config"
|
||||
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: Self.commandName,
|
||||
abstract: "Show the parsed configuration.",
|
||||
aliases: ["dc"]
|
||||
)
|
||||
|
||||
@OptionGroup var globals: GlobalOptions
|
||||
|
||||
func run() async throws {
|
||||
let configuration = try await globals.runClient(\.parsedConfiguration, command: Self.commandName)
|
||||
customDump(configuration)
|
||||
}
|
||||
}
|
||||
|
||||
struct GenerateConfig: AsyncParsableCommand {
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
commandName: "generate-config",
|
||||
abstract: "Generate a configuration file.",
|
||||
aliases: ["gc"]
|
||||
)
|
||||
|
||||
@OptionGroup var configOptions: ConfigurationOptions
|
||||
|
||||
@Flag(
|
||||
help: "The style of the configuration."
|
||||
)
|
||||
var style: Style = .semvar
|
||||
|
||||
@Argument(
|
||||
help: """
|
||||
Arguments / options used for custom pre-release, options / flags must proceed a '--' in
|
||||
the command. These are ignored if the `--custom` flag is not set.
|
||||
"""
|
||||
)
|
||||
var extraOptions: [String] = []
|
||||
|
||||
func run() async throws {
|
||||
try await withSetupDependencies {
|
||||
@Dependency(\.configurationClient) var configurationClient
|
||||
|
||||
let strategy: Configuration.VersionStrategy
|
||||
|
||||
switch style {
|
||||
case .branch:
|
||||
strategy = .branch(includeCommitSha: configOptions.commitSha)
|
||||
case .semvar:
|
||||
strategy = try .semvar(configOptions.semvarOptions(extraOptions: extraOptions))
|
||||
}
|
||||
|
||||
let configuration = try Configuration(
|
||||
target: configOptions.target(),
|
||||
strategy: strategy
|
||||
)
|
||||
|
||||
let url: URL
|
||||
switch configOptions.configurationFile {
|
||||
case let .some(path):
|
||||
url = URL(filePath: path)
|
||||
case .none:
|
||||
url = URL(filePath: ".bump-version.json")
|
||||
}
|
||||
|
||||
try await configurationClient.write(configuration, url)
|
||||
|
||||
print(url.cleanFilePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension UtilsCommand.GenerateConfig {
|
||||
enum Style: EnumerableFlag {
|
||||
case branch, semvar
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user