Skip to content

Commit

Permalink
Added a simulateLocation option in scheme specs (#756)
Browse files Browse the repository at this point in the history
* Added a simulateLocation option in scheme specs

* Updated fixtures for simulateLocation

* Use fileGroups instead of sources
  • Loading branch information
basvankuijck authored and brentleyjones committed Jan 23, 2020
1 parent 3a9131a commit f544dd3
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@
#### Added
- Support for language and region settings on a target basis [#728](https://github.com/yonaskolb/XcodeGen/pull/728) @FranzBusch
- Added option to generate only Info.plist files with `--only-plists` [#739](https://github.com/yonaskolb/XcodeGen/pull/739) @namolnad
- Added the option to specify a `simulateLocation` in a scheme [#722](https://github.com/yonaskolb/XcodeGen/issues/722) @basvankuijck
- Support for On Demand Resources tags [#753](https://github.com/yonaskolb/XcodeGen/pull/753) @sipao

#### Fixed
Expand Down
28 changes: 28 additions & 0 deletions Docs/ProjectSpec.md
Expand Up @@ -728,6 +728,7 @@ The different actions share some properties:
- [ ] **language**: **String** - `run` and `test` actions can define a language that is used for Application Language
- [ ] **region**: **String** - `run` and `test` actions can define a language that is used for Application Region
- [ ] **debugEnabled**: **Bool** - `run` and `test` actions can define a whether debugger should be used. This defaults to true.
- [ ] **simulateLocation**: **[Simulate Location](#simulate-location)** - `run` action can define a simulated location

### Execution Action

Expand Down Expand Up @@ -756,6 +757,33 @@ A multiline script can be written using the various YAML multiline methods, for
- [ ] **customArchiveName**: **String** - the custom name to give to the archive
- [ ] **revealArchiveInOrganizer**: **Bool** - flag to determine whether the archive will be revealed in Xcode's Organizer after it's done building


### Simulate Location
- [x] **allow**: **Bool** - enable location simulation
- [ ] **defaultLocation**: **String** - set the default location, possible values:
- `London, England`
- `Johannesburg, South Africa`
- `Moscow, Russia`
- `Mumbai, India`
- `Tokyo, Japan`
- `Sydney, Australia`
- `Hong Kong, China`
- `Honolulu, HI, USA`
- `San Francisco, CA, USA`
- `Mexico City, Mexico`
- `New York, NY, USA`
- `Rio de Janeiro, Brazil`
- `<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:
fileGroups:
- location.gpx
```


### Environment Variable

- [x] **variable**: **String** - variable's name.
Expand Down
58 changes: 57 additions & 1 deletion Sources/ProjectSpec/Scheme.swift
Expand Up @@ -32,6 +32,32 @@ public struct Scheme: Equatable {
self.archive = archive
}

public struct SimulateLocation: Equatable {
public enum ReferenceType: String {
case predefined = "1"
case gpx = "0"
}

public var allow: Bool
public var defaultLocation: String?

public var referenceType: ReferenceType? {
guard let defaultLocation = self.defaultLocation else {
return nil
}

if defaultLocation.contains(".gpx") {
return .gpx
}
return .predefined
}

public init(allow: Bool, defaultLocation: String) {
self.allow = allow
self.defaultLocation = defaultLocation
}
}

public struct ExecutionAction: Equatable {
public var script: String
public var name: String
Expand Down Expand Up @@ -80,6 +106,7 @@ public struct Scheme: Equatable {
public var language: String?
public var region: String?
public var debugEnabled: Bool
public var simulateLocation: SimulateLocation?

public init(
config: String,
Expand All @@ -90,7 +117,8 @@ public struct Scheme: Equatable {
disableMainThreadChecker: Bool = disableMainThreadCheckerDefault,
language: String? = nil,
region: String? = nil,
debugEnabled: Bool = debugEnabledDefault
debugEnabled: Bool = debugEnabledDefault,
simulateLocation: SimulateLocation? = nil
) {
self.config = config
self.commandLineArguments = commandLineArguments
Expand All @@ -101,6 +129,7 @@ public struct Scheme: Equatable {
self.language = language
self.region = region
self.debugEnabled = debugEnabled
self.simulateLocation = simulateLocation
}
}

Expand Down Expand Up @@ -280,6 +309,28 @@ extension Scheme.ExecutionAction: JSONEncodable {
}
}

extension Scheme.SimulateLocation: JSONObjectConvertible {

public init(jsonDictionary: JSONDictionary) throws {
allow = try jsonDictionary.json(atKeyPath: "allow")
defaultLocation = jsonDictionary.json(atKeyPath: "defaultLocation")
}
}

extension Scheme.SimulateLocation: JSONEncodable {
public func toJSONValue() -> Any {
var dict: [String: Any] = [
"allow": allow
]

if let defaultLocation = defaultLocation {
dict["defaultLocation"] = defaultLocation
}

return dict
}
}

extension Scheme.Run: JSONObjectConvertible {

public init(jsonDictionary: JSONDictionary) throws {
Expand All @@ -292,6 +343,7 @@ extension Scheme.Run: JSONObjectConvertible {
language = jsonDictionary.json(atKeyPath: "language")
region = jsonDictionary.json(atKeyPath: "region")
debugEnabled = jsonDictionary.json(atKeyPath: "debugEnabled") ?? Scheme.Run.debugEnabledDefault
simulateLocation = jsonDictionary.json(atKeyPath: "simulateLocation")
}
}

Expand All @@ -314,6 +366,10 @@ extension Scheme.Run: JSONEncodable {
if debugEnabled != Scheme.Run.debugEnabledDefault {
dict["debugEnabled"] = debugEnabled
}

if let simulateLocation = simulateLocation {
dict["simulateLocation"] = simulateLocation.toJSONValue()
}
return dict
}
}
Expand Down
12 changes: 12 additions & 0 deletions Sources/XcodeGenKit/SchemeGenerator.swift
Expand Up @@ -214,6 +214,16 @@ public class SchemeGenerator {
region: scheme.test?.region
)

let allowLocationSimulation = scheme.run?.simulateLocation?.allow ?? true
var locationScenarioReference: XCScheme.LocationScenarioReference?
if let simulateLocation = scheme.run?.simulateLocation, var identifier = simulateLocation.defaultLocation, let referenceType = simulateLocation.referenceType {
if referenceType == .gpx {
var path = Path("../\(identifier)")
path = path.simplifyingParentDirectoryReferences()
identifier = path.string
}
locationScenarioReference = XCScheme.LocationScenarioReference(identifier: identifier, referenceType: referenceType.rawValue)
}
let launchAction = XCScheme.LaunchAction(
runnable: shouldExecuteOnLaunch ? productRunable : nil,
buildConfiguration: scheme.run?.config ?? defaultDebugConfig.name,
Expand All @@ -222,6 +232,8 @@ public class SchemeGenerator {
macroExpansion: shouldExecuteOnLaunch ? nil : buildableReference,
selectedDebuggerIdentifier: (scheme.run?.debugEnabled ?? Scheme.Run.debugEnabledDefault) ? XCScheme.defaultDebugger : "",
selectedLauncherIdentifier: (scheme.run?.debugEnabled ?? Scheme.Run.debugEnabledDefault) ? XCScheme.defaultLauncher : "Xcode.IDEFoundation.Launcher.PosixSpawn",
allowLocationSimulation: allowLocationSimulation,
locationScenarioReference: locationScenarioReference,
disableMainThreadChecker: scheme.run?.disableMainThreadChecker ?? Scheme.Run.disableMainThreadCheckerDefault,
commandlineArguments: launchCommandLineArgs,
environmentVariables: launchVariables,
Expand Down
Expand Up @@ -89,6 +89,12 @@
ReferencedContainer = "container:Project.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<LocationScenarioReference
identifier = "Honolulu, HI, USA"
referenceType = "1">
</LocationScenarioReference>
<CommandLineArguments>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
Expand Down
6 changes: 5 additions & 1 deletion Tests/Fixtures/TestProject/project.yml
Expand Up @@ -281,7 +281,11 @@ schemes:
App_Scheme:
build:
targets:
App_iOS: all
App_iOS: all
run:
simulateLocation:
allow: true
defaultLocation: Honolulu, HI, USA
test:
gatherCoverageData: true
targets:
Expand Down
8 changes: 7 additions & 1 deletion Tests/XcodeGenKitTests/SchemeGeneratorTests.swift
Expand Up @@ -47,9 +47,11 @@ class SchemeGeneratorTests: XCTestCase {
let buildTarget = Scheme.BuildTarget(target: .local(app.name))
$0.it("generates scheme") {
let preAction = Scheme.ExecutionAction(name: "Script", script: "echo Starting", settingsTarget: app.name)
let simulateLocation = Scheme.SimulateLocation(allow: true, defaultLocation: "New York, NY, USA")
let scheme = Scheme(
name: "MyScheme",
build: Scheme.Build(targets: [buildTarget], preActions: [preAction])
build: Scheme.Build(targets: [buildTarget], preActions: [preAction]),
run: Scheme.Run(config: "Debug", simulateLocation: simulateLocation)
)
let project = Project(
name: "test",
Expand Down Expand Up @@ -91,6 +93,10 @@ class SchemeGeneratorTests: XCTestCase {

try expect(xcscheme.launchAction?.selectedDebuggerIdentifier) == XCScheme.defaultDebugger
try expect(xcscheme.testAction?.selectedDebuggerIdentifier) == XCScheme.defaultDebugger

try expect(xcscheme.launchAction?.allowLocationSimulation) == true
try expect(xcscheme.launchAction?.locationScenarioReference?.referenceType) == Scheme.SimulateLocation.ReferenceType.predefined.rawValue
try expect(xcscheme.launchAction?.locationScenarioReference?.identifier) == "New York, NY, USA"
}

$0.it("generates scheme with multiple configs") {
Expand Down

0 comments on commit f544dd3

Please sign in to comment.