Compare commits

...

7 Commits

Author SHA1 Message Date
Wolfgang Lutz
382ac0983d
Merge 71b3be13f0 into 8beb3b2d2d 2024-08-06 08:29:09 +05:00
Mizuo Nagayama
8beb3b2d2d
fix plural in ProjectSpec.md (#1487) 2024-08-06 05:35:27 +09:00
Wolfgang Lutz
71b3be13f0 implement string support for globs 2024-07-11 19:00:03 +02:00
Wolfgang Lutz
2c59b4e4f6 Add Basic Test 2024-07-11 17:19:06 +02:00
Wolfgang Lutz
034828366e Merge branch 'master' into feature/add_glob_support_for_includes 2024-07-11 16:34:59 +02:00
Wolfgang Lutz
14e4455e2f add return for older xcode/swift versions 2024-05-26 11:47:01 +02:00
Wolfgang Lutz
985562484a 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
```
2024-05-26 11:39:42 +02:00
7 changed files with 84 additions and 12 deletions

View File

@ -1039,7 +1039,7 @@ The different actions share some properties:
- [ ] **askForAppToLaunch**: **Bool** - `run` and `profile` actions can define the executable set to ask to launch. This defaults to false.
- [ ] **launchAutomaticallySubstyle**: **String** - `run` action can define the launch automatically substyle ('2' for extensions).
- [ ] **storeKitConfiguration**: **String** - `run` action can specify a storekit configuration. See [Options](#options).
- [ ] **macroExpansion**: **String** - `run` and `test` action can define the macro expansion from other target. This defaults to nil.
- [ ] **macroExpansion**: **String** - `run` and `test` actions can define the macro expansion from other target. This defaults to nil.
### Execution Action

View File

@ -1,6 +1,7 @@
import Foundation
import JSONUtilities
import PathKit
import XcodeGenCore
import Yams
public struct SpecFile {
@ -26,24 +27,62 @@ 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 func replacingPath(with newPath: Path) -> Include {
Include(
path: newPath,
relativePaths: relativePaths,
enable: enable
)
}
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) {
return [include]
} else if let dictionary = entry as? JSONDictionary, let path = dictionary["path"] as? String {
return Glob(pattern: (basePath + Path(path)).normalize().string)
.compactMap { Include(path: Path($0), dictionary: dictionary) }
} else {
return []
}
}
}
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]
return Glob(pattern: (basePath + include.path.normalize()).string)
.compactMap { try? Path($0).relativePath(from: basePath) }
.compactMap { include.replacingPath(with: $0) }
} else {
return []
}
@ -92,7 +131,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

View File

@ -0,0 +1,3 @@
include:
- path: "*/*.yml"
name: GlobImportDependent

View File

@ -0,0 +1,2 @@
include: "*/*.yml"
name: GlobImportDependent

View File

@ -0,0 +1,4 @@
name: DuplicatedImportRoot
fileGroups:
- First
- Second

View File

@ -0,0 +1,2 @@
fileGroups:
- Third

View File

@ -25,6 +25,28 @@ class SpecLoadingTests: XCTestCase {
}
}
func testSpecLoaderGlobImports() {
describe {
$0.it("includes files via glob") {
let path = fixturePath + "glob_include/glob_include_sut.yml"
let project = try loadSpec(path: path)
try expect(project.fileGroups) == ["First", "Second", "Third"]
}
}
}
func testSpecLoaderGlobImportsString() {
describe {
$0.it("includes files via glob") {
let path = fixturePath + "glob_include/glob_include_sut_string.yml"
let project = try loadSpec(path: path)
try expect(project.fileGroups) == ["First", "Second", "Third"]
}
}
}
func testSpecLoader() {
describe {
$0.it("merges includes") {