@@ -20,6 +20,7 @@ struct BridgeJSBuildPlugin: BuildToolPlugin {
2020
2121 private func createGenerateCommand ( context : PluginContext , target : SwiftSourceModuleTarget ) throws -> Command {
2222 let outputSwiftPath = context . pluginWorkDirectoryURL . appending ( path : " BridgeJS.swift " )
23+ let outputSkeletonPath = context . pluginWorkDirectoryURL . appending ( path : " JavaScript/BridgeJS.json " )
2324
2425 let inputSwiftFiles = target . sourceFiles . filter {
2526 ! $0 . url . path . hasPrefix ( context . pluginWorkDirectoryURL . path + " / " )
@@ -63,6 +64,14 @@ struct BridgeJSBuildPlugin: BuildToolPlugin {
6364 ] )
6465 }
6566
67+ for skeleton in dependencySkeletons ( context : context , target : target ) {
68+ arguments . append ( contentsOf : [
69+ " --dependency-skeleton " ,
70+ " \( skeleton . moduleName ) = \( skeleton . url . path ) " ,
71+ ] )
72+ inputFiles . append ( skeleton . url )
73+ }
74+
6675 let allSwiftFiles = inputSwiftFiles + pluginGeneratedSwiftFiles
6776 arguments . append ( contentsOf : allSwiftFiles . map ( \. path ) )
6877
@@ -71,8 +80,47 @@ struct BridgeJSBuildPlugin: BuildToolPlugin {
7180 executable : try context . tool ( named : " BridgeJSTool " ) . url ,
7281 arguments : arguments ,
7382 inputFiles : inputFiles ,
74- outputFiles : [ outputSwiftPath ]
83+ outputFiles : [ outputSwiftPath , outputSkeletonPath ]
7584 )
7685 }
86+
87+ private struct DependencySkeleton {
88+ let moduleName : String
89+ let url : URL
90+ }
91+
92+ /// We only read skeletons from dependencies with a `bridge-js.config.json` file.
93+ /// For the build system to correctly order the plugins, we need to set the skeleton
94+ /// files as input. However, I don’t think we have enough information here to determine
95+ /// whether the plugin which generates this is applied to the dependency, so we use
96+ /// the presence of `bridge-js.config.json` instead.
97+ private func dependencySkeletons (
98+ context : PluginContext ,
99+ target : SwiftSourceModuleTarget
100+ ) -> [ DependencySkeleton ] {
101+ let localTargets : [ SwiftSourceModuleTarget ] = target . recursiveTargetDependencies
102+ . compactMap { dependency in
103+ guard
104+ let swiftTarget = dependency as? SwiftSourceModuleTarget ,
105+ context . package . targets . contains ( where : { $0 . id == swiftTarget . id } ) ,
106+ FileManager . default . fileExists ( atPath : pathToConfigFile ( target : swiftTarget ) . path )
107+ else {
108+ return nil
109+ }
110+ return swiftTarget
111+ }
112+
113+ var skeletons : [ DependencySkeleton ] = [ ]
114+ var seenTargetNames = Set < String > ( )
115+ for swiftTarget in localTargets where seenTargetNames . insert ( swiftTarget . name ) . inserted {
116+ let skeletonURL = BridgeJSPluginPaths . skeletonURL (
117+ targetName : swiftTarget . name ,
118+ packageID : context . package . id ,
119+ buildPluginWorkDirectoryURL : context . pluginWorkDirectoryURL
120+ )
121+ skeletons . append ( DependencySkeleton ( moduleName : swiftTarget . name , url : skeletonURL ) )
122+ }
123+ return skeletons
124+ }
77125}
78126#endif
0 commit comments