From 7d23172c71ed8a9458ecd2f873b7d8425e4246bf Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Mon, 23 Dec 2024 22:46:20 -0500 Subject: [PATCH] feat: Updating configuration. --- .bump-version.json | 25 +++ .bump-version.toml | 6 + Package.swift | 1 + .../ConfigurationClient/Configuration.swift | 151 +++++++++++++++++- .../ConfigurationClientTests.swift | 51 ++++++ 5 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 .bump-version.json diff --git a/.bump-version.json b/.bump-version.json new file mode 100644 index 0000000..5da2325 --- /dev/null +++ b/.bump-version.json @@ -0,0 +1,25 @@ +{ + "strategy" : { + "semvar" : { + "preRelease" : { + "strategy" : { + "command" : { + "arguments" : [ + "git", + "describe", + "--tags" + ] + } + } + }, + "requireExistingFile" : true, + "requireExistingSemVar" : true + } + }, + "target" : { + "module" : { + "fileName" : "Version.swift", + "name" : "cli-version" + } + } +} \ No newline at end of file diff --git a/.bump-version.toml b/.bump-version.toml index dfbdf28..0959d2e 100644 --- a/.bump-version.toml +++ b/.bump-version.toml @@ -2,6 +2,12 @@ requireExistingFile = true requireExistingSemVar = true +[strategy.semvar.preRelease] +style = 'branch' + +[strategy.semvar.preRelease.branch] +includeCommitSha = true + [target.module] fileName = 'Version.swift' name = 'cli-version' diff --git a/Package.swift b/Package.swift index 6ffd377..114d62a 100644 --- a/Package.swift +++ b/Package.swift @@ -48,6 +48,7 @@ let package = Package( name: "ConfigurationClient", dependencies: [ "FileClient", + .product(name: "CustomDump", package: "swift-custom-dump"), .product(name: "Dependencies", package: "swift-dependencies"), .product(name: "DependenciesMacros", package: "swift-dependencies"), .product(name: "TOMLKit", package: "TOMLKit") diff --git a/Sources/ConfigurationClient/Configuration.swift b/Sources/ConfigurationClient/Configuration.swift index 0e704ec..b826600 100644 --- a/Sources/ConfigurationClient/Configuration.swift +++ b/Sources/ConfigurationClient/Configuration.swift @@ -1,6 +1,9 @@ +import CustomDump import Foundation import TOMLKit +// TODO: Just use json for configuration ?? + /// Represents configuration that can be set via a file, generally in the root of the /// project directory. /// @@ -38,6 +41,19 @@ public struct Configuration: Codable, Equatable, Sendable { } } +public struct Configuration2: Codable, Equatable, Sendable { + public let target: Configuration.Target? + public let strategy: Configuration.VersionStrategy2? + + public static let mock = Self( + target: .init(module: .init("cli-version")), + strategy: .semvar(value: .init(preRelease: .init( + strategy: .branch() + ))) + // strategy: .branch() + ) +} + public extension Configuration { /// Represents a branch version or pre-release strategy. @@ -58,12 +74,32 @@ public extension Configuration { } } + struct PreRelease2: Codable, Equatable, Sendable { + + public let prefix: String? + public let strategy: Strategy + + public init( + prefix: String? = nil, + strategy: Strategy + ) { + self.prefix = prefix + self.strategy = strategy + } + + public enum Strategy: Codable, Equatable, Sendable { + case branch(includeCommitSha: Bool = true) + case command(arguments: [String]) + case gitTag + } + } + /// Represents version strategy for pre-release. /// /// This appends a suffix to the version that get's generated from the version strategy. /// For example: `1.0.0-rc-1` /// - struct PreReleaseStrategy: Codable, Equatable, Sendable { + struct PreReleaseStrategy: Codable, Equatable, Sendable, CustomDumpReflectable { /// Use branch and commit sha as pre-release suffix. public let branch: Branch? @@ -76,7 +112,7 @@ public extension Configuration { /// Whether we use `git describe --tags` for part of the suffix, this is only used /// if we have a custom style. - public let usesGitTag: Bool + public let usesGitTag: Bool? init( style: StyleId, @@ -90,6 +126,30 @@ public extension Configuration { self.usesGitTag = usesGitTag } + public var customDumpMirror: Mirror { + guard let branch else { + return .init( + self, + children: [ + "style": style, + "prefix": prefix as Any, + "usesGitTag": style == .gitTag ? true : (usesGitTag ?? false) + ], + displayStyle: .struct + ) + // return .init(reflecting: self) + } + return .init( + self, + children: [ + "style": style, + "branch": branch, + "prefix": prefix as Any + ], + displayStyle: .struct + ) + } + /// Represents a pre-release strategy that is derived from calling /// `git describe --tags`. public static let gitTag = Self(style: StyleId.gitTag) @@ -154,11 +214,34 @@ public extension Configuration { } + struct SemVar2: Codable, Equatable, Sendable { + + /// Optional pre-releas suffix strategy. + public let preRelease: PreRelease2? + + /// Fail if an existing version file does not exist in the target. + public let requireExistingFile: Bool + + /// Fail if an existing semvar is not parsed from the file or version generation strategy. + public let requireExistingSemVar: Bool + + public init( + preRelease: PreRelease2? = nil, + requireExistingFile: Bool = true, + requireExistingSemVar: Bool = true + ) { + self.preRelease = preRelease + self.requireExistingFile = requireExistingFile + self.requireExistingSemVar = requireExistingSemVar + } + + } + /// Represents the target where we will bump the version in. /// /// This can either be a path to a version file or a module used to /// locate the version file. - struct Target: Codable, Equatable, Sendable { + struct Target: Codable, Equatable, Sendable, CustomDumpReflectable { /// The path to a version file. public let path: String? @@ -206,6 +289,44 @@ public extension Configuration { self.name = name self.fileName = fileName } + + } + + public var customDumpMirror: Mirror { + guard let module else { + guard let path else { return .init(reflecting: self) } + return .init( + self, + children: [ + "path": path + ], + displayStyle: .struct + ) + } + return .init( + self, + children: [ + "module": module + ], + displayStyle: .struct + ) + } + } + + enum VersionStrategy2: Codable, Equatable, Sendable { + case branch(includeCommitSha: Bool = true) + case semvar( + preRelease: PreRelease2? = nil, + requireExistingFile: Bool? = nil, + requireExistingSemVar: Bool? = nil + ) + + static func semvar(value: SemVar2) -> Self { + .semvar( + preRelease: value.preRelease, + requireExistingFile: value.requireExistingFile, + requireExistingSemVar: value.requireExistingSemVar + ) } } @@ -214,7 +335,7 @@ public extension Configuration { /// Typically a `SemVar` strategy or `Branch`. /// /// - struct VersionStrategy: Codable, Equatable, Sendable { + struct VersionStrategy: Codable, Equatable, Sendable, CustomDumpReflectable { /// Set if we're using the branch and commit sha to derive the version. public let branch: Branch? @@ -240,5 +361,27 @@ public extension Configuration { self.semvar = semvar } + public var customDumpMirror: Mirror { + if let branch { + return .init( + self, + children: [ + "branch": branch + ], + displayStyle: .struct + ) + } else if let semvar { + return .init( + self, + children: [ + "semvar": semvar + ], + displayStyle: .struct + ) + } else { + return .init(reflecting: self) + } + } + } } diff --git a/Tests/ConfigurationClientTests/ConfigurationClientTests.swift b/Tests/ConfigurationClientTests/ConfigurationClientTests.swift index c620609..1b39d4b 100644 --- a/Tests/ConfigurationClientTests/ConfigurationClientTests.swift +++ b/Tests/ConfigurationClientTests/ConfigurationClientTests.swift @@ -3,6 +3,7 @@ import Dependencies import Foundation import Testing import TestSupport +import TOMLKit @Suite("ConfigurationClientTests") struct ConfigurationClientTests { @@ -98,6 +99,56 @@ struct ConfigurationClientTests { } } + // @Test + // func writeDefault() async throws { + // try await run { + // @Dependency(\.coders) var coders + // @Dependency(\.configurationClient) var configurationClient + // + // // let configuration = Configuration.customPreRelease + // // try await configurationClient.write(configuration, .json(URL(filePath: ".bump-version.json"))) + // + // // let target = Configuration.Target2.path("foo") + // // let target = Configuration.Target2.gitTag + // // let target = Configuration.Target2.branch() + // let target = Configuration2.mock + // + // let encoded = try coders.jsonEncoder().encode(target) + // let url = URL(filePath: ".bump-version.json") + // try encoded.write(to: url) + // + // let data = try Data(contentsOf: url) + // let decoded = try coders.jsonDecoder().decode(Configuration2.self, from: data) + // print(decoded) + // } + // } + + // @Test + // func tomlPlayground() throws { + // let jsonEncoder = JSONEncoder() + // let encoder = TOMLEncoder() + // let decoder = TOMLDecoder() + // + // enum TestType: Codable { + // case one + // case hello(Hello) + // + // struct Hello: Codable { + // let value: String + // } + // } + // + // struct TestContainer: Codable { + // let testType: TestType + // } + // + // let sut = TestContainer(testType: .hello(.init(value: "world"))) + // let encoded = try encoder.encode(sut) + // print(encoded) + // // let decoded = try decoder.decode(TestContainer.self, from: encoded) + // // #expect(decoded.testType == sut.testType) + // } + func run( setupDependencies: @escaping (inout DependencyValues) -> Void = { _ in }, operation: () async throws -> Void