From 985562484a7c984df4b1862e07dee835e5e0cd50 Mon Sep 17 00:00:00 2001 From: Wolfgang Lutz Date: Sun, 26 May 2024 11:39:42 +0200 Subject: [PATCH 1/2] Add Glob support for dictionary includes This change enables the use of Glob expressions (e.g. Sources/*/Package.yml) when including a yml file: ``` include: - path: Sources/*/Package.yml - path: Sources/*/Tests.yml - path: Sources/*/UITests.yml ``` --- Sources/ProjectSpec/SpecFile.swift | 49 ++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/Sources/ProjectSpec/SpecFile.swift b/Sources/ProjectSpec/SpecFile.swift index 18ea1562..a35f630e 100644 --- a/Sources/ProjectSpec/SpecFile.swift +++ b/Sources/ProjectSpec/SpecFile.swift @@ -1,6 +1,7 @@ import Foundation import JSONUtilities import PathKit +import XcodeGenCore import Yams public struct SpecFile { @@ -26,22 +27,50 @@ public struct SpecFile { static let defaultEnable = true init?(any: Any) { - if let string = any as? String { - path = Path(string) - relativePaths = Include.defaultRelativePaths - enable = Include.defaultEnable + if let path = any as? String { + self.init( + path: Path(path), + relativePaths: Include.defaultRelativePaths, + enable: Include.defaultEnable + ) } else if let dictionary = any as? JSONDictionary, let path = dictionary["path"] as? String { - self.path = Path(path) - relativePaths = Self.resolveBoolean(dictionary, key: "relativePaths") ?? Include.defaultRelativePaths - enable = Self.resolveBoolean(dictionary, key: "enable") ?? Include.defaultEnable + self.init( + path: Path(path), + dictionary: dictionary + ) } else { return nil } } + + private init(path: Path, relativePaths: Bool, enable: Bool) { + self.path = path + self.relativePaths = relativePaths + self.enable = enable + } + + private init?(path: Path, dictionary: JSONDictionary) { + self.path = path + relativePaths = Self.resolveBoolean(dictionary, key: "relativePaths") ?? Include.defaultRelativePaths + enable = Self.resolveBoolean(dictionary, key: "enable") ?? Include.defaultEnable + } + + private static func includes(from array: [Any], basePath: Path) -> [Include] { + array.flatMap { entry -> [Include] in + if let string = entry as? String, let include = Include(any: string) { + [include] + } else if let dictionary = entry as? JSONDictionary, let path = dictionary["path"] as? String { + Glob(pattern: (basePath + Path(path)).normalize().string) + .compactMap { Include(path: Path($0), dictionary: dictionary) } + } else { + [] + } + } + } - static func parse(json: Any?) -> [Include] { + static func parse(json: Any?, basePath: Path) -> [Include] { if let array = json as? [Any] { - return array.compactMap(Include.init) + return includes(from: array, basePath: basePath) } else if let object = json, let include = Include(any: object) { return [include] } else { @@ -92,7 +121,7 @@ public struct SpecFile { let jsonDictionary = try SpecFile.loadDictionary(path: path).expand(variables: variables) - let includes = Include.parse(json: jsonDictionary["include"]) + let includes = Include.parse(json: jsonDictionary["include"], basePath: basePath) let subSpecs: [SpecFile] = try includes .filter(\.enable) .map { include in From 14e4455e2f15a8c1770997084dd776ffdcae80de Mon Sep 17 00:00:00 2001 From: Wolfgang Lutz Date: Sun, 26 May 2024 11:47:01 +0200 Subject: [PATCH 2/2] add return for older xcode/swift versions --- Sources/ProjectSpec/SpecFile.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/ProjectSpec/SpecFile.swift b/Sources/ProjectSpec/SpecFile.swift index a35f630e..7a67da87 100644 --- a/Sources/ProjectSpec/SpecFile.swift +++ b/Sources/ProjectSpec/SpecFile.swift @@ -58,12 +58,12 @@ public struct SpecFile { private static func includes(from array: [Any], basePath: Path) -> [Include] { array.flatMap { entry -> [Include] in if let string = entry as? String, let include = Include(any: string) { - [include] + return [include] } else if let dictionary = entry as? JSONDictionary, let path = dictionary["path"] as? String { - Glob(pattern: (basePath + Path(path)).normalize().string) + return Glob(pattern: (basePath + Path(path)).normalize().string) .compactMap { Include(path: Path($0), dictionary: dictionary) } } else { - [] + return [] } } }