@@ -7134,5 +7134,176 @@ struct PackageCommandTests {
7134
7134
expectNoDiagnostics ( observability. diagnostics)
7135
7135
}
7136
7136
}
7137
+
7138
+ @Test ( arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) )
7139
+ func commandPluginDynamicDependencies(
7140
+ buildData: BuildData
7141
+ ) async throws {
7142
+ try await withKnownIssue {
7143
+ try await testWithTemporaryDirectory { tmpPath in
7144
+ // Create a sample package with a command plugin that has a dynamic dependency.
7145
+ let packageDir = tmpPath. appending ( components: " MyPackage " )
7146
+ try localFileSystem. writeFileContents (
7147
+ packageDir. appending ( components: " Package.swift " ) ,
7148
+ string:
7149
+ """
7150
+ // swift-tools-version: 6.0
7151
+ // The swift-tools-version declares the minimum version of Swift required to build this package.
7152
+
7153
+ import PackageDescription
7154
+
7155
+ let package = Package(
7156
+ name: " command-plugin-dynamic-linking " ,
7157
+ products: [
7158
+ // Products can be used to vend plugins, making them visible to other packages.
7159
+ .plugin(
7160
+ name: " command-plugin-dynamic-linking " ,
7161
+ targets: [ " command-plugin-dynamic-linking " ]),
7162
+ ],
7163
+ dependencies: [
7164
+ .package(path: " LocalPackages/DynamicLib " )
7165
+ ],
7166
+ targets: [
7167
+ // Targets are the basic building blocks of a package, defining a module or a test suite.
7168
+ // Targets can depend on other targets in this package and products from dependencies.
7169
+ .executableTarget(
7170
+ name: " Core " ,
7171
+ dependencies: [
7172
+ .product(name: " DynamicLib " , package: " DynamicLib " )
7173
+ ]
7174
+ ),
7175
+ .plugin(
7176
+ name: " command-plugin-dynamic-linking " ,
7177
+ capability: .command(intent: .custom(
7178
+ verb: " command_plugin_dynamic_linking " ,
7179
+ description: " prints hello world "
7180
+ )),
7181
+ dependencies: [
7182
+ " Core "
7183
+ ]
7184
+ )
7185
+ ]
7186
+ )
7187
+ """
7188
+ )
7189
+ try localFileSystem. writeFileContents (
7190
+ packageDir. appending ( components: " Sources " , " Core " , " Core.swift " ) ,
7191
+ string:
7192
+ """
7193
+ import DynamicLib
7194
+
7195
+ @main
7196
+ struct Core {
7197
+ static func main() {
7198
+ let result = dynamicLibFunc()
7199
+ print(result)
7200
+ }
7201
+ }
7202
+ """
7203
+ )
7204
+ try localFileSystem. writeFileContents (
7205
+ packageDir. appending ( components: " Plugins " , " command-plugin-dynamic-linking.swift " ) ,
7206
+ string:
7207
+ """
7208
+ import PackagePlugin
7209
+ import Foundation
7210
+
7211
+ enum CommandError: Error, CustomStringConvertible {
7212
+ var description: String {
7213
+ String(describing: self)
7214
+ }
7215
+
7216
+ case pluginError(String)
7217
+ }
7218
+
7219
+ @main
7220
+ struct command_plugin_dynamic_linking: CommandPlugin {
7221
+ // Entry point for command plugins applied to Swift Packages.
7222
+ func performCommand(context: PluginContext, arguments: [String]) async throws {
7223
+ let tool = try context.tool(named: " Core " )
7224
+
7225
+ let process = try Process.run(tool.url, arguments: arguments)
7226
+ process.waitUntilExit()
7227
+
7228
+ if process.terminationReason != .exit || process.terminationStatus != 0 {
7229
+ throw CommandError.pluginError( " \\ (tool.name) failed " )
7230
+ } else {
7231
+ print( " Works fine! " )
7232
+ }
7233
+ }
7234
+ }
7235
+
7236
+ #if canImport(XcodeProjectPlugin)
7237
+ import XcodeProjectPlugin
7238
+
7239
+ extension command_plugin_dynamic_linking: XcodeCommandPlugin {
7240
+ // Entry point for command plugins applied to Xcode projects.
7241
+ func performCommand(context: XcodePluginContext, arguments: [String]) throws {
7242
+ print( " Hello, World! " )
7243
+ }
7244
+ }
7245
+
7246
+ #endif
7247
+ """
7248
+ )
7249
+
7250
+ try localFileSystem. writeFileContents (
7251
+ packageDir. appending ( components: " LocalPackages " , " DynamicLib " , " Package.swift " ) ,
7252
+ string:
7253
+ """
7254
+ // swift-tools-version: 6.0
7255
+ // The swift-tools-version declares the minimum version of Swift required to build this package.
7256
+
7257
+ import PackageDescription
7258
+
7259
+ let package = Package(
7260
+ name: " DynamicLib " ,
7261
+ products: [
7262
+ // Products define the executables and libraries a package produces, making them visible to other packages.
7263
+ .library(
7264
+ name: " DynamicLib " ,
7265
+ type: .dynamic,
7266
+ targets: [ " DynamicLib " ]),
7267
+ ],
7268
+ targets: [
7269
+ // Targets are the basic building blocks of a package, defining a module or a test suite.
7270
+ // Targets can depend on other targets in this package and products from dependencies.
7271
+ .target(
7272
+ name: " DynamicLib " ),
7273
+ .testTarget(
7274
+ name: " DynamicLibTests " ,
7275
+ dependencies: [ " DynamicLib " ]
7276
+ ),
7277
+ ]
7278
+ )
7279
+ """
7280
+ )
7281
+
7282
+ try localFileSystem. writeFileContents (
7283
+ packageDir. appending ( components: " LocalPackages " , " DynamicLib " , " Sources " , " DynamicLib.swift " ) ,
7284
+ string:
7285
+ """
7286
+ // The Swift Programming Language
7287
+ // https://docs.swift.org/swift-book
7288
+
7289
+ public func dynamicLibFunc() -> String {
7290
+ return " Hello from DynamicLib! "
7291
+ }
7292
+ """
7293
+ )
7294
+
7295
+ let ( stdout, _) = try await execute (
7296
+ [ " plugin " , " command_plugin_dynamic_linking " ] ,
7297
+ packagePath: packageDir,
7298
+ configuration: buildData. config,
7299
+ buildSystem: buildData. buildSystem,
7300
+ )
7301
+
7302
+ #expect( stdout. contains ( " Works fine! " ) )
7303
+ }
7304
+ } when: {
7305
+ ( ProcessInfo . hostOperatingSystem == . windows && buildData. buildSystem == . swiftbuild) || ( ProcessInfo . hostOperatingSystem == . linux && buildData. buildSystem == . swiftbuild)
7306
+ }
7307
+ }
7137
7308
}
7138
7309
}
0 commit comments