@@ -52,14 +52,14 @@ struct PackageInfo {
5252 let diagnostics = DiagnosticsEngine ( )
5353
5454 let options : Command . Options
55- let package : Package
55+ // let package: Package
5656 let graph : PackageGraph
5757 let manifest : Manifest
5858 let toolchain : Toolchain
5959 let workspace : Workspace
6060
6161
62- // MARJ : - Initialisation
62+ // MARK : - Initialisation
6363
6464 init ( options: Command . Options ) throws {
6565 self . options = options
@@ -74,13 +74,6 @@ struct PackageInfo {
7474 let loader = ManifestLoader ( manifestResources: resources)
7575 self . workspace = Workspace . create ( forRootPackage: root, manifestLoader: loader)
7676
77- self . package = try PackageBuilder . loadPackage (
78- packagePath: root,
79- swiftCompiler: self . toolchain. swiftCompiler,
80- xcTestMinimumDeploymentTargets: [ : ] ,
81- diagnostics: self . diagnostics
82- )
83-
8477 self . graph = self . workspace. loadPackageGraph ( root: root, diagnostics: self . diagnostics)
8578
8679 self . manifest = try ManifestLoader . loadManifest (
@@ -91,6 +84,33 @@ struct PackageInfo {
9184 }
9285
9386
87+ // MARK: - Validation
88+
89+ func validationErrors ( ) -> [ PackageValidationError ] {
90+ var errors = [ PackageValidationError] ( )
91+
92+ // check the graph for binary targets
93+ let binary = self . graph. allTargets. filter { $0. type == . binary }
94+ if binary. isEmpty == false {
95+ errors. append ( . containsBinaryTargets( binary. map ( \. name) ) )
96+ }
97+
98+ // check for system modules
99+ let system = self . graph. allTargets. filter { $0. type == . systemModule }
100+ if system. isEmpty == false {
101+ errors. append ( . containsSystemModules( system. map ( \. name) ) )
102+ }
103+
104+ // and for conditional dependencies
105+ let conditionals = self . graph. allTargets. filter { $0. dependencies. contains { $0. conditions. isEmpty == false } }
106+ if conditionals. isEmpty == false {
107+ errors. append ( . containsConditionalDependencies( conditionals. map ( \. name) ) )
108+ }
109+
110+ return errors
111+ }
112+
113+
94114 // MARK: - Product/Target Names
95115
96116 func validProductNames ( project: Xcode . Project ) throws -> [ String ] {
@@ -100,7 +120,7 @@ struct PackageInfo {
100120 if self . options. products. isEmpty == false {
101121 productNames = self . options. products
102122 } else {
103- productNames = package . manifest. libraryProductNames
123+ productNames = self . manifest. libraryProductNames
104124 }
105125
106126 // validation
@@ -115,15 +135,15 @@ struct PackageInfo {
115135 let invalidProducts = productNames. filter { xcodeTargetNames. contains ( $0) == false }
116136 guard invalidProducts. isEmpty == true else {
117137
118- let allLibraryProductNames = self . package . manifest. libraryProductNames
138+ let allLibraryProductNames = self . manifest. libraryProductNames
119139 let nonRootPackageTargets = xcodeTargetNames. filter { allLibraryProductNames. contains ( $0) == false }
120140
121141 throw ValidationError (
122142 """
123143 Invalid product/target name(s):
124144 \( invalidProducts. joined ( separator: " \n " ) )
125145
126- Available \( self . package . name) products:
146+ Available \( self . manifest . name) products:
127147 \( allLibraryProductNames. sorted ( ) . joined ( separator: " \n " ) )
128148
129149 Additional available targets:
@@ -136,13 +156,13 @@ struct PackageInfo {
136156 }
137157
138158 func printAllProducts ( project: Xcode . Project ) {
139- let allLibraryProductNames = self . package . manifest. libraryProductNames
159+ let allLibraryProductNames = self . manifest. libraryProductNames
140160 let xcodeTargetNames = project. frameworkTargets. map { $0. name }
141161 let nonRootPackageTargets = xcodeTargetNames. filter { allLibraryProductNames. contains ( $0) == false }
142162
143163 print (
144164 """
145- \n Available \( self . package . name) products:
165+ \n Available \( self . manifest . name) products:
146166 \( allLibraryProductNames. sorted ( ) . joined ( separator: " \n " ) )
147167
148168 Additional available targets:
@@ -182,6 +202,7 @@ struct PackageInfo {
182202 private var absoluteRootDirectory : AbsolutePath {
183203 AbsolutePath ( self . rootDirectory. path)
184204 }
205+
185206}
186207
187208
@@ -206,3 +227,34 @@ extension SupportedPlatform: Equatable, Comparable {
206227 return lhs. platform. name < rhs. platform. name
207228 }
208229}
230+
231+ // MARK: - Validation Errors
232+
233+ enum PackageValidationError : LocalizedError {
234+ case containsBinaryTargets( [ String ] )
235+ case containsSystemModules( [ String ] )
236+ case containsConditionalDependencies( [ String ] )
237+
238+ var isFatal : Bool {
239+ switch self {
240+ case . containsBinaryTargets, . containsSystemModules:
241+ return true
242+ case . containsConditionalDependencies:
243+ return false
244+ }
245+ }
246+
247+ var errorDescription : String ? {
248+ switch self {
249+ case let . containsBinaryTargets( targets) :
250+ return " Xcode project generation is not supported by Swift Package Manager for packages that contain binary targets. "
251+ + " These binary targets were detected: \( targets. joined ( separator: " , " ) ) "
252+ case let . containsSystemModules( targets) :
253+ return " Xcode project generation is not supported by Swift Package Manager for packages that reference system modules. "
254+ + " These system modules were referenced: \( targets. joined ( separator: " , " ) ) "
255+ case let . containsConditionalDependencies( targets) :
256+ return " Xcode project generation does not support conditional target dependencies, so the generated project may not build successfully. "
257+ + " These targets contain conditional dependencies: \( targets. joined ( separator: " , " ) ) "
258+ }
259+ }
260+ }
0 commit comments