feat: Updating command options.
This commit is contained in:
@@ -7,38 +7,10 @@ extension CliVersionCommand {
|
||||
struct Build: AsyncParsableCommand {
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
abstract: "Used for the build with version plugin.",
|
||||
discussion: "This should generally not be interacted with directly, outside of the build plugin.",
|
||||
subcommands: [BranchStyle.self, SemVarStyle.self],
|
||||
defaultSubcommand: SemVarStyle.self
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension CliVersionCommand.Build {
|
||||
struct BranchStyle: AsyncParsableCommand {
|
||||
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
commandName: "branch",
|
||||
abstract: "Build using branch and commit sha as the version.",
|
||||
discussion: "This should generally not be interacted with directly, outside of the plugin usage context."
|
||||
discussion: "This should generally not be interacted with directly, outside of the build plugin."
|
||||
)
|
||||
|
||||
@OptionGroup var globals: GlobalBranchOptions
|
||||
|
||||
func run() async throws {
|
||||
try await globals.shared().run(\.build)
|
||||
}
|
||||
}
|
||||
|
||||
struct SemVarStyle: AsyncParsableCommand {
|
||||
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
commandName: "semvar",
|
||||
abstract: "Generates a version file with SemVar style.",
|
||||
discussion: "This should generally not be interacted with directly, outside of the plugin usage context."
|
||||
)
|
||||
|
||||
@OptionGroup var globals: GlobalSemVarOptions
|
||||
@OptionGroup var globals: GlobalOptions
|
||||
|
||||
func run() async throws {
|
||||
try await globals.shared().run(\.build)
|
||||
|
||||
@@ -7,49 +7,15 @@ extension CliVersionCommand {
|
||||
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "bump",
|
||||
abstract: "Bump version of a command-line tool.",
|
||||
subcommands: [
|
||||
SemVarStyle.self,
|
||||
BranchStyle.self
|
||||
],
|
||||
defaultSubcommand: SemVarStyle.self
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension CliVersionCommand.Bump {
|
||||
|
||||
struct BranchStyle: AsyncParsableCommand {
|
||||
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "branch",
|
||||
abstract: "Bump using the current branch and commit sha."
|
||||
abstract: "Bump version of a command-line tool."
|
||||
)
|
||||
|
||||
@OptionGroup var globals: GlobalBranchOptions
|
||||
@OptionGroup var globals: GlobalOptions
|
||||
|
||||
func run() async throws {
|
||||
try await globals.shared().run(\.bump, args: nil)
|
||||
}
|
||||
}
|
||||
|
||||
struct SemVarStyle: AsyncParsableCommand {
|
||||
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "semvar",
|
||||
abstract: "Bump using semvar style options."
|
||||
)
|
||||
|
||||
@OptionGroup var globals: GlobalSemVarOptions
|
||||
|
||||
@Flag
|
||||
var bumpOption: CliClient.BumpOption = .patch
|
||||
|
||||
func run() async throws {
|
||||
try await globals.shared().run(\.bump, args: bumpOption)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension CliClient.BumpOption: EnumerableFlag {}
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
import ConfigurationClient
|
||||
import Dependencies
|
||||
import FileClient
|
||||
import Foundation
|
||||
|
||||
extension Configuration {
|
||||
|
||||
func mergingTarget(_ otherTarget: Configuration.Target?) -> Self {
|
||||
.init(
|
||||
target: otherTarget ?? target,
|
||||
strategy: strategy
|
||||
)
|
||||
}
|
||||
|
||||
func mergingStrategy(_ otherStrategy: Configuration.VersionStrategy?) -> Self {
|
||||
.init(
|
||||
target: target,
|
||||
strategy: strategy?.merging(otherStrategy)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension Configuration.Branch {
|
||||
func merging(_ other: Self?) -> Self {
|
||||
return .init(includeCommitSha: other?.includeCommitSha ?? includeCommitSha)
|
||||
}
|
||||
}
|
||||
|
||||
extension Configuration.SemVar {
|
||||
func merging(_ other: Self?) -> Self {
|
||||
.init(
|
||||
preRelease: other?.preRelease ?? preRelease,
|
||||
requireExistingFile: other?.requireExistingFile ?? requireExistingFile,
|
||||
requireExistingSemVar: other?.requireExistingSemVar ?? requireExistingSemVar
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension Configuration.VersionStrategy {
|
||||
func merging(_ other: Self?) -> Self {
|
||||
guard let branch else {
|
||||
guard let semvar else { return self }
|
||||
return .semvar(semvar.merging(other?.semvar))
|
||||
}
|
||||
return .branch(branch.merging(other?.branch))
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func withConfiguration<T>(
|
||||
path: String?,
|
||||
_ operation: (Configuration) async throws -> T
|
||||
) async throws -> T {
|
||||
@Dependency(\.configurationClient) var configurationClient
|
||||
|
||||
let configuration = try await configurationClient.findAndLoad(
|
||||
path != nil ? URL(filePath: path!) : nil
|
||||
)
|
||||
|
||||
return try await operation(configuration)
|
||||
}
|
||||
// import ConfigurationClient
|
||||
// import Dependencies
|
||||
// import FileClient
|
||||
// import Foundation
|
||||
//
|
||||
// extension Configuration {
|
||||
//
|
||||
// func mergingTarget(_ otherTarget: Configuration.Target?) -> Self {
|
||||
// .init(
|
||||
// target: otherTarget ?? target,
|
||||
// strategy: strategy
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// func mergingStrategy(_ otherStrategy: Configuration.VersionStrategy?) -> Self {
|
||||
// .init(
|
||||
// target: target,
|
||||
// strategy: strategy?.merging(otherStrategy)
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension Configuration.Branch {
|
||||
// func merging(_ other: Self?) -> Self {
|
||||
// return .init(includeCommitSha: other?.includeCommitSha ?? includeCommitSha)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension Configuration.SemVar {
|
||||
// func merging(_ other: Self?) -> Self {
|
||||
// .init(
|
||||
// preRelease: other?.preRelease ?? preRelease,
|
||||
// requireExistingFile: other?.requireExistingFile ?? requireExistingFile,
|
||||
// requireExistingSemVar: other?.requireExistingSemVar ?? requireExistingSemVar
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension Configuration.VersionStrategy {
|
||||
// func merging(_ other: Self?) -> Self {
|
||||
// guard let branch else {
|
||||
// guard let semvar else { return self }
|
||||
// return .semvar(semvar.merging(other?.semvar))
|
||||
// }
|
||||
// return .branch(branch.merging(other?.branch))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @discardableResult
|
||||
// func withConfiguration<T>(
|
||||
// path: String?,
|
||||
// _ operation: (Configuration) async throws -> T
|
||||
// ) async throws -> T {
|
||||
// @Dependency(\.configurationClient) var configurationClient
|
||||
//
|
||||
// let configuration = try await configurationClient.findAndLoad(
|
||||
// path != nil ? URL(filePath: path!) : nil
|
||||
// )
|
||||
//
|
||||
// return try await operation(configuration)
|
||||
// }
|
||||
|
||||
@@ -8,45 +8,13 @@ extension CliVersionCommand {
|
||||
struct Generate: AsyncParsableCommand {
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
abstract: "Generates a version file in a command line tool that can be set via the git tag or git sha.",
|
||||
discussion: "This command can be interacted with directly, outside of the plugin usage context.",
|
||||
subcommands: [BranchStyle.self, SemVarStyle.self],
|
||||
defaultSubcommand: SemVarStyle.self
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension CliVersionCommand.Generate {
|
||||
struct BranchStyle: AsyncParsableCommand {
|
||||
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
commandName: "branch",
|
||||
abstract: "Generates a version file with branch and commit sha as the version.",
|
||||
discussion: "This command can be interacted with directly, outside of the plugin usage context."
|
||||
)
|
||||
|
||||
@OptionGroup var globals: GlobalBranchOptions
|
||||
|
||||
func run() async throws {
|
||||
try await globals.shared().run(\.generate)
|
||||
}
|
||||
}
|
||||
|
||||
struct SemVarStyle: AsyncParsableCommand {
|
||||
|
||||
static let configuration: CommandConfiguration = .init(
|
||||
commandName: "semvar",
|
||||
abstract: "Generates a version file with SemVar style.",
|
||||
discussion: "This command can be interacted with directly, outside of the plugin usage context."
|
||||
)
|
||||
|
||||
@OptionGroup var globals: GlobalSemVarOptions
|
||||
@OptionGroup var globals: GlobalOptions
|
||||
|
||||
func run() async throws {
|
||||
try await globals.shared().run(\.generate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum GenerationError: Error {
|
||||
case fileExists(path: String)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import Dependencies
|
||||
import Foundation
|
||||
import Rainbow
|
||||
|
||||
struct GlobalOptions<Child: ParsableArguments>: ParsableArguments {
|
||||
struct GlobalOptions: ParsableArguments {
|
||||
|
||||
@Option(
|
||||
name: .shortAndLong,
|
||||
@@ -14,7 +14,17 @@ struct GlobalOptions<Child: ParsableArguments>: ParsableArguments {
|
||||
var configurationFile: String?
|
||||
|
||||
@OptionGroup var targetOptions: TargetOptions
|
||||
@OptionGroup var child: Child
|
||||
|
||||
@OptionGroup var semvarOptions: SemVarOptions
|
||||
|
||||
@Flag(
|
||||
name: .long,
|
||||
inversion: .prefixedNo,
|
||||
help: """
|
||||
Include the short commit sha in version or pre-release branch style output.
|
||||
"""
|
||||
)
|
||||
var commitSha: Bool = true
|
||||
|
||||
@Option(
|
||||
name: .customLong("git-directory"),
|
||||
@@ -36,8 +46,6 @@ struct GlobalOptions<Child: ParsableArguments>: ParsableArguments {
|
||||
|
||||
}
|
||||
|
||||
struct Empty: ParsableArguments {}
|
||||
|
||||
struct TargetOptions: ParsableArguments {
|
||||
@Option(
|
||||
name: .shortAndLong,
|
||||
@@ -59,7 +67,16 @@ struct TargetOptions: ParsableArguments {
|
||||
|
||||
}
|
||||
|
||||
// TODO: Need to be able to pass in arguments for custom command pre-release option.
|
||||
|
||||
struct PreReleaseOptions: ParsableArguments {
|
||||
|
||||
@Flag(
|
||||
name: .shortAndLong,
|
||||
help: ""
|
||||
)
|
||||
var disablePreRelease: Bool = false
|
||||
|
||||
@Flag(
|
||||
name: [.customShort("s"), .customLong("pre-release-branch-style")],
|
||||
help: """
|
||||
@@ -76,6 +93,14 @@ struct PreReleaseOptions: ParsableArguments {
|
||||
)
|
||||
var useTagAsPreRelease: Bool = false
|
||||
|
||||
@Option(
|
||||
name: .long,
|
||||
help: """
|
||||
Add / use a pre-release prefix string.
|
||||
"""
|
||||
)
|
||||
var preReleasePrefix: String?
|
||||
|
||||
@Option(
|
||||
name: .long,
|
||||
help: """
|
||||
@@ -84,6 +109,7 @@ struct PreReleaseOptions: ParsableArguments {
|
||||
"""
|
||||
)
|
||||
var custom: String?
|
||||
|
||||
}
|
||||
|
||||
struct SemVarOptions: ParsableArguments {
|
||||
@@ -105,25 +131,7 @@ struct SemVarOptions: ParsableArguments {
|
||||
@OptionGroup var preRelease: PreReleaseOptions
|
||||
}
|
||||
|
||||
typealias GlobalSemVarOptions = GlobalOptions<SemVarOptions>
|
||||
typealias GlobalBranchOptions = GlobalOptions<Empty>
|
||||
|
||||
extension GlobalSemVarOptions {
|
||||
func shared() async throws -> CliClient.SharedOptions {
|
||||
try await withConfiguration(path: configurationFile) { configuration in
|
||||
try shared(configuration.mergingStrategy(.semvar(child.configSemVarOptions())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension GlobalBranchOptions {
|
||||
func shared() async throws -> CliClient.SharedOptions {
|
||||
try await withConfiguration(path: configurationFile) { configuration in
|
||||
try shared(configuration.mergingStrategy(.branch()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Move these to global options.
|
||||
extension CliClient.SharedOptions {
|
||||
|
||||
func run(_ keyPath: KeyPath<CliClient, @Sendable (Self) async throws -> String>) async throws {
|
||||
@@ -156,12 +164,16 @@ extension CliClient.SharedOptions {
|
||||
|
||||
extension GlobalOptions {
|
||||
|
||||
func shared(_ configuration: Configuration) throws -> CliClient.SharedOptions {
|
||||
.init(
|
||||
func shared() throws -> CliClient.SharedOptions {
|
||||
try .init(
|
||||
allowPreReleaseTag: !semvarOptions.preRelease.disablePreRelease,
|
||||
dryRun: dryRun,
|
||||
gitDirectory: gitDirectory,
|
||||
logLevel: .init(verbose: verbose),
|
||||
configuration: configuration
|
||||
verbose: verbose,
|
||||
target: targetOptions.configTarget(),
|
||||
branch: .init(includeCommitSha: commitSha),
|
||||
semvar: semvarOptions.configSemVarOptions(),
|
||||
configurationFile: configurationFile
|
||||
)
|
||||
}
|
||||
|
||||
@@ -170,20 +182,6 @@ extension GlobalOptions {
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension TargetOptions {
|
||||
func target() throws -> String {
|
||||
guard let path else {
|
||||
guard let module else {
|
||||
print("Neither target path or module was set.")
|
||||
throw InvalidTargetOption()
|
||||
}
|
||||
|
||||
return "\(module)/\(fileName)"
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
struct InvalidTargetOption: Error {}
|
||||
|
||||
func configTarget() throws -> Configuration.Target? {
|
||||
guard let path else {
|
||||
guard let module else {
|
||||
|
||||
Reference in New Issue
Block a user