wip
This commit is contained in:
@@ -9,7 +9,8 @@ let package = Package(
|
||||
],
|
||||
products: [
|
||||
.library(name: "GitVersion", targets: ["GitVersion"]),
|
||||
.plugin(name: "GenerateVersionPlugin", targets: ["GenerateVersionPlugin"])
|
||||
.plugin(name: "GenerateVersionPlugin", targets: ["GenerateVersionPlugin"]),
|
||||
.plugin(name: "UpdateVersionPlugin", targets: ["UpdateVersionPlugin"])
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/m-housh/swift-shell-client.git", from: "0.1.0"),
|
||||
@@ -48,6 +49,21 @@ let package = Package(
|
||||
dependencies: [
|
||||
"git-version"
|
||||
]
|
||||
),
|
||||
.plugin(
|
||||
name: "UpdateVersionPlugin",
|
||||
capability: .command(
|
||||
intent: .custom(
|
||||
verb: "update-version",
|
||||
description: "Updates a version file in the given target."
|
||||
),
|
||||
permissions: [
|
||||
.writeToPackageDirectory(reason: "Update a version file in the target's directory.")
|
||||
]
|
||||
),
|
||||
dependencies: [
|
||||
"git-version"
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ struct GenerateVersionPlugin: CommandPlugin {
|
||||
func performCommand(context: PluginContext, arguments: [String]) async throws {
|
||||
let gitVersion = try context.tool(named: "git-version")
|
||||
|
||||
var arguments = ["generate"] + arguments
|
||||
let arguments = ["generate"] + arguments
|
||||
|
||||
for target in context.package.targets {
|
||||
guard let target = target as? SourceModuleTarget,
|
||||
|
||||
29
Plugins/UpdateVersionPlugin/UpdateVersionPlugin.swift
Normal file
29
Plugins/UpdateVersionPlugin/UpdateVersionPlugin.swift
Normal file
@@ -0,0 +1,29 @@
|
||||
import PackagePlugin
|
||||
import Foundation
|
||||
|
||||
@main
|
||||
struct UpdateVersionPlugin: CommandPlugin {
|
||||
|
||||
func performCommand(context: PluginContext, arguments: [String]) async throws {
|
||||
let gitVersion = try context.tool(named: "git-version")
|
||||
|
||||
let arguments = ["update"] + arguments
|
||||
|
||||
for target in context.package.targets {
|
||||
guard let target = target as? SourceModuleTarget,
|
||||
arguments.first(where: { $0.contains(target.name) }) != nil
|
||||
else { continue }
|
||||
|
||||
let process = Process()
|
||||
process.executableURL = URL(fileURLWithPath: gitVersion.path.string)
|
||||
process.arguments = arguments
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
|
||||
guard process.terminationReason == .exit && process.terminationStatus == 0 else {
|
||||
Diagnostics.error("Reason: \(process.terminationReason), status: \(process.terminationStatus)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ fileprivate struct GitVersion {
|
||||
.init(
|
||||
shell: .env,
|
||||
environment: nil,
|
||||
in: workingDirectory,
|
||||
in: workingDirectory ?? FileManager.default.currentDirectoryPath,
|
||||
argument.arguments
|
||||
)
|
||||
}
|
||||
|
||||
@@ -100,90 +100,92 @@ public struct SwiftBuild {
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - filePath: The file path to replace nil in.
|
||||
/// - workingDirectory: Customize the working directory for the command.
|
||||
/// - closure: The closure to run with the updated file content string.
|
||||
public func replacingNilWithVersionString(
|
||||
in filePath: String,
|
||||
from workingDirectory: String? = nil,
|
||||
_ closure: @escaping (String) throws -> Void
|
||||
) throws {
|
||||
@Dependency(\.fileClient) var fileClient: FileClient
|
||||
@Dependency(\.gitVersionClient) var gitClient: GitVersionClient
|
||||
@Dependency(\.logger) var logger: Logger
|
||||
|
||||
let currentVersion = try gitClient.currentVersion(in: workingDirectory)
|
||||
let originalContents = try fileClient.readAsString(path: filePath)
|
||||
|
||||
logger.debug("Setting version: \(currentVersion)")
|
||||
|
||||
let updatedContents = originalContents
|
||||
.replacingOccurrences(of: "nil", with: "\"\(currentVersion)\"")
|
||||
|
||||
logger.debug("Set version")
|
||||
|
||||
try closure(updatedContents)
|
||||
}
|
||||
|
||||
|
||||
/// Replace nil in the given file path and then run the given closure.
|
||||
///
|
||||
/// > 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.
|
||||
/// - build: The swift builder to use.
|
||||
public func replacingNilWithVersionString(
|
||||
in filePath: String,
|
||||
from workingDirectory: String? = nil,
|
||||
_ closure: @escaping () throws -> Void
|
||||
) throws {
|
||||
@Dependency(\.fileClient) var fileClient: FileClient
|
||||
@Dependency(\.logger) var logger: Logger
|
||||
|
||||
// grab the original contents, to set it back when done.
|
||||
let originalContents = try fileClient.readAsString(path: filePath)
|
||||
|
||||
try self.replacingNilWithVersionString(
|
||||
in: filePath,
|
||||
from: workingDirectory
|
||||
) { update in
|
||||
try fileClient.write(string: update, to: filePath)
|
||||
defer { try! fileClient.write(string: originalContents, to: filePath) }
|
||||
|
||||
try closure()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Replace nil in the given file path and then build the project, using the
|
||||
/// given builder.
|
||||
///
|
||||
/// > Note: The file contents will be reset back to nil after the build operation.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - filePath: The file path to replace nil in.
|
||||
/// - workingDirectory: Customize the working directory for the command.
|
||||
/// - build: The swift builder to use.
|
||||
public func replacingNilWithVersionString(
|
||||
in filePath: String,
|
||||
from workingDirectory: String? = nil,
|
||||
build: SwiftBuild
|
||||
) throws {
|
||||
try replacingNilWithVersionString(
|
||||
in: filePath,
|
||||
from: workingDirectory,
|
||||
build.run
|
||||
)
|
||||
}
|
||||
}
|
||||
//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.
|
||||
// ///
|
||||
// /// - Parameters:
|
||||
// /// - filePath: The file path to replace nil in.
|
||||
// /// - workingDirectory: Customize the working directory for the command.
|
||||
// /// - closure: The closure to run with the updated file content string.
|
||||
// public func replacingNilWithVersionString(
|
||||
// in filePath: String,
|
||||
// from workingDirectory: String? = nil,
|
||||
// _ closure: @escaping (String) throws -> Void
|
||||
// ) throws {
|
||||
// @Dependency(\.fileClient) var fileClient: FileClient
|
||||
// @Dependency(\.gitVersionClient) var gitClient: GitVersionClient
|
||||
// @Dependency(\.logger) var logger: Logger
|
||||
//
|
||||
// let currentVersion = try gitClient.currentVersion(in: workingDirectory)
|
||||
// let originalContents = try fileClient.readAsString(path: filePath)
|
||||
//
|
||||
// logger.debug("Setting version: \(currentVersion)")
|
||||
//
|
||||
// let updatedContents = originalContents
|
||||
// .replacingOccurrences(of: "nil", with: "\"\(currentVersion)\"")
|
||||
//
|
||||
// logger.debug("Set version")
|
||||
// logger.debug("Updated contents:")
|
||||
// logger.debug("\(updatedContents)")
|
||||
//
|
||||
// try closure(updatedContents)
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /// Replace nil in the given file path and then run the given closure.
|
||||
// ///
|
||||
// /// > 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.
|
||||
// /// - build: The swift builder to use.
|
||||
// public func replacingNilWithVersionString(
|
||||
// in filePath: String,
|
||||
// from workingDirectory: String? = nil,
|
||||
// _ closure: @escaping () throws -> Void
|
||||
// ) throws {
|
||||
// @Dependency(\.fileClient) var fileClient: FileClient
|
||||
// @Dependency(\.logger) var logger: Logger
|
||||
//
|
||||
// // grab the original contents, to set it back when done.
|
||||
// let originalContents = try fileClient.readAsString(path: filePath)
|
||||
//
|
||||
// try self.replacingNilWithVersionString(
|
||||
// in: filePath,
|
||||
// from: workingDirectory
|
||||
// ) { update in
|
||||
// try fileClient.write(string: update, to: filePath)
|
||||
// defer { try! fileClient.write(string: originalContents, to: filePath) }
|
||||
//
|
||||
// try closure()
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /// Replace nil in the given file path and then build the project, using the
|
||||
// /// given builder.
|
||||
// ///
|
||||
// /// > Note: The file contents will be reset back to nil after the build operation.
|
||||
// ///
|
||||
// /// - Parameters:
|
||||
// /// - filePath: The file path to replace nil in.
|
||||
// /// - workingDirectory: Customize the working directory for the command.
|
||||
// /// - build: The swift builder to use.
|
||||
// public func replacingNilWithVersionString(
|
||||
// in filePath: String,
|
||||
// from workingDirectory: String? = nil,
|
||||
// build: SwiftBuild
|
||||
// ) throws {
|
||||
// try replacingNilWithVersionString(
|
||||
// in: filePath,
|
||||
// from: workingDirectory,
|
||||
// build.run
|
||||
// )
|
||||
// }
|
||||
//}
|
||||
|
||||
fileprivate extension Array where Element == SwiftBuild.Argument {
|
||||
|
||||
|
||||
@@ -42,8 +42,3 @@ 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
|
||||
|
||||
"""
|
||||
|
||||
@@ -14,17 +14,3 @@ struct GitVersionCommand: ParsableCommand {
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
|
||||
func parseTarget(_ target: String) -> URL {
|
||||
@@ -18,3 +19,27 @@ extension URL {
|
||||
.replacingOccurrences(of: "file://", with: "")
|
||||
}
|
||||
}
|
||||
|
||||
let template = """
|
||||
// Do not set this variable, it is set during the build process.
|
||||
let VERSION: String? = nil
|
||||
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
@Flag(name: .long, help: "Increase logging level.")
|
||||
var verbose: Bool = false
|
||||
}
|
||||
|
||||
@@ -19,43 +19,35 @@ extension GitVersionCommand {
|
||||
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
|
||||
try withDependencies {
|
||||
$0.logger.logLevel = shared.verbose ? .debug : .info
|
||||
$0.fileClient = .liveValue
|
||||
$0.gitVersionClient = .liveValue
|
||||
$0.shellClient = .liveValue
|
||||
} operation: {
|
||||
@Dependency(\.gitVersionClient) var gitVersion
|
||||
@Dependency(\.fileClient) var fileClient
|
||||
@Dependency(\.logger) var logger
|
||||
@Dependency(\.shellClient) var shell
|
||||
|
||||
let targetUrl = parseTarget(shared.target)
|
||||
let fileUrl = targetUrl.appendingPathComponent(shared.fileName)
|
||||
let fileString = fileUrl.fileString()
|
||||
let targetUrl = parseTarget(shared.target)
|
||||
let fileUrl = targetUrl
|
||||
.appendingPathComponent(shared.fileName)
|
||||
|
||||
// guard FileManager.default.fileExists(atPath: fileUrl.absoluteString) else {
|
||||
// logger.info("Version file does not exist.")
|
||||
// throw UpdateError.versionFileDoesNotExist(path: fileString)
|
||||
// }
|
||||
let fileString = fileUrl.fileString()
|
||||
|
||||
let currentVersion = try gitVersion.currentVersion()
|
||||
let cwd = FileManager.default.currentDirectoryPath
|
||||
logger.info("CWD: \(cwd)")
|
||||
logger.info("Git version: \(currentVersion)")
|
||||
let currentVersion = try gitVersion.currentVersion(in: gitDirectory)
|
||||
|
||||
var updatedContents: String = ""
|
||||
try withDependencies({
|
||||
$0.logger.logLevel = .debug
|
||||
}, operation: {
|
||||
try shell.replacingNilWithVersionString(
|
||||
in: fileString
|
||||
// from: gitDirectory
|
||||
) {
|
||||
updatedContents = $0
|
||||
let fileContents = template
|
||||
.replacingOccurrences(of: "nil", with: "\"\(currentVersion)\"")
|
||||
|
||||
if !shared.dryRun {
|
||||
try fileClient.write(string: fileContents, to: fileUrl)
|
||||
logger.info("Updated version file: \(fileString)")
|
||||
} else {
|
||||
logger.info("Would update file contents to:")
|
||||
logger.info("\(fileContents)")
|
||||
}
|
||||
})
|
||||
|
||||
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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// Do not set this variable, it is set during the build process.
|
||||
let VERSION: String? = ""
|
||||
let VERSION: String? = nil
|
||||
|
||||
@@ -35,6 +35,7 @@ final class GitVersionTests: XCTestCase {
|
||||
// can't really have a predictable result for the live client.
|
||||
XCTAssertNotEqual(version, "blob")
|
||||
|
||||
// print(FileManager.default.currentDirectoryPath)
|
||||
// let other = try versionClient.currentVersion()
|
||||
// XCTAssertEqual(version, other)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user