diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 08cc8200..f0fd6687 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -218,6 +218,7 @@ A source can be provided via a string (the path) or an object of the form: - `file`: a file reference with a parent group will be created (Default for files or directories with extensions) - `group`: a group with all it's containing files. (Default for directories without extensions) - `folder`: a folder reference. + - ⚪️ **optional**: `Bool` - Disable missing path check. Defaults to false. ```yaml diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index 471557a7..cbcbd842 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -63,7 +63,7 @@ extension ProjectSpec { for source in target.sources { let sourcePath = basePath + source.path - if !sourcePath.exists { + if !source.optional && !sourcePath.exists { errors.append(.invalidTargetSource(target: target.name, source: sourcePath.string)) } } diff --git a/Sources/ProjectSpec/TargetSource.swift b/Sources/ProjectSpec/TargetSource.swift index 8807b80f..f1e427a5 100644 --- a/Sources/ProjectSpec/TargetSource.swift +++ b/Sources/ProjectSpec/TargetSource.swift @@ -9,6 +9,7 @@ public struct TargetSource { public var compilerFlags: [String] public var excludes: [String] public var type: SourceType? + public var optional: Bool public enum SourceType: String { case group @@ -16,12 +17,13 @@ public struct TargetSource { case folder } - public init(path: String, name: String? = nil, compilerFlags: [String] = [], excludes: [String] = [], type: SourceType? = nil) { + public init(path: String, name: String? = nil, compilerFlags: [String] = [], excludes: [String] = [], type: SourceType? = nil, optional: Bool = false) { self.path = path self.name = name self.compilerFlags = compilerFlags self.excludes = excludes self.type = type + self.optional = optional } } @@ -53,6 +55,7 @@ extension TargetSource: JSONObjectConvertible { excludes = jsonDictionary.json(atKeyPath: "excludes") ?? [] type = jsonDictionary.json(atKeyPath: "type") + optional = jsonDictionary.json(atKeyPath: "optional") ?? false } } @@ -64,5 +67,6 @@ extension TargetSource: Equatable { && lhs.compilerFlags == rhs.compilerFlags && lhs.excludes == rhs.excludes && lhs.type == rhs.type + && lhs.optional == rhs.optional } } diff --git a/Tests/XcodeGenKitTests/ProjectSpecTests.swift b/Tests/XcodeGenKitTests/ProjectSpecTests.swift index d8393335..92267b7a 100644 --- a/Tests/XcodeGenKitTests/ProjectSpecTests.swift +++ b/Tests/XcodeGenKitTests/ProjectSpecTests.swift @@ -101,6 +101,16 @@ func projectSpecTests() { try expectValidationError(spec, .invalidSchemeConfig(scheme: "scheme1", config: "debugInvalid")) try expectValidationError(spec, .invalidSchemeConfig(scheme: "scheme1", config: "releaseInvalid")) } + + $0.it("allows missing optional file") { + var spec = baseSpec + spec.targets = [Target(name: "target1", + type: .application, + platform: .iOS, + sources: [.init(path: "generated.swift", optional: true)] + )] + try spec.validate() + } } } }