wip
This commit is contained in:
@@ -106,10 +106,20 @@ public struct FileClient {
|
||||
try self.write(data, url)
|
||||
}
|
||||
|
||||
/// Write's the given string to a file.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - string: The string to write to the file.
|
||||
/// - url: The file url.
|
||||
public func write(string: String, to url: URL) throws {
|
||||
try self.write(Data(string.utf8), url)
|
||||
}
|
||||
|
||||
/// Write's the the string to a file path.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - string: The string to write to the file.
|
||||
/// - path: The file path.
|
||||
public func write(string: String, to path: String) throws {
|
||||
let url = try url(for: path)
|
||||
try self.write(string: string, to: url)
|
||||
|
||||
@@ -105,8 +105,6 @@ extension ShellClient {
|
||||
/// Reads contents at the given file path, then allows the caller to act on the
|
||||
/// results after "nil" has been replaced with the current version string.
|
||||
///
|
||||
/// > Note: The file contents will be reset back to nil after the closure operation.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - filePath: The file path to replace nil in.
|
||||
/// - workingDirectory: Customize the working directory for the command.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import Foundation
|
||||
import GitVersion
|
||||
import ShellClient
|
||||
|
||||
/// Shows the intended use-case for building a command line tool that set's the version
|
||||
/// based on the tag in the git worktree.
|
||||
|
||||
@main
|
||||
public struct Build {
|
||||
public static func main() throws {
|
||||
@Dependency(\.shellClient) var shell: ShellClient
|
||||
|
||||
let gitDir = URL(fileURLWithPath: #file)
|
||||
.deletingLastPathComponent()
|
||||
.deletingLastPathComponent()
|
||||
.deletingLastPathComponent()
|
||||
|
||||
try withDependencies {
|
||||
$0.gitVersionClient = .liveValue
|
||||
$0.logger.logLevel = .debug
|
||||
} operation: {
|
||||
try shell.replacingNilWithVersionString(
|
||||
in: "Sources/example/Version.swift",
|
||||
from: gitDir.absoluteString,
|
||||
build: SwiftBuild.release()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
// Do not change this value, it is set by the build script.
|
||||
let VERSION: String? = nil
|
||||
@@ -1,23 +0,0 @@
|
||||
import ArgumentParser
|
||||
import ShellClient
|
||||
|
||||
/// An example of using the git version client with a command line tool
|
||||
/// The ``VERSION`` variable get's set during the build process.
|
||||
@main
|
||||
public struct Example: ParsableCommand {
|
||||
|
||||
public static let configuration: CommandConfiguration = .init(
|
||||
abstract: "An example of using the `GitVersion` command to set the version for a command line app.",
|
||||
version: VERSION ?? "0.0.0"
|
||||
)
|
||||
|
||||
public init() { }
|
||||
|
||||
public func run() throws {
|
||||
@Dependency(\.logger) var logger: Logger
|
||||
|
||||
let version = (VERSION ?? "0.0.0").blue
|
||||
logger.info("Version: \(version)")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
import ArgumentParser
|
||||
import Dependencies
|
||||
import GitVersion
|
||||
import ShellClient
|
||||
|
||||
@main
|
||||
public struct GitVersionBuilder: AsyncParsableCommand {
|
||||
|
||||
public init() { }
|
||||
|
||||
@Argument
|
||||
var input: String
|
||||
|
||||
@Argument
|
||||
var output: String
|
||||
|
||||
public func run() async throws {
|
||||
@Dependency(\.logger) var logger
|
||||
@Dependency(\.fileClient) var fileClient
|
||||
@Dependency(\.shellClient) var shell: ShellClient
|
||||
|
||||
logger.debug("Building with input file: \(input)")
|
||||
logger.debug("Output file: \(output)")
|
||||
|
||||
try shell.replacingNilWithVersionString(
|
||||
in: input
|
||||
) { update in
|
||||
logger.debug("Updating with:\n\(update)")
|
||||
try fileClient.write(string: update, to: output)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
49
Sources/git-version/GenerateCommand.swift
Normal file
49
Sources/git-version/GenerateCommand.swift
Normal file
@@ -0,0 +1,49 @@
|
||||
import ArgumentParser
|
||||
import Dependencies
|
||||
import Foundation
|
||||
import GitVersion
|
||||
import ShellClient
|
||||
|
||||
extension GitVersionCommand {
|
||||
|
||||
struct Generate: ParsableCommand {
|
||||
static var configuration: CommandConfiguration = .init(
|
||||
abstract: "Generates a version file in a command line tool that can be set via the git tag or git sha."
|
||||
)
|
||||
|
||||
@OptionGroup var shared: SharedOptions
|
||||
|
||||
func run() throws {
|
||||
@Dependency(\.logger) var logger: Logger
|
||||
@Dependency(\.fileClient) var fileClient
|
||||
|
||||
let targetUrl = parseTarget(shared.target)
|
||||
let fileUrl = targetUrl.appendingPathComponent(shared.fileName)
|
||||
|
||||
let fileString = fileUrl.fileString()
|
||||
|
||||
guard !FileManager.default.fileExists(atPath: fileUrl.absoluteString) else {
|
||||
logger.info("File already exists at path.")
|
||||
throw GenerationError.fileExists(path: fileString)
|
||||
}
|
||||
|
||||
if !shared.dryRun {
|
||||
try fileClient.write(string: template, to: fileUrl)
|
||||
logger.info("Generated file at: \(fileString)")
|
||||
} else {
|
||||
logger.info("Would generate file at: \(fileString)")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate enum GenerationError: Error {
|
||||
case fileExists(path: String)
|
||||
}
|
||||
|
||||
fileprivate let template = """
|
||||
// Do not set this variable, it is set during the build process.
|
||||
let VERSION: String? = nil
|
||||
|
||||
"""
|
||||
30
Sources/git-version/GitVersionCommand.swift
Normal file
30
Sources/git-version/GitVersionCommand.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
|
||||
@main
|
||||
struct GitVersionCommand: ParsableCommand {
|
||||
|
||||
static var configuration: CommandConfiguration = .init(
|
||||
commandName: "git-version",
|
||||
version: VERSION ?? "0.0.0",
|
||||
subcommands: [
|
||||
Generate.self,
|
||||
Update.self
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
struct SharedOptions: ParsableArguments {
|
||||
|
||||
@Argument(help: "The target for the version file.")
|
||||
var target: String
|
||||
|
||||
@Option(
|
||||
name: .customLong("filename"),
|
||||
help: "Specify the file name for the version file."
|
||||
)
|
||||
var fileName: String = "Version.swift"
|
||||
|
||||
@Flag(name: .customLong("dry-run"))
|
||||
var dryRun: Bool = false
|
||||
}
|
||||
20
Sources/git-version/Helpers.swift
Normal file
20
Sources/git-version/Helpers.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
import Foundation
|
||||
|
||||
func parseTarget(_ target: String) -> URL {
|
||||
let url = URL(fileURLWithPath: target)
|
||||
let urlTest = url
|
||||
.deletingLastPathComponent()
|
||||
|
||||
guard urlTest.lastPathComponent == "Sources" else {
|
||||
return URL(fileURLWithPath: "Sources")
|
||||
.appendingPathComponent(target)
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
extension URL {
|
||||
func fileString() -> String {
|
||||
self.absoluteString
|
||||
.replacingOccurrences(of: "file://", with: "")
|
||||
}
|
||||
}
|
||||
66
Sources/git-version/UpdateCommand.swift
Normal file
66
Sources/git-version/UpdateCommand.swift
Normal file
@@ -0,0 +1,66 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
import GitVersion
|
||||
import ShellClient
|
||||
|
||||
extension GitVersionCommand {
|
||||
|
||||
struct Update: ParsableCommand {
|
||||
static var configuration: CommandConfiguration = .init(
|
||||
abstract: "Updates a version string to the git tag or git sha."
|
||||
)
|
||||
|
||||
@OptionGroup var shared: SharedOptions
|
||||
|
||||
@Option(
|
||||
name: .customLong("git-directory"),
|
||||
help: "The git directory for the version."
|
||||
)
|
||||
var gitDirectory: String? = nil
|
||||
|
||||
func run() throws {
|
||||
@Dependency(\.logger) var logger: Logger
|
||||
@Dependency(\.fileClient) var fileClient: FileClient
|
||||
@Dependency(\.gitVersionClient) var gitVersion
|
||||
@Dependency(\.shellClient) var shell
|
||||
|
||||
let targetUrl = parseTarget(shared.target)
|
||||
let fileUrl = targetUrl.appendingPathComponent(shared.fileName)
|
||||
let fileString = fileUrl.fileString()
|
||||
|
||||
// guard FileManager.default.fileExists(atPath: fileUrl.absoluteString) else {
|
||||
// logger.info("Version file does not exist.")
|
||||
// throw UpdateError.versionFileDoesNotExist(path: fileString)
|
||||
// }
|
||||
|
||||
let currentVersion = try gitVersion.currentVersion()
|
||||
let cwd = FileManager.default.currentDirectoryPath
|
||||
logger.info("CWD: \(cwd)")
|
||||
logger.info("Git version: \(currentVersion)")
|
||||
|
||||
var updatedContents: String = ""
|
||||
try withDependencies({
|
||||
$0.logger.logLevel = .debug
|
||||
}, operation: {
|
||||
try shell.replacingNilWithVersionString(
|
||||
in: fileString
|
||||
// from: gitDirectory
|
||||
) {
|
||||
updatedContents = $0
|
||||
}
|
||||
})
|
||||
|
||||
if !shared.dryRun {
|
||||
try fileClient.write(string: updatedContents, to: fileUrl)
|
||||
logger.info("Updated version file: \(fileString)")
|
||||
} else {
|
||||
logger.info("Would update file contents to:")
|
||||
logger.info("\(updatedContents)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate enum UpdateError: Error {
|
||||
case versionFileDoesNotExist(path: String)
|
||||
}
|
||||
2
Sources/git-version/Version.swift
Normal file
2
Sources/git-version/Version.swift
Normal file
@@ -0,0 +1,2 @@
|
||||
// Do not set this variable, it is set during the build process.
|
||||
let VERSION: String? = ""
|
||||
Reference in New Issue
Block a user