diff --git a/Plugins/MetaProtocolCodable/Plugin.swift b/Plugins/MetaProtocolCodable/Plugin.swift index 2279b62b..787cdf06 100644 --- a/Plugins/MetaProtocolCodable/Plugin.swift +++ b/Plugins/MetaProtocolCodable/Plugin.swift @@ -46,36 +46,48 @@ struct MetaProtocolCodable: BuildToolPlugin { ) throws -> [Command] where Context: MetaProtocolCodablePluginContext { // Get config let tool = try context.tool(named: "ProtocolGen") + #if swift(<6) + let toolUrl = URL(string: tool.path.string)! + #else + let toolUrl = tool.url + #endif let config = try fetchConfig(for: target) let (allTargets, imports) = config.scanInput(for: target, in: context) // Setup folder - let genFolder = context.pluginWorkDirectory.appending(["ProtocolGen"]) + let genFolder = context.pluginWorkDirectoryURL.appending(path: "ProtocolGen") try FileManager.default.createDirectory( - atPath: genFolder.string, withIntermediateDirectories: true + at: genFolder, withIntermediateDirectories: true ) // Create source scan commands - var intermFiles: [Path] = [] + var intermFiles: [URL] = [] var buildCommands = allTargets.flatMap { target in return target.sourceFiles(withSuffix: "swift").map { file in let moduleName = target.moduleName - let fileName = file.path.stem + #if swift(<6) + let fileUrl = URL(string: file.path.string)! + #else + let fileUrl = file.url + #endif + let fileName = fileUrl.deletingPathExtension().lastPathComponent let genFileName = "\(moduleName)-\(fileName)-gen.json" - let genFile = genFolder.appending([genFileName]) + let genFile = genFolder.appending(path: genFileName) intermFiles.append(genFile) + + return Command.buildCommand( displayName: """ Parse source file "\(fileName)" in module "\(moduleName)" """, - executable: tool.path, + executable: toolUrl, arguments: [ "parse", - file.path.string, + fileUrl.absoluteString, "--output", - genFile.string, + genFile.absoluteString, ], - inputFiles: [file.path], + inputFiles: [fileUrl], outputFiles: [genFile] ) } @@ -84,20 +96,20 @@ struct MetaProtocolCodable: BuildToolPlugin { // Create syntax generation command let moduleName = target.moduleName let genFileName = "\(moduleName)+ProtocolHelperCoders.swift" - let genPath = genFolder.appending(genFileName) - var genArgs = ["generate", "--output", genPath.string] + let genPath = genFolder.appending(path: genFileName) + var genArgs = ["generate", "--output", genPath.absoluteString] for `import` in imports { genArgs.append(contentsOf: ["--module", `import`]) } for file in intermFiles { - genArgs.append(file.string) + genArgs.append(file.absoluteString) } buildCommands.append( .buildCommand( displayName: """ Generate protocol decoding/encoding syntax for "\(moduleName)" """, - executable: tool.path, + executable: toolUrl, arguments: genArgs, inputFiles: intermFiles, outputFiles: [genPath] diff --git a/Plugins/MetaProtocolCodable/PluginContext.swift b/Plugins/MetaProtocolCodable/PluginContext.swift index 27a8c14d..3f4f8ffe 100644 --- a/Plugins/MetaProtocolCodable/PluginContext.swift +++ b/Plugins/MetaProtocolCodable/PluginContext.swift @@ -1,4 +1,5 @@ import PackagePlugin +import Foundation /// Provides information about the package for which the plugin is invoked, /// as well as contextual information based on the plugin's stated intent @@ -24,6 +25,8 @@ protocol MetaProtocolCodablePluginContext { /// directories for cache files and other file system content that either /// it or the command will need. var pluginWorkDirectory: Path { get } + var pluginWorkDirectoryURL: URL { get } + /// The targets which are local to current context. /// /// These targets are included in the same package/project as this context. diff --git a/Plugins/MetaProtocolCodable/SourceTarget/SwiftPackageTarget.swift b/Plugins/MetaProtocolCodable/SourceTarget/SwiftPackageTarget.swift index 3258e459..ba9a2943 100644 --- a/Plugins/MetaProtocolCodable/SourceTarget/SwiftPackageTarget.swift +++ b/Plugins/MetaProtocolCodable/SourceTarget/SwiftPackageTarget.swift @@ -1,6 +1,7 @@ import Foundation import PackagePlugin + /// Represents an SwiftPM target. /// /// Uses `SourceModuleTarget` to provide conformances. @@ -11,6 +12,27 @@ struct SwiftPackageTarget { let module: any SourceModuleTarget } +/// This is a workaround because PackageDescription.Target.directoryURL will not be available until version 6.1 +/// See: https://github.com/swiftlang/swift-package-manager/blob/735ddd97fa651729921315c8e46bd790429362cb/Sources/PackagePlugin/PackageModel.swift#L184-L186 +extension PackagePlugin.Target { + var directoryURL: URL { + #if swift(<6) + // No `directoryURL` but `Path` is not deprecated yet + return URL(string: directory.string)! +#else + // Concrete types have `directoryURL` + switch self { + case let target as ClangSourceModuleTarget: + return target.directoryURL + case let target as SwiftSourceModuleTarget: + return target.directoryURL + default: + fatalError("Unsupported target type") + } +#endif + } +} + extension SwiftPackageTarget: MetaProtocolCodableSourceTarget { /// The name of the module produced /// by the target. @@ -64,17 +86,17 @@ extension SwiftPackageTarget: MetaProtocolCodableSourceTarget { /// - Returns: The config file path. func configPath(named name: String) throws -> String? { let fileManager = FileManager.default - let directory = module.directory.string - let contents = try fileManager.contentsOfDirectory(atPath: directory) + let directory = module.directoryURL +// let directory = URL(string: module.directory.string)! + let contents = try fileManager.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) let file = contents.first { file in - let path = Path(file) return name.lowercased() - == path.stem + == file.deletingPathExtension().lastPathComponent .components(separatedBy: .alphanumerics.inverted) .joined(separator: "") .lowercased() } guard let file else { return nil } - return module.directory.appending([file]).string + return directory.appending(path: file.absoluteString).absoluteString } } diff --git a/Sources/ProtocolGen/Generate.swift b/Sources/ProtocolGen/Generate.swift index a17b733b..d9c2474c 100644 --- a/Sources/ProtocolGen/Generate.swift +++ b/Sources/ProtocolGen/Generate.swift @@ -336,7 +336,7 @@ extension ProtocolGen { ) ).description let sourceData = sourceText.data(using: .utf8) - fileManager.createFile(atPath: output, contents: sourceData) + _ = fileManager.createFile(atPath: output, contents: sourceData) } } }