Compare commits

...

4 Commits

Author SHA1 Message Date
Wolfgang Lutz
666d17daef
Merge 14e4455e2f into 45151c2882 2024-07-10 12:20:29 +10:00
Ernesto Cambuston
45151c2882
Allow changing macro expansions on test actions. (#1468)
* Allow to override test macroExpansions

* update doc

* style

* Address feedback from PR

* fix build

* add toJSONValue encoding
2024-07-10 12:19:30 +10: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
5 changed files with 91 additions and 13 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` action can define the macro expansion from other target. This defaults to nil.
- [ ] **macroExpansion**: **String** - `run` and `test` action can define the macro expansion from other target. This defaults to nil.
### Execution Action

View File

@ -220,6 +220,7 @@ public struct Scheme: Equatable {
public var captureScreenshotsAutomatically: Bool
public var deleteScreenshotsWhenEachTestSucceeds: Bool
public var testPlans: [TestPlan]
public var macroExpansion: String?
public struct TestTarget: Equatable, ExpressibleByStringLiteral {
@ -286,7 +287,8 @@ public struct Scheme: Equatable {
debugEnabled: Bool = debugEnabledDefault,
customLLDBInit: String? = nil,
captureScreenshotsAutomatically: Bool = captureScreenshotsAutomaticallyDefault,
deleteScreenshotsWhenEachTestSucceeds: Bool = deleteScreenshotsWhenEachTestSucceedsDefault
deleteScreenshotsWhenEachTestSucceeds: Bool = deleteScreenshotsWhenEachTestSucceedsDefault,
macroExpansion: String? = nil
) {
self.config = config
self.gatherCoverageData = gatherCoverageData
@ -304,6 +306,7 @@ public struct Scheme: Equatable {
self.customLLDBInit = customLLDBInit
self.captureScreenshotsAutomatically = captureScreenshotsAutomatically
self.deleteScreenshotsWhenEachTestSucceeds = deleteScreenshotsWhenEachTestSucceeds
self.macroExpansion = macroExpansion
}
public var shouldUseLaunchSchemeArgsEnv: Bool {
@ -620,6 +623,7 @@ extension Scheme.Test: JSONObjectConvertible {
customLLDBInit = jsonDictionary.json(atKeyPath: "customLLDBInit")
captureScreenshotsAutomatically = jsonDictionary.json(atKeyPath: "captureScreenshotsAutomatically") ?? Scheme.Test.captureScreenshotsAutomaticallyDefault
deleteScreenshotsWhenEachTestSucceeds = jsonDictionary.json(atKeyPath: "deleteScreenshotsWhenEachTestSucceeds") ?? Scheme.Test.deleteScreenshotsWhenEachTestSucceedsDefault
macroExpansion = jsonDictionary.json(atKeyPath: "macroExpansion")
}
}
@ -636,6 +640,7 @@ extension Scheme.Test: JSONEncodable {
"language": language,
"region": region,
"coverageTargets": coverageTargets.map { $0.reference },
"macroExpansion": macroExpansion
]
if gatherCoverageData != Scheme.Test.gatherCoverageDataDefault {

View File

@ -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) {
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]
} 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

View File

@ -289,9 +289,18 @@ public class SchemeGenerator {
let testBuildableEntries = buildActionEntries.filter({ $0.buildFor.contains(.testing) }) + testBuildTargetEntries
let testMacroExpansionBuildableRef = testBuildableEntries.map(\.buildableReference).contains(buildableReference) ? buildableReference : testBuildableEntries.first?.buildableReference
let testMacroExpansion: XCScheme.BuildableReference = buildActionEntries.first(
where: { value in
if let macroExpansion = scheme.test?.macroExpansion {
return value.buildableReference.blueprintName == macroExpansion
}
return false
}
)?.buildableReference ?? testMacroExpansionBuildableRef ?? buildableReference
let testAction = XCScheme.TestAction(
buildConfiguration: scheme.test?.config ?? defaultDebugConfig.name,
macroExpansion: testMacroExpansionBuildableRef,
macroExpansion: testMacroExpansion,
testables: testables,
testPlans: testPlans.isEmpty ? nil : testPlans,
preActions: scheme.test?.preActions.map(getExecutionAction) ?? [],

View File

@ -476,6 +476,41 @@ class SchemeGeneratorTests: XCTestCase {
let xcodeProject = try project.generateXcodeProject()
let xcscheme = try unwrap(xcodeProject.sharedData?.schemes.first)
try expect(xcscheme.testAction?.macroExpansion?.buildableName) == "MyApp.app"
try expect(xcscheme.launchAction?.macroExpansion?.buildableName) == "MyApp.app"
}
$0.it("allows to override test macroExpansion") {
let app = Target(
name: "MyApp",
type: .application,
platform: .iOS,
dependencies: [Dependency(type: .target, reference: "MyAppExtension", embed: false)]
)
let `extension` = Target(
name: "MyAppExtension",
type: .appExtension,
platform: .iOS
)
let appTarget = Scheme.BuildTarget(target: .local(app.name), buildTypes: [.running])
let extensionTarget = Scheme.BuildTarget(target: .local(`extension`.name), buildTypes: [.running])
let scheme = Scheme(
name: "TestScheme",
build: Scheme.Build(targets: [appTarget, extensionTarget]),
run: Scheme.Run(config: "Debug", macroExpansion: "MyApp"),
test: .init(macroExpansion: "MyAppExtension")
)
let project = Project(
name: "test",
targets: [app, `extension`],
schemes: [scheme]
)
let xcodeProject = try project.generateXcodeProject()
let xcscheme = try unwrap(xcodeProject.sharedData?.schemes.first)
try expect(xcscheme.testAction?.macroExpansion?.buildableName) == "MyAppExtension.appex"
try expect(xcscheme.launchAction?.macroExpansion?.buildableName) == "MyApp.app"
}