Browse Source

Remove `PathLike` and use `URL` instead (#2269)

Removes the `PathLike` definition from `GRPCSwiftPlugin` and uses `URL`
instead, as this project has a minimum supported version of Swift 6.1
now.
Michael Gecht 1 month ago
parent
commit
5770e23158
1 changed files with 31 additions and 97 deletions
  1. 31 97
      Plugins/GRPCSwiftPlugin/plugin.swift

+ 31 - 97
Plugins/GRPCSwiftPlugin/plugin.swift

@@ -99,42 +99,42 @@ struct GRPCSwiftPlugin {
   ///   - tool: The tool method from the context.
   /// - Returns: The build commands configured based on the arguments.
   func createBuildCommands(
-    pluginWorkDirectory: PathLike,
+    pluginWorkDirectory: URL,
     sourceFiles: FileList,
     tool: (String) throws -> PackagePlugin.PluginContext.Tool
   ) throws -> [Command] {
-    let maybeConfigFile = sourceFiles.map { PathLike($0) }.first {
-      $0.lastComponent == Self.configurationFileName
+    let maybeConfigFile = sourceFiles.map { $0.url }.first {
+      $0.lastPathComponent == Self.configurationFileName
     }
 
     guard let configurationFilePath = maybeConfigFile else {
       throw PluginError.noConfigFound(Self.configurationFileName)
     }
 
-    let data = try Data(contentsOf: URL(configurationFilePath))
+    let data = try Data(contentsOf: configurationFilePath)
     let configuration = try JSONDecoder().decode(Configuration.self, from: data)
 
     try self.validateConfiguration(configuration)
 
-    let targetDirectory = configurationFilePath.removingLastComponent()
-    var importPaths: [PathLike] = [targetDirectory]
+    let targetDirectory = configurationFilePath.deletingLastPathComponent()
+    var importPaths: [URL] = [targetDirectory]
     if let configuredImportPaths = configuration.importPaths {
-      importPaths.append(contentsOf: configuredImportPaths.map { PathLike($0) })
+      importPaths.append(contentsOf: configuredImportPaths.map { URL(fileURLWithPath: $0) })
     }
 
     // We need to find the path of protoc and protoc-gen-grpc-swift
-    let protocPath: PathLike
+    let protocPath: URL
     if let configuredProtocPath = configuration.protocPath {
-      protocPath = PathLike(configuredProtocPath)
+      protocPath = URL(fileURLWithPath: configuredProtocPath)
     } else if let environmentPath = ProcessInfo.processInfo.environment["PROTOC_PATH"] {
       // The user set the env variable, so let's take that
-      protocPath = PathLike(environmentPath)
+      protocPath = URL(fileURLWithPath: environmentPath)
     } else {
       // The user didn't set anything so let's try see if SPM can find a binary for us
-      protocPath = try PathLike(tool("protoc"))
+      protocPath = try tool("protoc").url
     }
 
-    let protocGenGRPCSwiftPath = try PathLike(tool("protoc-gen-grpc-swift"))
+    let protocGenGRPCSwiftPath = try tool("protoc-gen-grpc-swift").url
 
     return configuration.invocations.map { invocation in
       self.invokeProtoc(
@@ -159,22 +159,22 @@ struct GRPCSwiftPlugin {
   ///   - importPaths: List of paths to pass with "-I <path>" to `protoc`.
   /// - Returns: The build command configured based on the arguments
   private func invokeProtoc(
-    directory: PathLike,
+    directory: URL,
     invocation: Configuration.Invocation,
-    protocPath: PathLike,
-    protocGenGRPCSwiftPath: PathLike,
-    outputDirectory: PathLike,
-    importPaths: [PathLike]
+    protocPath: URL,
+    protocGenGRPCSwiftPath: URL,
+    outputDirectory: URL,
+    importPaths: [URL]
   ) -> Command {
     // Construct the `protoc` arguments.
     var protocArgs = [
-      "--plugin=protoc-gen-grpc-swift=\(protocGenGRPCSwiftPath)",
-      "--grpc-swift_out=\(outputDirectory)",
+      "--plugin=protoc-gen-grpc-swift=\(protocGenGRPCSwiftPath.path())",
+      "--grpc-swift_out=\(outputDirectory.path())",
     ]
 
     importPaths.forEach { path in
       protocArgs.append("-I")
-      protocArgs.append("\(path)")
+      protocArgs.append(path.path())
     }
 
     if let visibility = invocation.visibility {
@@ -201,20 +201,20 @@ struct GRPCSwiftPlugin {
       protocArgs.append("--grpc-swift_opt=_V2=\(v2)")
     }
 
-    var inputFiles = [PathLike]()
-    var outputFiles = [PathLike]()
+    var inputFiles = [URL]()
+    var outputFiles = [URL]()
 
     for var file in invocation.protoFiles {
       // Append the file to the protoc args so that it is used for generating
       protocArgs.append(file)
-      inputFiles.append(directory.appending(file))
+      inputFiles.append(directory.appending(path: file, directoryHint: .notDirectory))
 
       // The name of the output file is based on the name of the input file.
       // We validated in the beginning that every file has the suffix of .proto
       // This means we can just drop the last 5 elements and append the new suffix
       file.removeLast(5)
       file.append("grpc.swift")
-      let protobufOutputPath = outputDirectory.appending(file)
+      let protobufOutputPath = outputDirectory.appending(path: file, directoryHint: .notDirectory)
 
       // Add the outputPath as an output file
       outputFiles.append(protobufOutputPath)
@@ -223,7 +223,10 @@ struct GRPCSwiftPlugin {
         // Remove .swift extension and add .reflection extension
         file.removeLast(5)
         file.append("reflection")
-        let reflectionOutputPath = outputDirectory.appending(file)
+        let reflectionOutputPath = outputDirectory.appending(
+          path: file,
+          directoryHint: .notDirectory
+        )
         outputFiles.append(reflectionOutputPath)
       }
     }
@@ -231,7 +234,7 @@ struct GRPCSwiftPlugin {
     // Construct the command. Specifying the input and output paths lets the build
     // system know when to invoke the command. The output paths are passed on to
     // the rule engine in the build system.
-    return Command.buildCommand(
+    return .buildCommand(
       displayName: "Generating gRPC Swift files from proto files",
       executable: protocPath,
       arguments: protocArgs,
@@ -261,7 +264,7 @@ extension GRPCSwiftPlugin: BuildToolPlugin {
       throw PluginError.invalidTarget("\(type(of: target))")
     }
 
-    let workDirectory = PathLike(context.pluginWorkDirectory)
+    let workDirectory = context.pluginWorkDirectoryURL
 
     return try self.createBuildCommands(
       pluginWorkDirectory: workDirectory,
@@ -271,75 +274,6 @@ extension GRPCSwiftPlugin: BuildToolPlugin {
   }
 }
 
-// 'Path' was effectively deprecated in Swift 6 in favour of URL. ('Effectively' because all
-// methods, properties, and conformances have been deprecated but the type hasn't.) This type wraps
-// either depending on the compiler version.
-struct PathLike: CustomStringConvertible {
-  typealias Value = Path
-
-  private(set) var value: Value
-
-  init(_ value: Value) {
-    self.value = value
-  }
-
-  init(_ path: String) {
-    self.value = Path(path)
-  }
-
-  init(_ element: FileList.Element) {
-    self.value = element.path
-  }
-
-  init(_ element: PluginContext.Tool) {
-    self.value = element.path
-  }
-
-  var description: String {
-    return String(describing: self.value)
-  }
-
-  var lastComponent: String {
-    return self.value.lastComponent
-  }
-
-  func removingLastComponent() -> Self {
-    var copy = self
-    copy.value = self.value.removingLastComponent()
-    return copy
-  }
-
-  func appending(_ path: String) -> Self {
-    var copy = self
-    copy.value = self.value.appending(path)
-    return copy
-  }
-}
-
-extension Command {
-  static func buildCommand(
-    displayName: String?,
-    executable: PathLike,
-    arguments: [String],
-    inputFiles: [PathLike],
-    outputFiles: [PathLike]
-  ) -> PackagePlugin.Command {
-    return Self.buildCommand(
-      displayName: displayName,
-      executable: executable.value,
-      arguments: arguments,
-      inputFiles: inputFiles.map { $0.value },
-      outputFiles: outputFiles.map { $0.value }
-    )
-  }
-}
-
-extension URL {
-  init(_ pathLike: PathLike) {
-    self = URL(fileURLWithPath: "\(pathLike.value)")
-  }
-}
-
 #if canImport(XcodeProjectPlugin)
 import XcodeProjectPlugin
 
@@ -348,7 +282,7 @@ extension GRPCSwiftPlugin: XcodeBuildToolPlugin {
     context: XcodePluginContext,
     target: XcodeTarget
   ) throws -> [Command] {
-    let workDirectory = PathLike(context.pluginWorkDirectory)
+    let workDirectory = context.pluginWorkDirectoryURL
 
     return try self.createBuildCommands(
       pluginWorkDirectory: workDirectory,