From 51bbe1a2cf2feed410cd0ead5d6fae0d47f5f310 Mon Sep 17 00:00:00 2001 From: Mads Odgaard Date: Fri, 14 Nov 2025 10:01:27 +0100 Subject: [PATCH 1/3] Add option to set custom proto path --- PluginExamples/Package.swift | 10 ++++++++++ PluginExamples/Sources/CustomProtoPath/empty.swift | 3 +++ .../Sources/CustomProtoPath/protos/Bar/Bar.proto | 5 +++++ .../Sources/CustomProtoPath/protos/Foo/Foo.proto | 7 +++++++ .../Sources/CustomProtoPath/protos/Main.proto | 9 +++++++++ .../CustomProtoPath/swift-protobuf-config.json | 13 +++++++++++++ .../Sources/ExampleTests/ExampleTests.swift | 9 +++++++++ Plugins/SwiftProtobufPlugin/plugin.swift | 14 ++++++++++---- 8 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 PluginExamples/Sources/CustomProtoPath/empty.swift create mode 100644 PluginExamples/Sources/CustomProtoPath/protos/Bar/Bar.proto create mode 100644 PluginExamples/Sources/CustomProtoPath/protos/Foo/Foo.proto create mode 100644 PluginExamples/Sources/CustomProtoPath/protos/Main.proto create mode 100644 PluginExamples/Sources/CustomProtoPath/swift-protobuf-config.json diff --git a/PluginExamples/Package.swift b/PluginExamples/Package.swift index 31d062239..92a6fa13b 100644 --- a/PluginExamples/Package.swift +++ b/PluginExamples/Package.swift @@ -47,6 +47,15 @@ let package = Package( .plugin(name: "SwiftProtobufPlugin", package: "swift-protobuf") ] ), + .target( + name: "CustomProtoPath", + dependencies: [ + .product(name: "SwiftProtobuf", package: "swift-protobuf") + ], + plugins: [ + .plugin(name: "SwiftProtobufPlugin", package: "swift-protobuf") + ] + ), .testTarget( name: "ExampleTests", dependencies: [ @@ -54,6 +63,7 @@ let package = Package( .target(name: "Nested"), .target(name: "Import"), .target(name: "AccessLevelOnImport"), + .target(name: "CustomProtoPath"), ] ), ], diff --git a/PluginExamples/Sources/CustomProtoPath/empty.swift b/PluginExamples/Sources/CustomProtoPath/empty.swift new file mode 100644 index 000000000..d4445d2a5 --- /dev/null +++ b/PluginExamples/Sources/CustomProtoPath/empty.swift @@ -0,0 +1,3 @@ +/// DO NOT DELETE. +/// +/// We need to keep this file otherwise the plugin is not running. diff --git a/PluginExamples/Sources/CustomProtoPath/protos/Bar/Bar.proto b/PluginExamples/Sources/CustomProtoPath/protos/Bar/Bar.proto new file mode 100644 index 000000000..8e672a88c --- /dev/null +++ b/PluginExamples/Sources/CustomProtoPath/protos/Bar/Bar.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message Bar { + string name = 1; +} diff --git a/PluginExamples/Sources/CustomProtoPath/protos/Foo/Foo.proto b/PluginExamples/Sources/CustomProtoPath/protos/Foo/Foo.proto new file mode 100644 index 000000000..c7dbff913 --- /dev/null +++ b/PluginExamples/Sources/CustomProtoPath/protos/Foo/Foo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "Bar/Bar.proto"; + +message Foo { + Bar bar = 1; +} diff --git a/PluginExamples/Sources/CustomProtoPath/protos/Main.proto b/PluginExamples/Sources/CustomProtoPath/protos/Main.proto new file mode 100644 index 000000000..18b17a89a --- /dev/null +++ b/PluginExamples/Sources/CustomProtoPath/protos/Main.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "Bar/Bar.proto"; +import "Foo/Foo.proto"; + +message Main { + Bar bar = 1; + Foo foo = 2; +} \ No newline at end of file diff --git a/PluginExamples/Sources/CustomProtoPath/swift-protobuf-config.json b/PluginExamples/Sources/CustomProtoPath/swift-protobuf-config.json new file mode 100644 index 000000000..24722c38d --- /dev/null +++ b/PluginExamples/Sources/CustomProtoPath/swift-protobuf-config.json @@ -0,0 +1,13 @@ +{ + "invocations": [ + { + "protoFiles": [ + "Bar/Bar.proto", + "Foo/Foo.proto", + "Main.proto" + ], + "visibility": "public", + "protoPath": "protos" + } + ] +} diff --git a/PluginExamples/Sources/ExampleTests/ExampleTests.swift b/PluginExamples/Sources/ExampleTests/ExampleTests.swift index 1bd2d5354..c59604220 100644 --- a/PluginExamples/Sources/ExampleTests/ExampleTests.swift +++ b/PluginExamples/Sources/ExampleTests/ExampleTests.swift @@ -18,4 +18,13 @@ final class ExampleTests: XCTestCase { let foo = Foo.with { $0.bar = .with { $0.name = "Bar" } } XCTAssertEqual(foo.bar.name, "Bar") } + + func testCustomProtoPath() { + let main = CustomProtoPath.Main.with { + $0.bar = .with { $0.name = "Bar" } + $0.foo = .with { $0.bar = .with { $0.name = "BarInFoo" } } + } + XCTAssertEqual(main.bar.name, "Bar") + XCTAssertEqual(main.foo.bar.name, "BarInFoo") + } } diff --git a/Plugins/SwiftProtobufPlugin/plugin.swift b/Plugins/SwiftProtobufPlugin/plugin.swift index 74af4b966..e82e0a816 100644 --- a/Plugins/SwiftProtobufPlugin/plugin.swift +++ b/Plugins/SwiftProtobufPlugin/plugin.swift @@ -86,6 +86,8 @@ struct SwiftProtobufPlugin { var implementationOnlyImports: Bool? /// Whether import statements should be preceded with visibility. var useAccessLevelOnImports: Bool? + /// Overrides the path to look for protobuf files + var protoPath: String? } /// The path to the `protoc` binary. @@ -171,10 +173,14 @@ struct SwiftProtobufPlugin { "--swift_out=\(outputDirectory)", ] - // We need to add the target directory as a search path since we require the user to specify - // the proto files relative to it. + let protoDirectory = if let protoPath = invocation.protoPath { + directory.appending(protoPath) + } else { + directory + } + protocArgs.append("-I") - protocArgs.append("\(directory)") + protocArgs.append("\(protoDirectory)") // Add the visibility if it was set if let visibility = invocation.visibility { @@ -202,7 +208,7 @@ struct SwiftProtobufPlugin { 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(protoDirectory.appending(file)) // 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 From 7e22b8eb1c7d421795a421e2bac0598f21139eae Mon Sep 17 00:00:00 2001 From: Mads Odgaard Date: Mon, 1 Dec 2025 12:09:39 +0100 Subject: [PATCH 2/3] fix test --- PluginExamples/Sources/ExampleTests/ExampleTests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/PluginExamples/Sources/ExampleTests/ExampleTests.swift b/PluginExamples/Sources/ExampleTests/ExampleTests.swift index c59604220..a928ad8a8 100644 --- a/PluginExamples/Sources/ExampleTests/ExampleTests.swift +++ b/PluginExamples/Sources/ExampleTests/ExampleTests.swift @@ -2,6 +2,7 @@ import Import import Nested import Simple import XCTest +import CustomProtoPath final class ExampleTests: XCTestCase { func testSimple() { From 09fdc4e5392e5994bf81e3fb7ef4aba288504962 Mon Sep 17 00:00:00 2001 From: Mads Odgaard Date: Mon, 1 Dec 2025 12:10:14 +0100 Subject: [PATCH 3/3] format --- .../Sources/ExampleTests/ExampleTests.swift | 2 +- Plugins/SwiftProtobufPlugin/plugin.swift | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/PluginExamples/Sources/ExampleTests/ExampleTests.swift b/PluginExamples/Sources/ExampleTests/ExampleTests.swift index a928ad8a8..5d05e05af 100644 --- a/PluginExamples/Sources/ExampleTests/ExampleTests.swift +++ b/PluginExamples/Sources/ExampleTests/ExampleTests.swift @@ -1,8 +1,8 @@ +import CustomProtoPath import Import import Nested import Simple import XCTest -import CustomProtoPath final class ExampleTests: XCTestCase { func testSimple() { diff --git a/Plugins/SwiftProtobufPlugin/plugin.swift b/Plugins/SwiftProtobufPlugin/plugin.swift index e82e0a816..4249c45e0 100644 --- a/Plugins/SwiftProtobufPlugin/plugin.swift +++ b/Plugins/SwiftProtobufPlugin/plugin.swift @@ -173,11 +173,12 @@ struct SwiftProtobufPlugin { "--swift_out=\(outputDirectory)", ] - let protoDirectory = if let protoPath = invocation.protoPath { - directory.appending(protoPath) - } else { - directory - } + let protoDirectory = + if let protoPath = invocation.protoPath { + directory.appending(protoPath) + } else { + directory + } protocArgs.append("-I") protocArgs.append("\(protoDirectory)")