Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions Docs/ProjectSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Note that target names can also be changed by adding a `name` property to a targ
- [ ] **fileTypes**: **[String: [FileType](#filetype)]** - A list of default file options for specific file extensions across the project. Values in [Sources](#sources) will overwrite these settings.
- [ ] **preGenCommand**: **String** - A bash command to run before the project has been generated. If the project isn't generated due to no changes when using the cache then this won't run. This is useful for running things like generating resources files before the project is regenerated.
- [ ] **postGenCommand**: **String** - A bash command to run after the project has been generated. If the project isn't generated due to no changes when using the cache then this won't run. This is useful for running things like `pod install` only if the project is actually regenerated.
- [ ] **useBaseInternationalization**: **Bool** If this is `false` and your project does not include resources located in a **Base.lproj** directory then `Base` will not be included in the projects 'known regions'. The default value is `true`.
- [ ] **useBaseInternationalization**: **Bool** If this is `false` and your project does not include resources located in a **Base.lproj** directory then `Base` will not be included in the projects 'known regions'. The default value is `true`.
- [ ] **schemePathPrefix**: **String** - A path prefix for relative paths in schemes, such as StoreKitConfiguration. The default is `"../../"`, which is suitable for non-workspace projects. For use in workspaces, use `"../"`.

```yaml
Expand All @@ -147,7 +147,7 @@ Describe an order of groups. Available parameters:

```yaml
options:
groupOrdering:
groupOrdering:
- order: [Sources, Resources, Tests, Support files, Configurations]
- pattern: '^.*Screen$'
order: [View, Presenter, Interactor, Entities, Assembly]
Expand Down Expand Up @@ -525,7 +525,7 @@ packages:
targets:
App:
dependencies:
- package: Yams
- package: Yams
- package: SwiftPM
product: SPMUtility
```
Expand Down Expand Up @@ -730,7 +730,7 @@ Any attributes defined within a targets `templateAttributes` will be used to rep
```yaml
targets:
MyFramework:
templates:
templates:
- Framework
templateAttributes:
frameworkName: AwesomeFramework
Expand Down Expand Up @@ -824,7 +824,7 @@ A multiline script can be written using the various YAML multiline methods, for
### Test Action

- [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false
- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference)]** - a list of targets to gather code coverage. Each entry can also either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference)
- [ ] **coverageTargets**: **[String OR [Target Reference](#target-reference)]** - a list of targets to gather code coverage. Each entry can also either be a simple string, a string using [Project Reference](#project-reference) or [Target Reference](#target-reference)
- [ ] **targets**: **[[Test Target](#test-target)]** - a list of targets to test. Each entry can either be a simple string, or a [Test Target](#test-target)
- [ ] **customLLDBInit**: **String** - the absolute path to the custom `.lldbinit` file
- [ ] **captureScreenshotsAutomatically**: **Bool** - indicates whether screenshots should be captured automatically while UI Testing. This defaults to true.
Expand All @@ -834,9 +834,9 @@ A multiline script can be written using the various YAML multiline methods, for
A target can be one of a 2 types:

- **name**: **String** - The name of the target.
- **target**: **[Testable Target Reference](#testable-target-reference)** - The information of the target. You can specify more detailed information than `name:`.
- **target**: **[Target Reference](#target-reference)** - The information of the target. You can specify more detailed information than `name:`.

As syntax suger, you can also specify **[Testable Target Reference](#testable-target-reference)** without `target`.
As syntax suger, you can also specify **[Target Reference](#target-reference)** without `target`.

#### Other Parameters

Expand All @@ -847,7 +847,7 @@ As syntax suger, you can also specify **[Testable Target Reference](#testable-ta
- [ ] **skippedTests**: **[String]** - List of tests in the test target to skip. Defaults to empty
- [ ] **selectedTests**: **[String]** - List of tests in the test target to whitelist and select. Defaults to empty. This will override `skippedTests` if provided

#### Testable Target Reference
#### Target Reference
A Testable Target Reference can be one of 3 types:
- `package: {local-swift-package-name}/{target-name}`: Name of local swift package and its target.
- `local: {target-name}`: Name of local target.
Expand All @@ -860,7 +860,7 @@ A Testable Target Reference can be one of 3 types:


### Simulate Location
- [x] **allow**: **Bool** - enable location simulation
- [x] **allow**: **Bool** - enable location simulation
- [ ] **defaultLocation**: **String** - set the default location, possible values:
- `London, England`
- `Johannesburg, South Africa`
Expand All @@ -874,9 +874,9 @@ A Testable Target Reference can be one of 3 types:
- `Mexico City, Mexico`
- `New York, NY, USA`
- `Rio de Janeiro, Brazil`
- `<relative-path-to-gpx-file>` (e.g. ./location.gpx)
- `<relative-path-to-gpx-file>` (e.g. ./location.gpx)
Setting the **defaultLocation** to a custom gpx file, you also need to add that file to `fileGroups` for Xcode be able to use it:

```yaml
targets:
MyTarget:
Expand Down Expand Up @@ -913,8 +913,8 @@ schemes:
- MyTarget1
- ExternalTarget/OtherTarget1
- package: LocalPackage/TestTarget
targets:
- Tester1
targets:
- Tester1
- name: Tester2
parallelizable: true
randomExecutionOrder: true
Expand Down Expand Up @@ -985,7 +985,7 @@ Swift packages are defined at a project level, and then linked to individual tar
- `branch: master`
- `revision: xxxxxx`
- [ ] **github** : **String**- this is an optional helper you can use for github repos. Instead of specifying the full url in `url` you can just specify the github org and repo

### Local Package

- [x] **path**: **String** - the path to the package in local. The path must be directory with a `Package.swift`.
Expand Down
30 changes: 15 additions & 15 deletions Sources/ProjectSpec/Scheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public struct Scheme: Equatable {

public var config: String?
public var gatherCoverageData: Bool
public var coverageTargets: [TestableTargetReference]
public var coverageTargets: [TargetReference]
public var disableMainThreadChecker: Bool
public var commandLineArguments: [String: Bool]
public var targets: [TestTarget]
Expand All @@ -189,7 +189,7 @@ public struct Scheme: Equatable {
public static let parallelizableDefault = false

public var name: String { targetReference.name }
public let targetReference: TestableTargetReference
public let targetReference: TargetReference
public var randomExecutionOrder: Bool
public var parallelizable: Bool
public var location: String?
Expand All @@ -198,7 +198,7 @@ public struct Scheme: Equatable {
public var selectedTests: [String]

public init(
targetReference: TestableTargetReference,
targetReference: TargetReference,
randomExecutionOrder: Bool = randomExecutionOrderDefault,
parallelizable: Bool = parallelizableDefault,
location: String? = nil,
Expand All @@ -217,7 +217,7 @@ public struct Scheme: Equatable {

public init(stringLiteral value: String) {
do {
targetReference = try TestableTargetReference(value)
targetReference = try TargetReference(value)
randomExecutionOrder = false
parallelizable = false
location = nil
Expand All @@ -233,7 +233,7 @@ public struct Scheme: Equatable {
public init(
config: String,
gatherCoverageData: Bool = gatherCoverageDataDefault,
coverageTargets: [TestableTargetReference] = [],
coverageTargets: [TargetReference] = [],
disableMainThreadChecker: Bool = disableMainThreadCheckerDefault,
randomExecutionOrder: Bool = false,
parallelizable: Bool = false,
Expand Down Expand Up @@ -331,10 +331,10 @@ public struct Scheme: Equatable {
}

public struct BuildTarget: Equatable, Hashable {
public var target: TestableTargetReference
public var target: TargetReference
public var buildTypes: [BuildType]

public init(target: TestableTargetReference, buildTypes: [BuildType] = BuildType.all) {
public init(target: TargetReference, buildTypes: [BuildType] = BuildType.all) {
self.target = target
self.buildTypes = buildTypes
}
Expand Down Expand Up @@ -469,9 +469,9 @@ extension Scheme.Test: JSONObjectConvertible {
if let coverages = jsonDictionary["coverageTargets"] as? [Any] {
coverageTargets = try coverages.compactMap { target in
if let string = target as? String {
return try TestableTargetReference(string)
return try TargetReference(string)
} else if let dictionary = target as? JSONDictionary,
let target: TestableTargetReference = try? .init(jsonDictionary: dictionary) {
let target: TargetReference = try? .init(jsonDictionary: dictionary) {
return target
} else {
return nil
Expand All @@ -486,7 +486,7 @@ extension Scheme.Test: JSONObjectConvertible {
if let targets = jsonDictionary["targets"] as? [Any] {
self.targets = try targets.compactMap { target in
if let string = target as? String {
return try TestTarget(targetReference: TestableTargetReference(string))
return try TestTarget(targetReference: TargetReference(string))
} else if let dictionary = target as? JSONDictionary {
return try TestTarget(jsonDictionary: dictionary)
} else {
Expand Down Expand Up @@ -554,13 +554,13 @@ extension Scheme.Test.TestTarget: JSONObjectConvertible {

public init(jsonDictionary: JSONDictionary) throws {
if let name: String = jsonDictionary.json(atKeyPath: "name") {
targetReference = try TestableTargetReference(name)
self.targetReference = try TargetReference(name)
} else if let local: String = jsonDictionary.json(atKeyPath: "local") {
self.targetReference = TestableTargetReference.local(local)
self.targetReference = TargetReference.local(local)
} else if let project: String = jsonDictionary.json(atKeyPath: "project") {
self.targetReference = TestableTargetReference.project(project)
self.targetReference = TargetReference.project(project)
} else if let package: String = jsonDictionary.json(atKeyPath: "package") {
self.targetReference = TestableTargetReference.package(package)
self.targetReference = TargetReference.package(package)
} else {
self.targetReference = try jsonDictionary.json(atKeyPath: "target")
}
Expand Down Expand Up @@ -719,7 +719,7 @@ extension Scheme.Build: JSONObjectConvertible {
} else {
buildTypes = BuildType.all
}
let target = try TestableTargetReference(targetRepr)
let target = try TargetReference(targetRepr)
targets.append(Scheme.BuildTarget(target: target, buildTypes: buildTypes))
}
self.targets = targets.sorted { $0.target.name < $1.target.name }
Expand Down
28 changes: 8 additions & 20 deletions Sources/ProjectSpec/SpecValidation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@ extension Project {
let dependencyTargetReference = try TargetReference(dependency.reference)

switch dependencyTargetReference.location {
case .local:
if getProjectTarget(dependency.reference) == nil {
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
}
case .project(let dependencyProjectName):
if getProjectReference(dependencyProjectName) == nil {
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
}
case .local where getProjectTarget(dependency.reference) == nil:
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
case .project(let dependencyProjectName) where getProjectReference(dependencyProjectName) == nil:
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
case .package(let package) where getPackage(package) == nil:
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
default: break
}

case .sdk:
let path = Path(dependency.reference)
if !dependency.reference.contains("/") {
Expand Down Expand Up @@ -243,18 +243,6 @@ extension Project {
return .invalidSchemeTarget(scheme: scheme.name, target: targetReference.name, action: action)
case .project(let project) where getProjectReference(project) == nil:
return .invalidProjectReference(scheme: scheme.name, reference: project)
case .local, .project:
return nil
}
}

/// Returns a descriptive error if the given target reference was invalid otherwise `nil`.
private func validationError(for testableTargetReference: TestableTargetReference, in scheme: Scheme, action: String) -> SpecValidationError.ValidationError? {
switch testableTargetReference.location {
case .local where getProjectTarget(testableTargetReference.name) == nil:
return .invalidSchemeTarget(scheme: scheme.name, target: testableTargetReference.name, action: action)
case .project(let project) where getProjectReference(project) == nil:
return .invalidProjectReference(scheme: scheme.name, reference: project)
case .package(let package) where getPackage(package) == nil:
return .invalidLocalPackage(package)
case .local, .project, .package:
Expand Down
46 changes: 45 additions & 1 deletion Sources/ProjectSpec/TargetReference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public struct TargetReference: Hashable {
public enum Location: Hashable {
case local
case project(String)
case package(String)
}

public init(name: String, location: Location) {
Expand All @@ -34,6 +35,16 @@ extension TargetReference {
public static func local(_ name: String) -> TargetReference {
TargetReference(name: name, location: .local)
}

public static func project(_ name: String) -> TargetReference {
let paths = name.split(separator: "/")
return TargetReference(name: String(paths[1]), location: .project(String(paths[0])))
}

public static func package(_ name: String) -> TargetReference {
let paths = name.split(separator: "/")
return TargetReference(name: String(paths[1]), location: .package(String(paths[0])))
}
}

extension TargetReference: ExpressibleByStringLiteral {
Expand All @@ -46,7 +57,7 @@ extension TargetReference: CustomStringConvertible {
public var reference: String {
switch location {
case .local: return name
case .project(let root):
case .project(let root), .package(let root):
return "\(root)/\(name)"
}
}
Expand All @@ -55,3 +66,36 @@ extension TargetReference: CustomStringConvertible {
reference
}
}

extension TargetReference: JSONObjectConvertible {

public init(jsonDictionary: JSONDictionary) throws {
if let project: String = jsonDictionary.json(atKeyPath: "project") {
let paths = project.split(separator: "/")
name = String(paths[1])
location = .project(String(paths[0]))
} else if let project: String = jsonDictionary.json(atKeyPath: "package") {
let paths = project.split(separator: "/")
name = String(paths[1])
location = .package(String(paths[0]))
} else {
name = try jsonDictionary.json(atKeyPath: "local")
location = .local
}
}
}

extension TargetReference: JSONEncodable {
public func toJSONValue() -> Any {
var dictionary: JSONDictionary = [:]
switch self.location {
case .package(let packageName):
dictionary["package"] = "\(packageName)/\(name)"
case .project(let projectName):
dictionary["project"] = "\(projectName)/\(name)"
case .local:
dictionary["local"] = name
}
return dictionary
}
}
2 changes: 1 addition & 1 deletion Sources/ProjectSpec/TargetScheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extension TargetScheme: JSONObjectConvertible {
if let targets = jsonDictionary["testTargets"] as? [Any] {
testTargets = try targets.compactMap { target in
if let string = target as? String {
return .init(targetReference: try TestableTargetReference(string))
return .init(targetReference: try TargetReference(string))
} else if let dictionary = target as? JSONDictionary,
let target: Scheme.Test.TestTarget = try? .init(jsonDictionary: dictionary) {
return target
Expand Down
Loading