feat: Renames some options, adds a require-configuration option that fails if configuration is not found.
All checks were successful
CI / Ubuntu (push) Successful in 2m19s
All checks were successful
CI / Ubuntu (push) Successful in 2m19s
This commit is contained in:
@@ -18,7 +18,7 @@ struct BumpCommand: CommandRepresentable {
|
||||
),
|
||||
makeExample(
|
||||
label: "Dry run, just show what the bumped version would be.",
|
||||
example: "--minor --dry-run"
|
||||
example: "--minor --print"
|
||||
)
|
||||
])
|
||||
)
|
||||
|
||||
@@ -149,8 +149,6 @@ extension ConfigCommand {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add verbose.
|
||||
// TODO: Need to be able to generate a branch style config file.
|
||||
@dynamicMemberLookup
|
||||
struct ConfigCommandOptions: ParsableArguments {
|
||||
|
||||
@@ -210,12 +208,6 @@ private extension ConfigCommand.ConfigCommandOptions {
|
||||
case .swift:
|
||||
customDump(configuration)
|
||||
}
|
||||
|
||||
// guard printJson else {
|
||||
// customDump(configuration)
|
||||
// return
|
||||
// }
|
||||
// try handlePrintJson(configuration)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@ by the module that a `Version.swift` file resides in. It also declares the strat
|
||||
new versions.
|
||||
|
||||
The command-line tool comes with a command to generate the configuration file for you, this should
|
||||
be ran from the root of your project.
|
||||
be ran from the root of your project or by specifying the path to write the configuration file to
|
||||
using the `-f | --configuration-file` option. The below examples assume that you're running in the
|
||||
root project directory.
|
||||
|
||||
```bash
|
||||
bump-version config generate --target-module my-tool
|
||||
|
||||
@@ -39,10 +39,18 @@ are ignored if your configuration or options specify to use a `branch` strategy.
|
||||
bump-version bump --minor
|
||||
```
|
||||
|
||||
If you want to use the default configuration without generating your own project configuration, then
|
||||
you can specify the path or module to the bump command. The default configuration will use the
|
||||
`gitTag` strategy without any pre-release strategy.
|
||||
|
||||
```bash
|
||||
bump-version bump --minor --target-module my-tool
|
||||
```
|
||||
|
||||
Show the output, but don't update the version file.
|
||||
|
||||
```bash
|
||||
bump-version bump --major --dry-run
|
||||
bump-version bump --major --print
|
||||
```
|
||||
|
||||
### Generate Command
|
||||
@@ -66,11 +74,10 @@ Generates a configuration file based on the passed in options.
|
||||
|
||||
The following options are used to declare strategy used for deriving the version.
|
||||
|
||||
| Long | Description |
|
||||
| -------- | ------------------------------------------------------- |
|
||||
| --branch | Use the branch strategy |
|
||||
| --semvar | Use the semvar strategy (default) |
|
||||
| --print | Print the output to stdout instead of generating a file |
|
||||
| Long | Description |
|
||||
| -------- | --------------------------------- |
|
||||
| --branch | Use the branch strategy |
|
||||
| --semvar | Use the semvar strategy (default) |
|
||||
|
||||
##### Generate Configuration Example
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ of their usage.
|
||||
|
||||
### General Options
|
||||
|
||||
| Short | Long | Argument | Description |
|
||||
| ----- | --------------- | -------- | -------------------------------------------------------------------- |
|
||||
| N/A | --dry-run | N/A | Perform the command, but don't write any output files |
|
||||
| N/A | --git-directory | <path> | The path to the root of your project, defaults to current directory |
|
||||
| -h | --help | N/A | Show help for a command |
|
||||
| -v | --verbose | N/A | Increase logging level, can be passed multiple times (example: -vvv) |
|
||||
| N/A | --version | N/A | Show the version of the command line tool |
|
||||
| Short | Long | Argument | Description |
|
||||
| ----- | ------------------- | -------- | -------------------------------------------------------------------- |
|
||||
| N/A | --print | N/A | Perform the command, but don't write any output files |
|
||||
| N/A | --project-directory | <path> | The path to the root of your project, defaults to current directory |
|
||||
| -h | --help | N/A | Show help for a command |
|
||||
| -v | --verbose | N/A | Increase logging level, can be passed multiple times (example: -vvv) |
|
||||
| N/A | --version | N/A | Show the version of the command line tool |
|
||||
|
||||
### Configuration Options
|
||||
|
||||
@@ -30,6 +30,7 @@ of their usage.
|
||||
| N/A | --require-existing-semvar | N/A | Fail if an existing semvar is not found in the version file. |
|
||||
| -c | --custom-command | <arguments> | Use a custom command strategy for the version (any options need to proceed a '--') |
|
||||
| N/A | --commit-sha/--no-commit-sha | N/A | Use the commit sha with branch version or pre-release strategy |
|
||||
| N/A | --require-configuration | N/A | Fail if a configuration file is not found |
|
||||
|
||||
#### Pre-Release Options
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ struct GlobalOptions: ParsableArguments {
|
||||
var configOptions: ConfigurationOptions
|
||||
|
||||
@Option(
|
||||
name: .customLong("git-directory"),
|
||||
help: "The git directory for the version (default: current directory)"
|
||||
name: .customLong("project-directory"),
|
||||
help: "The project directory. (default: current directory)"
|
||||
)
|
||||
var gitDirectory: String?
|
||||
var projectDirectory: String?
|
||||
|
||||
@Flag(
|
||||
name: .customLong("dry-run"),
|
||||
name: .customLong("print"),
|
||||
help: "Print's what would be written to a target version file."
|
||||
)
|
||||
var dryRun: Bool = false
|
||||
@@ -41,6 +41,7 @@ struct GlobalOptions: ParsableArguments {
|
||||
}
|
||||
|
||||
struct ConfigurationOptions: ParsableArguments {
|
||||
|
||||
@Option(
|
||||
name: [.customShort("f"), .long],
|
||||
help: "Specify the path to a configuration file. (default: .bump-version.json)",
|
||||
@@ -61,6 +62,14 @@ struct ConfigurationOptions: ParsableArguments {
|
||||
)
|
||||
var commitSha: Bool = true
|
||||
|
||||
@Flag(
|
||||
name: .long,
|
||||
help: """
|
||||
Require a configuration file, otherwise fail.
|
||||
"""
|
||||
)
|
||||
var requireConfiguration: Bool = false
|
||||
|
||||
}
|
||||
|
||||
struct TargetOptions: ParsableArguments {
|
||||
@@ -126,7 +135,6 @@ struct PreReleaseOptions: ParsableArguments {
|
||||
|
||||
}
|
||||
|
||||
// TODO: Add custom command strategy.
|
||||
struct SemVarOptions: ParsableArguments {
|
||||
|
||||
@Flag(
|
||||
|
||||
@@ -64,7 +64,7 @@ extension GlobalOptions {
|
||||
command: command,
|
||||
dryRun: dryRun,
|
||||
extraOptions: extraOptions,
|
||||
gitDirectory: gitDirectory,
|
||||
gitDirectory: projectDirectory,
|
||||
verbose: verbose
|
||||
)
|
||||
}
|
||||
@@ -129,7 +129,6 @@ extension SemVarOptions {
|
||||
) throws -> Configuration.SemVar {
|
||||
@Dependency(\.logger) var logger
|
||||
|
||||
// TODO: Update when / if there's an update config command.
|
||||
if customCommand && preRelease.customPreRelease {
|
||||
logger.warning("""
|
||||
Custom pre-release can not be used at same time as custom command.
|
||||
@@ -167,6 +166,15 @@ extension ConfigurationOptions {
|
||||
)
|
||||
}
|
||||
|
||||
private func configurationToMerge(extraOptions: [String]) throws -> Configuration {
|
||||
try .init(
|
||||
target: target(),
|
||||
strategy: semvarOptions.gitTag
|
||||
? .semvar(semvarOptions(extraOptions: extraOptions))
|
||||
: .branch(includeCommitSha: commitSha)
|
||||
)
|
||||
}
|
||||
|
||||
func shared(
|
||||
command: String,
|
||||
dryRun: Bool = true,
|
||||
@@ -177,12 +185,11 @@ extension ConfigurationOptions {
|
||||
try .init(
|
||||
allowPreReleaseTag: !semvarOptions.preRelease.disablePreRelease,
|
||||
dryRun: dryRun,
|
||||
gitDirectory: gitDirectory,
|
||||
projectDirectory: gitDirectory,
|
||||
loggingOptions: .init(command: command, verbose: verbose),
|
||||
target: target(),
|
||||
branch: semvarOptions.gitTag ? nil : .init(includeCommitSha: commitSha),
|
||||
semvar: semvarOptions(extraOptions: extraOptions),
|
||||
configurationFile: configurationFile
|
||||
configurationToMerge: configurationToMerge(extraOptions: extraOptions),
|
||||
configurationFile: configurationFile,
|
||||
requireConfigurationFile: requireConfiguration
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,35 +36,46 @@ public struct CliClient: Sendable {
|
||||
case major, minor, patch, preRelease
|
||||
}
|
||||
|
||||
/// Represents options that are used by all the commands.
|
||||
public struct SharedOptions: Equatable, Sendable {
|
||||
|
||||
/// Whether to allow pre-release suffixes.
|
||||
let allowPreReleaseTag: Bool
|
||||
|
||||
/// Flag on if we write to files or not.
|
||||
let dryRun: Bool
|
||||
let gitDirectory: String?
|
||||
|
||||
/// Specify a path to the project directory.
|
||||
let projectDirectory: String?
|
||||
|
||||
/// The logging options to use.
|
||||
let loggingOptions: LoggingOptions
|
||||
let target: Configuration.Target?
|
||||
let branch: Configuration.Branch?
|
||||
let semvar: Configuration.SemVar?
|
||||
|
||||
/// Configuration that gets merged with the loaded (or default) configuration.
|
||||
let configurationToMerge: Configuration?
|
||||
|
||||
/// Path to the configuration file to load.
|
||||
let configurationFile: String?
|
||||
|
||||
/// Fail if a configuration file is not found.
|
||||
let requireConfigurationFile: Bool
|
||||
|
||||
public init(
|
||||
allowPreReleaseTag: Bool = true,
|
||||
dryRun: Bool = false,
|
||||
gitDirectory: String? = nil,
|
||||
projectDirectory: String? = nil,
|
||||
loggingOptions: LoggingOptions,
|
||||
target: Configuration.Target? = nil,
|
||||
branch: Configuration.Branch? = nil,
|
||||
semvar: Configuration.SemVar? = nil,
|
||||
configurationFile: String? = nil
|
||||
configurationToMerge: Configuration? = nil,
|
||||
configurationFile: String? = nil,
|
||||
requireConfigurationFile: Bool = false
|
||||
) {
|
||||
self.allowPreReleaseTag = allowPreReleaseTag
|
||||
self.dryRun = dryRun
|
||||
self.gitDirectory = gitDirectory
|
||||
self.projectDirectory = projectDirectory
|
||||
self.loggingOptions = loggingOptions
|
||||
self.target = target
|
||||
self.branch = branch
|
||||
self.semvar = semvar
|
||||
self.configurationFile = configurationFile
|
||||
self.configurationToMerge = configurationToMerge
|
||||
self.requireConfigurationFile = requireConfigurationFile
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ to come after the plugin name.
|
||||
|
||||
| Option | Description |
|
||||
| ---------- | --------------------------------------------------------------------- |
|
||||
| --dry-run | Do not write to any files, but describe where values would be written |
|
||||
| --print | Do not write to any files, but describe where values would be written |
|
||||
| --filename | Override the file name to be written in the target directory |
|
||||
| --verbose | Increase the logging output |
|
||||
|
||||
@@ -47,7 +47,7 @@ to come after the plugin name.
|
||||
swift package \
|
||||
--allow-writing-to-package-directory \
|
||||
generate-version \
|
||||
--dry-run \
|
||||
--print \
|
||||
--verbose \
|
||||
<target>
|
||||
```
|
||||
|
||||
@@ -25,14 +25,14 @@ public extension CliClient.SharedOptions {
|
||||
logger.trace("\nConfiguration: \(configurationString)")
|
||||
|
||||
// This will fail if the target url is not set properly.
|
||||
let targetUrl = try configuration.targetUrl(gitDirectory: gitDirectory)
|
||||
let targetUrl = try configuration.targetUrl(gitDirectory: projectDirectory)
|
||||
logger.debug("Target: \(targetUrl.cleanFilePath)")
|
||||
|
||||
// Perform the operation, which generates the new version and writes it.
|
||||
try await operation(
|
||||
configuration.currentVersion(
|
||||
targetUrl: targetUrl,
|
||||
gitDirectory: gitDirectory
|
||||
gitDirectory: projectDirectory
|
||||
)
|
||||
)
|
||||
|
||||
@@ -50,27 +50,20 @@ public extension CliClient.SharedOptions {
|
||||
@Dependency(\.configurationClient) var configurationClient
|
||||
@Dependency(\.logger) var logger
|
||||
|
||||
var strategy: Configuration.VersionStrategy?
|
||||
|
||||
if let branch {
|
||||
if configurationToMerge?.strategy?.branch != nil {
|
||||
logger.trace("Merging branch strategy.")
|
||||
strategy = .branch(branch)
|
||||
} else if let semvar {
|
||||
// strategy = .branch(branch)
|
||||
} else if let semvar = configurationToMerge?.strategy?.semvar {
|
||||
logger.trace("Merging semvar strategy.")
|
||||
var semvarString = ""
|
||||
customDump(semvar, to: &semvarString)
|
||||
logger.trace("\(semvarString)")
|
||||
strategy = .semvar(semvar)
|
||||
}
|
||||
|
||||
let configuration = Configuration(
|
||||
target: target,
|
||||
strategy: strategy
|
||||
)
|
||||
|
||||
return try await configurationClient.withConfiguration(
|
||||
path: configurationFile,
|
||||
merging: configuration,
|
||||
merging: configurationToMerge,
|
||||
strict: requireConfigurationFile,
|
||||
operation: operation
|
||||
)
|
||||
}
|
||||
@@ -82,7 +75,7 @@ public extension CliClient.SharedOptions {
|
||||
try await fileClient.write(string: string, to: url)
|
||||
} else {
|
||||
logger.debug("Skipping, due to dry-run being passed.")
|
||||
logger.info("\n\(string)\n")
|
||||
// logger.info("\n\(string)\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +83,11 @@ public extension CliClient.SharedOptions {
|
||||
@Dependency(\.logger) var logger
|
||||
|
||||
let version = try currentVersion.version.string(allowPreReleaseTag: allowPreReleaseTag)
|
||||
logger.debug("Version: \(version)")
|
||||
if !dryRun {
|
||||
logger.debug("Version: \(version)")
|
||||
} else {
|
||||
logger.info("Version: \(version)")
|
||||
}
|
||||
|
||||
let template = currentVersion.usesOptionalType ? Template.optional(version) : Template.nonOptional(version)
|
||||
logger.trace("Template string: \(template)")
|
||||
@@ -160,6 +157,12 @@ extension CliClient.SharedOptions {
|
||||
}
|
||||
|
||||
logger.debug("Bumped version: \(version)")
|
||||
|
||||
if dryRun {
|
||||
logger.info("Version: \(version)")
|
||||
return
|
||||
}
|
||||
|
||||
let template = usesOptionalType ? Template.optional(version) : Template.build(version)
|
||||
try await write(template, to: container.targetUrl)
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ public extension Configuration {
|
||||
struct PreRelease: Codable, Equatable, Sendable {
|
||||
|
||||
public let prefix: String?
|
||||
// TODO: Remove optional.
|
||||
public let strategy: Strategy?
|
||||
|
||||
public init(
|
||||
@@ -84,7 +83,6 @@ public extension Configuration {
|
||||
public enum Strategy: Codable, Equatable, Sendable {
|
||||
case branch(includeCommitSha: Bool = true)
|
||||
case command(arguments: [String])
|
||||
// TODO: Remove.
|
||||
case gitTag
|
||||
|
||||
public var branch: Branch? {
|
||||
|
||||
@@ -29,11 +29,26 @@ public struct ConfigurationClient: Sendable {
|
||||
public var write: @Sendable (Configuration, URL) async throws -> Void
|
||||
|
||||
/// Find a configuration file and load it if found.
|
||||
public func findAndLoad(_ url: URL? = nil) async throws -> Configuration {
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - url: The optional path to the configuration file.
|
||||
/// - strict: Fail if a configuration file is not found, otherwise return default configuration.
|
||||
public func findAndLoad(_ url: URL? = nil, strict: Bool = true) async throws -> Configuration {
|
||||
guard let url = try? await find(url) else {
|
||||
throw ConfigurationClientError.configurationNotFound
|
||||
if strict {
|
||||
throw ConfigurationClientError.configurationNotFound
|
||||
}
|
||||
return .default
|
||||
}
|
||||
return (try? await load(url)) ?? .default
|
||||
|
||||
let loaded = try? await load(url)
|
||||
guard let loaded else {
|
||||
if strict {
|
||||
throw ConfigurationClientError.configurationNotFound
|
||||
}
|
||||
return .default
|
||||
}
|
||||
return loaded
|
||||
}
|
||||
|
||||
/// Loads configuration from the given path, or searches for the default file and loads it.
|
||||
@@ -47,10 +62,12 @@ public struct ConfigurationClient: Sendable {
|
||||
public func withConfiguration<T>(
|
||||
path: String?,
|
||||
merging other: Configuration? = nil,
|
||||
strict: Bool = true,
|
||||
operation: (Configuration) async throws -> T
|
||||
) async throws -> T {
|
||||
let configuration = try await findAndLoad(
|
||||
path != nil ? URL(filePath: path!) : nil
|
||||
path != nil ? URL(filePath: path!) : nil,
|
||||
strict: strict
|
||||
)
|
||||
return try await operation(configuration.merging(other))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user