mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-10-26 14:01:24 +03:00
Merge branch 'external-target-ref' into test-coverage
This commit is contained in:
commit
f81adfe291
46
.github/workflows/ci.yml
vendored
46
.github/workflows/ci.yml
vendored
@ -1,13 +1,25 @@
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push: {}
|
||||
pull_request: {}
|
||||
jobs:
|
||||
swift_5:
|
||||
runs-on: macos-latest
|
||||
name: Swift 5.0
|
||||
run:
|
||||
runs-on: macOS-latest
|
||||
name: Xcode ${{ matrix.xcode }}
|
||||
strategy:
|
||||
matrix:
|
||||
xcode: ["10.3", "11"]
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Info
|
||||
run: swift --version; swift package --version
|
||||
- name: Set Xcode
|
||||
run: |
|
||||
echo "Available Xcode versions:"
|
||||
ls /Applications | grep Xcode
|
||||
echo "Choosing Xcode_${{ matrix.xcode }}.app"
|
||||
sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app
|
||||
xcodebuild -version
|
||||
swift --version
|
||||
swift package --version
|
||||
- name: Resolve
|
||||
run: swift package resolve
|
||||
- name: Build
|
||||
@ -20,25 +32,3 @@ jobs:
|
||||
run: scripts/diff-fixtures.sh
|
||||
- name: Build fixtures
|
||||
run: scripts/build-fixtures.sh
|
||||
# swift_5.1:
|
||||
# runs-on: macos-latest
|
||||
# name: Swift 5.1
|
||||
# steps:
|
||||
# - uses: actions/checkout@master
|
||||
# - name: Xcode version
|
||||
# run: sudo xcode-select -s /Applications/Xcode_11_beta.app
|
||||
# - name: Info
|
||||
# run: swift --version; swift package --version
|
||||
# - name: Resolve
|
||||
# run: swift package resolve
|
||||
# - name: Build
|
||||
# run: swift build
|
||||
# - name: Test
|
||||
# run: swift test
|
||||
# - name: Gen fixtures
|
||||
# run: scripts/gen-fixtures.sh
|
||||
# - name: Check fixtures
|
||||
# run: scripts/diff-fixtures.sh
|
||||
# - name: Build fixtures
|
||||
# run: scripts/build-fixtures.sh
|
||||
|
||||
|
44
CHANGELOG.md
44
CHANGELOG.md
@ -3,23 +3,53 @@
|
||||
## Next Version
|
||||
|
||||
#### Added
|
||||
|
||||
- Added `includes` to `sources` for a Target. This follows the same glob-style as `excludes` but functions as a way to only include files that match a specified pattern. Useful if you only want a certain file type, for example specifying `**/*.swift`. [#637](https://github.com/yonaskolb/XcodeGen/pull/637) @bclymer
|
||||
- Support `dylib` SDK. [#650](https://github.com/yonaskolb/XcodeGen/pull/650) @kateinoigakukun
|
||||
- Added `language` and `region` options for `run` and `test` scheme [#654](https://github.com/yonaskolb/XcodeGen/pull/654) @kateinoigakukun
|
||||
- Added `debugEnabled` option for `run` and `test` scheme [#657](https://github.com/yonaskolb/XcodeGen/pull/657) @kateinoigakukun
|
||||
- Support External Target Reference. [#655](https://github.com/yonaskolb/XcodeGen/pull/655) @kateinoigakukun
|
||||
- Support Target Reference to another project. [#655](https://github.com/yonaskolb/XcodeGen/pull/655) @kateinoigakukun
|
||||
- Added `enableCoverage` for each test target. This enables to gather code coverage for specific targets. [#656](https://github.com/yonaskolb/XcodeGen/pull/656) @kateinoigakukun
|
||||
|
||||
#### Fixed
|
||||
- Add base localisation by default even if no base localised files were found. Fixes warning in Xcode 11 [#685](https://github.com/yonaskolb/XcodeGen/pull/685) @yonaskolb
|
||||
|
||||
|
||||
## 2.9.0
|
||||
|
||||
#### Added
|
||||
- Added Scheme Templates [#672](https://github.com/yonaskolb/XcodeGen/pull/672) @bclymer
|
||||
|
||||
#### Fixed
|
||||
- Fixed macOS unit test setting preset [#665](https://github.com/yonaskolb/XcodeGen/pull/665) @yonaskolb
|
||||
- Add `rcproject` files to sources build phase instead of resources [#669](https://github.com/yonaskolb/XcodeGen/pull/669) @Qusic
|
||||
- Prefer default configuration names for generated schemes [#673](https://github.com/yonaskolb/XcodeGen/pull/673) @giginet
|
||||
- Fixed some resource files being placed to "Recovered References" group [#679](https://github.com/yonaskolb/XcodeGen/pull/679) @nivanchikov
|
||||
|
||||
#### Internal
|
||||
- Updated to SwiftCLI 5.3.2 [#667](https://github.com/yonaskolb/XcodeGen/pull/667) @giginet
|
||||
- Fixed tests in case-sensitive file system [#670](https://github.com/yonaskolb/XcodeGen/pull/670) @Qusic
|
||||
|
||||
[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.8.0...2.9.0)
|
||||
|
||||
## 2.8.0
|
||||
|
||||
#### Added
|
||||
- Added support for Swift Package dependencies [#624](https://github.com/yonaskolb/XcodeGen/pull/624) @yonaskolb
|
||||
- Added `includes` to `sources` for a Target. This follows the same glob-style as `excludes` but functions as a way to only include files that match a specified pattern. Useful if you only want a certain file type, for example specifying `**/*.swift`. [#637](https://github.com/yonaskolb/XcodeGen/pull/637) @bclymer
|
||||
- Support `dylib` SDK. [#650](https://github.com/yonaskolb/XcodeGen/pull/650) @kateinoigakukun
|
||||
- Added `language` and `region` options for `run` and `test` scheme [#654](https://github.com/yonaskolb/XcodeGen/pull/654) @kateinoigakukun
|
||||
- Added `debugEnabled` option for `run` and `test` scheme [#657](https://github.com/yonaskolb/XcodeGen/pull/657) @kateinoigakukun
|
||||
|
||||
#### Fixed
|
||||
- Expand template variable in Array of Any [#651](https://github.com/yonaskolb/XcodeGen/pull/651) @kateinoigakukun
|
||||
- Significantly improve performance when running with a large number files. [#658](https://github.com/yonaskolb/XcodeGen/pull/658) @kateinoigakukun
|
||||
- Removed some more diffs between the generated .pbxproj and when Xcode resaves it [#663](https://github.com/yonaskolb/XcodeGen/pull/663) @yonaskolb
|
||||
|
||||
#### Internal
|
||||
- Removed needless `Array` initialization. [#661](https://github.com/yonaskolb/XcodeGen/pull/661) @RomanPodymov
|
||||
- Updated to XcodeProj 7.1.0 [#624](https://github.com/yonaskolb/XcodeGen/pull/624) @yonaskolb
|
||||
|
||||
[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.7.0...2.8.0)
|
||||
|
||||
## 2.7.0
|
||||
|
||||
#### Added
|
||||
|
||||
- Added Bash 4 style recursive globbing (`**/*`) in target sources `excludes` [#636](https://github.com/yonaskolb/XcodeGen/pull/636) @bclymer
|
||||
- Added ability to disable main thread checker in Schemes [#601](https://github.com/yonaskolb/XcodeGen/pull/601) @wag-miles
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
- [Aggregate Target](#aggregate-target)
|
||||
- [Target Template](#target-template)
|
||||
- [Scheme](#scheme)
|
||||
- [Scheme Template](#scheme-template)
|
||||
- [Swift Package](#swift-package)
|
||||
|
||||
## General
|
||||
|
||||
@ -46,6 +48,9 @@ You can also use environment variables in your configuration file, by using `${S
|
||||
- [ ] **fileGroups**: **[String]** - A list of paths to add to the root of the project. These aren't files that will be included in your targets, but that you'd like to include in the project hierachy anyway. For example a folder of xcconfig files that aren't already added by any target sources, or a Readme file.
|
||||
- [ ] **schemes**: **[Scheme](#scheme)** - A list of schemes by name. This allows more control over what is found in [Target Scheme](#target-scheme)
|
||||
- [ ] **targetTemplates**: **[String: [Target Template](#target-template)]** - a list of targets that can be used as templates for actual targets which reference them via a `template` property. They can be used to extract common target settings. Works great in combination with `include`.
|
||||
- [ ] **packages**: **[String: [Swift Package](#swift-package)]** - a map of Swift packages by name
|
||||
- [ ] **localPackages**: **[String]** - A list of paths to local Swift Packages. The paths must be directories with a `Package.swift` file in them. This is used to override `packages` with a local version for development purposes.
|
||||
- [ ] **projectReferences**: **[String: [Project Reference](#project-reference)]** - a map of project references by name
|
||||
|
||||
### Include
|
||||
|
||||
@ -117,6 +122,7 @@ Note that target names can also be changed by adding a `name` property to a targ
|
||||
- [ ] **transitivelyLinkDependencies**: **Bool** - If this is `true` then targets will link to the dependencies of their target dependencies. If a target should embed its dependencies, such as application and test bundles, it will embed these transitive dependencies as well. Some complex setups might want to set this to `false` and explicitly specify dependencies at every level. Targets can override this with [Target](#target).transitivelyLinkDependencies. Defaults to `false`.
|
||||
- [ ] **generateEmptyDirectories**: **Bool** - If this is `true` then empty directories will be added to project too else will be missed. Defaults to `false`.
|
||||
- [ ] **findCarthageFrameworks**: **Bool** - When this is set to `true`, all the invididual frameworks for Carthage dependencies will automatically be found. This property can be overriden individually for each carthage dependency - for more details see See **findFrameworks** in the [Dependency](#dependency) section. Defaults to `false`.
|
||||
- [ ] **localPackagesGroup**: **String** - The group name that local packages are put into. This defaults to `Packages`
|
||||
|
||||
```yaml
|
||||
options:
|
||||
@ -373,6 +379,7 @@ A dependency can be one of a 3 types:
|
||||
- `framework: path` - links to a framework
|
||||
- `carthage: name` - helper for linking to a Carthage framework
|
||||
- `sdk: name` - links to a dependency with the SDK. This can either be a relative path within the sdk root or a single filename that references a framework (.framework) or lib (.tbd)
|
||||
- `package: name` - links to a Swift Package. The name must match the name of a package defined in the top level `packages`
|
||||
|
||||
**Linking options**:
|
||||
|
||||
@ -396,7 +403,7 @@ Carthage frameworks are expected to be in `CARTHAGE_BUILD_PATH/PLATFORM/FRAMEWOR
|
||||
- `PLATFORM` = the target's platform
|
||||
- `FRAMEWORK` = the specified name.
|
||||
|
||||
All the invididual frameworks of a Carthage dependency can be automatically found via `findFrameworks: true`. This overrides the value of [Options](#options).findCarthageFrameworks. Otherwise each one will have to be listed invididually.
|
||||
All the individual frameworks of a Carthage dependency can be automatically found via `findFrameworks: true`. This overrides the value of [Options](#options).findCarthageFrameworks. Otherwise each one will have to be listed individually.
|
||||
Xcodegen uses `.version` files generated by Carthage in order for this framework lookup to work, so the Carthage dependencies will need to have already been built at the time XcodeGen is run.
|
||||
|
||||
If any applications contain carthage dependencies within itself or any dependent targets, a carthage copy files script is automatically added to the application containing all the relevant frameworks. A `FRAMEWORK_SEARCH_PATHS` setting is also automatically added
|
||||
@ -433,6 +440,25 @@ targets:
|
||||
type: framework
|
||||
```
|
||||
|
||||
**Package dependency**
|
||||
- [ ] **product**: **String** - The product to use from the package. This defaults to the package name, so is only required if a Package has multiple libraries or a library with a differing name
|
||||
|
||||
```yaml
|
||||
packages:
|
||||
Yams:
|
||||
url: https://github.com/jpsim/Yams
|
||||
majorVersion: 2.0.0
|
||||
SwiftPM:
|
||||
url: https://github.com/apple/swift-package-manager
|
||||
branch: swift-5.0-branch
|
||||
targets:
|
||||
App:
|
||||
dependencies:
|
||||
- package: Yams
|
||||
- package: SwiftPM
|
||||
product: SPMUtility
|
||||
```
|
||||
|
||||
### Config Files
|
||||
|
||||
Specifies `.xcconfig` files for each configuration.
|
||||
@ -650,7 +676,7 @@ Schemes allows for more control than the convenience [Target Scheme](#target-sch
|
||||
|
||||
### Build
|
||||
|
||||
- [x] **targets**: **[String:String]**, **[String:[String]]** or **[String: [String: [Build Target](#build-target)]]** - A map of target names to build and which build types they should be enabled for. The build types can be `all`, `none`, or an array of the following types:
|
||||
- [x] **targets**: **[String:String]** or **[String:[String]]** - A map of target names to build and which build types they should be enabled for. The build types can be `all`, `none`, or an array of the following types:
|
||||
- `run` or `running`
|
||||
- `test` or `testing`
|
||||
- `profile` or `profiling`
|
||||
@ -673,10 +699,6 @@ parallelizeBuild: true
|
||||
buildImplicitDependencies: true
|
||||
```
|
||||
|
||||
### Build Target
|
||||
- [ ] **types** Build types they should be enabled for.
|
||||
- [ ] **externalProject**: **String** - `xcodeproj` file to reference target.
|
||||
|
||||
### Common Build Action options
|
||||
|
||||
The different actions share some properties:
|
||||
@ -714,7 +736,6 @@ A multiline script can be written using the various YAML multiline methods, for
|
||||
- [ ] **parallelizable**: **Bool** - Whether to run tests in parallel. Defaults to false
|
||||
- [ ] **randomExecutionOrder**: **Bool** - Whether to run tests in a random order. Defaults to false
|
||||
- [ ] **skippedTests**: **[String]** - List of tests in the test target to skip. Defaults to empty.
|
||||
- [ ] **externalProject**: **String** - `xcodeproj` file to reference target.
|
||||
|
||||
#### Coverage Target
|
||||
- [x] **name**: **String** - The name of the target
|
||||
@ -738,9 +759,6 @@ schemes:
|
||||
targets:
|
||||
MyTarget1: all
|
||||
MyTarget2: [run, archive]
|
||||
MyTarget3:
|
||||
types: [run, test]
|
||||
externalProject: ./Submodules/OtherProject.xcodeproj
|
||||
run:
|
||||
config: prod-debug
|
||||
commandLineArguments: "--option value"
|
||||
@ -757,7 +775,6 @@ schemes:
|
||||
targets:
|
||||
- Tester1
|
||||
- name: Tester2
|
||||
externalProject: ./Submodules/OtherProject.xcodeproj
|
||||
parallelizable: true
|
||||
randomExecutionOrder: true
|
||||
skippedTests: [Test/testExample()]
|
||||
@ -774,3 +791,79 @@ schemes:
|
||||
customArchiveName: MyTarget
|
||||
revealArchiveInOrganizer: false
|
||||
```
|
||||
|
||||
### Scheme Template
|
||||
|
||||
This is a template that can be referenced from a normal scheme using the `templates` property. The properties of this template are the same as a [Scheme](#scheme). This functions identically in practice to [Target Template](#target-template).
|
||||
Any instances of `${scheme_name}` within each template will be replaced by the final scheme name which references the template.
|
||||
Any attributes defined within a scheme's `templateAttributes` will be used to replace any attribute references in the template using the syntax `${attribute_name}`.
|
||||
|
||||
```yaml
|
||||
schemes:
|
||||
MyModule:
|
||||
templates:
|
||||
- FeatureModuleScheme
|
||||
templateAttributes:
|
||||
testTargetName: MyModuleTests
|
||||
|
||||
schemeTemplates:
|
||||
FeatureModuleScheme:
|
||||
templates:
|
||||
- TestScheme
|
||||
build:
|
||||
targets:
|
||||
${scheme_name}: build
|
||||
|
||||
TestScheme:
|
||||
test:
|
||||
gatherCoverageData: true
|
||||
targets:
|
||||
- name: ${testTargetName}
|
||||
parallelizable: true
|
||||
randomExecutionOrder: true
|
||||
```
|
||||
|
||||
The result will be a scheme that builds `MyModule` when you request a build, and will test against `MyModuleTests` when you request to run tests. This is particularly useful when you work in a very modular application and each module has a similar structure.
|
||||
|
||||
## Swift Package
|
||||
Swift packages are defined at a project level, and then linked to individual targets via a [Dependency](#dependency).
|
||||
|
||||
> Note that Swift Packages don't work in projects with configurations other than `Debug` and `Release`. That limitation is tracked here bugs.swift.org/browse/SR-10927
|
||||
|
||||
- [x] **url**: **URL** - the url to the package
|
||||
- [x] **version**: **String** - the version of the package to use. It can take a few forms:
|
||||
- `majorVersion: 1.2.0` or `from: 1.2.0`
|
||||
- `minorVersion: 1.2.1`
|
||||
- `exactVersion: 1.2.1` or `version: 1.2.1`
|
||||
- `minVersion: 1.0.0, maxVersion: 1.2.9`
|
||||
- `branch: master`
|
||||
- `revision: xxxxxx`
|
||||
|
||||
```yml
|
||||
packages:
|
||||
Yams:
|
||||
url: https://github.com/jpsim/Yams
|
||||
from: 2.0.0
|
||||
targets:
|
||||
App:
|
||||
dependencies:
|
||||
- package: Yams
|
||||
```
|
||||
|
||||
|
||||
## Project Reference
|
||||
|
||||
Project References are defined at a project level, and then you can use the project name to refer its target via a [Scheme](#scheme)
|
||||
|
||||
- [x] **path**: **String** - The path to the `xcodeproj` file to reference.
|
||||
|
||||
```yml
|
||||
projectReferences:
|
||||
YamsProject:
|
||||
path: ./Carthage/Checkouts/Yams/Yams.xcodeproj
|
||||
schemes:
|
||||
TestTarget:
|
||||
build:
|
||||
targets:
|
||||
YamsProject/Yams: ["run"]
|
||||
```
|
||||
|
@ -4,9 +4,10 @@
|
||||
- [Settings](#settings)
|
||||
- [Setting Groups](#setting-groups)
|
||||
- [xcconfig files](#xcconfig-files)
|
||||
- [Use dependencies](#use-dependencies)
|
||||
- [Dependencies](#dependencies)
|
||||
- [CocoaPods](#cocoapods)
|
||||
- [Carthage](#carthage)
|
||||
- [Swift Package](#swift-package)
|
||||
- [SDK](#sdk)
|
||||
- [Framework](#framework)
|
||||
|
||||
@ -92,7 +93,7 @@ You can also always overide any build settings on CI when building by passing sp
|
||||
DEVELOPMENT_TEAM=XXXXXXXXX xcodebuild ...
|
||||
```
|
||||
|
||||
# Use dependencies
|
||||
# Dependencies
|
||||
|
||||
Each target can declare one or more dependencies. See [Dependency](ProjectSpec.md#dependency) in the ProjectSpec for more info about all the properties
|
||||
|
||||
@ -153,6 +154,41 @@ options:
|
||||
carthageBuildPath: ../../Carthage/Build
|
||||
```
|
||||
|
||||
### Swift Package
|
||||
Swift Packages can be integrated by defining them at the project level and then referencing them in targets
|
||||
|
||||
```yaml
|
||||
packages:
|
||||
Yams:
|
||||
url: https://github.com/jpsim/Yams
|
||||
from: 2.0.0
|
||||
SwiftPM:
|
||||
url: https://github.com/apple/swift-package-manager
|
||||
branch: swift-5.0-branch
|
||||
targets:
|
||||
App:
|
||||
dependencies:
|
||||
# by default the package product that is linked to is the same as the package name
|
||||
- package: Yams
|
||||
- package: SwiftPM
|
||||
- package: SwiftPM
|
||||
product: SPMUtility # specify a specific product
|
||||
```
|
||||
If you want to check in the `Package.resolved` file so that everyone is on the same versions, you need to check in `ProjectName.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved`
|
||||
|
||||
> Note that Swift Packages don't work in projects with configurations other than `Debug` and `Release`. That limitation is tracked here bugs.swift.org/browse/SR-10927
|
||||
|
||||
You can also include local Swift Packages by referencing them by paths in `localPackages`. When these have the same name as `packages` they will be used instead of the remote repos. This is useful for local development.
|
||||
|
||||
```yml
|
||||
localPackages:
|
||||
- ../../Yams
|
||||
- ~/Developer/MyPackage
|
||||
```
|
||||
These local packages get put into a `Packages` group in the root of the project by default. This can be changed with `options.localPackagesGroup`
|
||||
|
||||
> For now local packages that don't mirror remote packages aren't able to be linked to
|
||||
|
||||
### SDK
|
||||
System frameworks and libs can be linked by using the `sdk` dependency type. You can either specify frameworks or libs by using a `.framework`, `.tbd` or `dylib` filename, respectively
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
TOOL_NAME = XcodeGen
|
||||
export EXECUTABLE_NAME = xcodegen
|
||||
VERSION = 2.7.0
|
||||
VERSION = 2.9.0
|
||||
|
||||
PREFIX = /usr/local
|
||||
INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME)
|
||||
|
@ -60,8 +60,8 @@
|
||||
"repositoryURL": "https://github.com/jakeheis/SwiftCLI.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "5318c37d3cacc8780f50b87a8840a6774320ebdf",
|
||||
"version": "5.2.2"
|
||||
"revision": "ba2268e67c07b9f9cfbc0801385e6238b36255eb",
|
||||
"version": "5.3.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -69,8 +69,8 @@
|
||||
"repositoryURL": "https://github.com/tuist/xcodeproj.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b951777f42e9acbfb8f19da623b43aaa604422f9",
|
||||
"version": "7.0.0"
|
||||
"revision": "aefcbf59cea5b0831837ed2f385e6dfd80d82cc9",
|
||||
"version": "7.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "XcodeGen",
|
||||
platforms: [.macOS(.v10_13)],
|
||||
products: [
|
||||
.executable(name: "xcodegen", targets: ["XcodeGen"]),
|
||||
.library(name: "XcodeGenKit", targets: ["XcodeGenKit"]),
|
||||
@ -15,8 +16,8 @@ let package = Package(
|
||||
.package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "4.2.0"),
|
||||
.package(url: "https://github.com/kylef/Spectre.git", from: "0.9.0"),
|
||||
.package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"),
|
||||
.package(url: "https://github.com/tuist/xcodeproj.git", .exact("7.0.0")),
|
||||
.package(url: "https://github.com/jakeheis/SwiftCLI.git", .exact("5.2.2")),
|
||||
.package(url: "https://github.com/tuist/xcodeproj.git", .exact("7.1.0")),
|
||||
.package(url: "https://github.com/jakeheis/SwiftCLI.git", .upToNextMinor(from: "5.3.2")),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "XcodeGen", dependencies: [
|
||||
|
@ -39,6 +39,10 @@ Given a very simple project spec file like this:
|
||||
name: MyProject
|
||||
options:
|
||||
bundleIdPrefix: com.myapp
|
||||
packages:
|
||||
Yams:
|
||||
url: https://github.com/jpsim/Yams
|
||||
from: 2.0.0
|
||||
targets:
|
||||
MyApp:
|
||||
type: application
|
||||
@ -57,7 +61,7 @@ targets:
|
||||
- framework: Vendor/MyFramework.framework
|
||||
- sdk: Contacts.framework
|
||||
- sdk: libc++.tbd
|
||||
- sdk: libz.dylib
|
||||
- package: Yams
|
||||
MyFramework:
|
||||
type: framework
|
||||
platform: iOS
|
||||
@ -103,7 +107,7 @@ swift run xcodegen
|
||||
Add the following to your Package.swift file's dependencies:
|
||||
|
||||
```swift
|
||||
.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.7.0"),
|
||||
.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.9.0"),
|
||||
```
|
||||
|
||||
And then import wherever needed: `import XcodeGenKit`
|
||||
|
@ -1,3 +1,3 @@
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"]
|
||||
SDKROOT: iphoneos
|
||||
TARGETED_DEVICE_FAMILY: '1,2'
|
||||
|
@ -1,3 +1,3 @@
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/../Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/../Frameworks"]
|
||||
SDKROOT: macosx
|
||||
COMBINE_HIDPI_IMAGES: 'YES'
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGETED_DEVICE_FAMILY: 3
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"]
|
||||
SDKROOT: appletvos
|
||||
|
@ -1 +1 @@
|
||||
LD_RUNPATH_SEARCH_PATHS: $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/../Frameworks", "@loader_path/../Frameworks"]
|
||||
|
@ -1 +1 @@
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks @executable_path/../../../../Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", "@executable_path/../../../../Frameworks"]
|
||||
|
@ -1,2 +1,2 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME: iMessage App Icon
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks"]
|
||||
|
@ -1 +1 @@
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks"]
|
||||
|
@ -1,2 +1,2 @@
|
||||
BUNDLE_LOADER: $(TEST_HOST)
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks"]
|
||||
|
@ -1,2 +1,2 @@
|
||||
BUNDLE_LOADER: $(TEST_HOST)
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks"]
|
||||
|
@ -1,2 +1,2 @@
|
||||
SKIP_INSTALL: 'YES'
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks"]
|
||||
|
@ -1,2 +1,2 @@
|
||||
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks"]
|
||||
ASSETCATALOG_COMPILER_COMPLICATION_NAME: Complication
|
||||
|
@ -38,6 +38,7 @@ public struct Dependency: Equatable {
|
||||
case framework
|
||||
case carthage(findFrameworks: Bool?)
|
||||
case sdk(root: String?)
|
||||
case package(product: String?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,6 +65,10 @@ extension Dependency: JSONObjectConvertible {
|
||||
let sdkRoot: String? = jsonDictionary.json(atKeyPath: "root")
|
||||
type = .sdk(root: sdkRoot)
|
||||
reference = sdk
|
||||
} else if let package: String = jsonDictionary.json(atKeyPath: "package") {
|
||||
let product: String? = jsonDictionary.json(atKeyPath: "product")
|
||||
type = .package(product: product)
|
||||
reference = package
|
||||
} else {
|
||||
throw SpecParsingError.invalidDependency(jsonDictionary)
|
||||
}
|
||||
@ -114,6 +119,8 @@ extension Dependency: JSONEncodable {
|
||||
}
|
||||
case .sdk:
|
||||
dict["sdk"] = reference
|
||||
case .package:
|
||||
dict["package"] = reference
|
||||
}
|
||||
|
||||
return dict
|
||||
|
@ -19,6 +19,9 @@ public struct Project: BuildSettingsContainer {
|
||||
}
|
||||
}
|
||||
|
||||
public var packages: [String: SwiftPackage]
|
||||
public var localPackages: [String]
|
||||
|
||||
public var settings: Settings
|
||||
public var settingGroups: [String: Settings]
|
||||
public var configs: [Config]
|
||||
@ -28,15 +31,15 @@ public struct Project: BuildSettingsContainer {
|
||||
public var fileGroups: [String]
|
||||
public var configFiles: [String: String]
|
||||
public var include: [String] = []
|
||||
public var externalProjects: [ExternalProject] = [] {
|
||||
public var projectReferences: [ProjectReference] = [] {
|
||||
didSet {
|
||||
externalProjectsMap = Dictionary(uniqueKeysWithValues: externalProjects.map { ($0.name, $0) })
|
||||
projectReferencesMap = Dictionary(uniqueKeysWithValues: projectReferences.map { ($0.name, $0) })
|
||||
}
|
||||
}
|
||||
|
||||
private var targetsMap: [String: Target]
|
||||
private var aggregateTargetsMap: [String: AggregateTarget]
|
||||
private var externalProjectsMap: [String: ExternalProject]
|
||||
private var projectReferencesMap: [String: ProjectReference]
|
||||
|
||||
public init(
|
||||
basePath: Path = "",
|
||||
@ -47,11 +50,13 @@ public struct Project: BuildSettingsContainer {
|
||||
settings: Settings = .empty,
|
||||
settingGroups: [String: Settings] = [:],
|
||||
schemes: [Scheme] = [],
|
||||
packages: [String: SwiftPackage] = [:],
|
||||
localPackages: [String] = [],
|
||||
options: SpecOptions = SpecOptions(),
|
||||
fileGroups: [String] = [],
|
||||
configFiles: [String: String] = [:],
|
||||
attributes: [String: Any] = [:],
|
||||
externalProjects: [ExternalProject] = []
|
||||
projectReferences: [ProjectReference] = []
|
||||
) {
|
||||
self.basePath = basePath
|
||||
self.name = name
|
||||
@ -63,16 +68,18 @@ public struct Project: BuildSettingsContainer {
|
||||
self.settings = settings
|
||||
self.settingGroups = settingGroups
|
||||
self.schemes = schemes
|
||||
self.packages = packages
|
||||
self.localPackages = localPackages
|
||||
self.options = options
|
||||
self.fileGroups = fileGroups
|
||||
self.configFiles = configFiles
|
||||
self.attributes = attributes
|
||||
self.externalProjects = externalProjects
|
||||
externalProjectsMap = Dictionary(uniqueKeysWithValues: self.externalProjects.map { ($0.name, $0) })
|
||||
self.projectReferences = projectReferences
|
||||
projectReferencesMap = Dictionary(uniqueKeysWithValues: self.projectReferences.map { ($0.name, $0) })
|
||||
}
|
||||
|
||||
public func getExternalProject(_ projectName: String) -> ExternalProject? {
|
||||
return externalProjectsMap[projectName]
|
||||
public func getProjectReference(_ projectName: String) -> ProjectReference? {
|
||||
return projectReferencesMap[projectName]
|
||||
}
|
||||
|
||||
public func getTarget(_ targetName: String) -> Target? {
|
||||
@ -139,6 +146,8 @@ extension Project: Equatable {
|
||||
lhs.fileGroups == rhs.fileGroups &&
|
||||
lhs.configFiles == rhs.configFiles &&
|
||||
lhs.options == rhs.options &&
|
||||
lhs.packages == rhs.packages &&
|
||||
lhs.localPackages == rhs.localPackages &&
|
||||
NSDictionary(dictionary: lhs.attributes).isEqual(to: rhs.attributes)
|
||||
}
|
||||
}
|
||||
@ -157,7 +166,7 @@ extension Project {
|
||||
public init(basePath: Path = "", jsonDictionary: JSONDictionary) throws {
|
||||
self.basePath = basePath
|
||||
|
||||
let jsonDictionary = try Project.resolveProject(jsonDictionary: jsonDictionary)
|
||||
let jsonDictionary = Project.resolveProject(jsonDictionary: jsonDictionary)
|
||||
|
||||
name = try jsonDictionary.json(atKeyPath: "name")
|
||||
settings = jsonDictionary.json(atKeyPath: "settings") ?? .empty
|
||||
@ -168,12 +177,18 @@ extension Project {
|
||||
configs.map { Config(name: $0, type: ConfigType(rawValue: $1)) }.sorted { $0.name < $1.name }
|
||||
targets = try jsonDictionary.json(atKeyPath: "targets").sorted { $0.name < $1.name }
|
||||
aggregateTargets = try jsonDictionary.json(atKeyPath: "aggregateTargets").sorted { $0.name < $1.name }
|
||||
externalProjects = try jsonDictionary.json(atKeyPath: "externalProjects").sorted { $0.name < $1.name }
|
||||
projectReferences = try jsonDictionary.json(atKeyPath: "projectReferences").sorted { $0.name < $1.name }
|
||||
schemes = try jsonDictionary.json(atKeyPath: "schemes")
|
||||
fileGroups = jsonDictionary.json(atKeyPath: "fileGroups") ?? []
|
||||
configFiles = jsonDictionary.json(atKeyPath: "configFiles") ?? [:]
|
||||
attributes = jsonDictionary.json(atKeyPath: "attributes") ?? [:]
|
||||
include = jsonDictionary.json(atKeyPath: "include") ?? []
|
||||
if jsonDictionary["packages"] != nil {
|
||||
packages = try jsonDictionary.json(atKeyPath: "packages", invalidItemBehaviour: .fail)
|
||||
} else {
|
||||
packages = [:]
|
||||
}
|
||||
localPackages = jsonDictionary.json(atKeyPath: "localPackages") ?? []
|
||||
if jsonDictionary["options"] != nil {
|
||||
options = try jsonDictionary.json(atKeyPath: "options")
|
||||
} else {
|
||||
@ -181,17 +196,18 @@ extension Project {
|
||||
}
|
||||
targetsMap = Dictionary(uniqueKeysWithValues: targets.map { ($0.name, $0) })
|
||||
aggregateTargetsMap = Dictionary(uniqueKeysWithValues: aggregateTargets.map { ($0.name, $0) })
|
||||
externalProjectsMap = Dictionary(uniqueKeysWithValues: externalProjects.map { ($0.name, $0) })
|
||||
projectReferencesMap = Dictionary(uniqueKeysWithValues: projectReferences.map { ($0.name, $0) })
|
||||
}
|
||||
|
||||
static func resolveProject(jsonDictionary: JSONDictionary) throws -> JSONDictionary {
|
||||
static func resolveProject(jsonDictionary: JSONDictionary) -> JSONDictionary {
|
||||
var jsonDictionary = jsonDictionary
|
||||
|
||||
// resolve multiple times so that we support both multi-platform templates,
|
||||
// as well as platform specific templates in multi-platform targets
|
||||
jsonDictionary = try Target.resolveMultiplatformTargets(jsonDictionary: jsonDictionary)
|
||||
jsonDictionary = try Target.resolveTargetTemplates(jsonDictionary: jsonDictionary)
|
||||
jsonDictionary = try Target.resolveMultiplatformTargets(jsonDictionary: jsonDictionary)
|
||||
jsonDictionary = Target.resolveMultiplatformTargets(jsonDictionary: jsonDictionary)
|
||||
jsonDictionary = Target.resolveTargetTemplates(jsonDictionary: jsonDictionary)
|
||||
jsonDictionary = Scheme.resolveSchemeTemplates(jsonDictionary: jsonDictionary)
|
||||
jsonDictionary = Target.resolveMultiplatformTargets(jsonDictionary: jsonDictionary)
|
||||
|
||||
return jsonDictionary
|
||||
}
|
||||
@ -202,6 +218,7 @@ extension Project: PathContainer {
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.string("configFiles"),
|
||||
.string("localPackages"),
|
||||
.object("options", SpecOptions.pathProperties),
|
||||
.object("targets", Target.pathProperties),
|
||||
.object("targetTemplates", Target.pathProperties),
|
||||
@ -256,48 +273,25 @@ extension Project: JSONEncodable {
|
||||
let configsPairs = configs.map { ($0.name, $0.type?.rawValue) }
|
||||
let aggregateTargetsPairs = aggregateTargets.map { ($0.name, $0.toJSONValue()) }
|
||||
let schemesPairs = schemes.map { ($0.name, $0.toJSONValue()) }
|
||||
let externalProjectsPairs = externalProjects.map { ($0.name, $0.toJSONValue()) }
|
||||
let projectReferencesPairs = projectReferences.map { ($0.name, $0.toJSONValue()) }
|
||||
|
||||
return [
|
||||
"name": name,
|
||||
"options": options.toJSONValue(),
|
||||
"settings": settings.toJSONValue(),
|
||||
"fileGroups": fileGroups,
|
||||
"configFiles": configFiles,
|
||||
"include": include,
|
||||
"attributes": attributes,
|
||||
"targets": Dictionary(uniqueKeysWithValues: targetPairs),
|
||||
"configs": Dictionary(uniqueKeysWithValues: configsPairs),
|
||||
"aggregateTargets": Dictionary(uniqueKeysWithValues: aggregateTargetsPairs),
|
||||
"schemes": Dictionary(uniqueKeysWithValues: schemesPairs),
|
||||
"settingGroups": settingGroups.mapValues { $0.toJSONValue() },
|
||||
"externalProjects": externalProjectsPairs,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct ExternalProject {
|
||||
public let name: String
|
||||
public let path: String
|
||||
|
||||
public init(name: String, path: String) {
|
||||
self.name = name
|
||||
self.path = path
|
||||
}
|
||||
}
|
||||
|
||||
extension ExternalProject: NamedJSONDictionaryConvertible {
|
||||
public init(name: String, jsonDictionary: JSONDictionary) throws {
|
||||
self.name = name
|
||||
self.path = try jsonDictionary.json(atKeyPath: "path")
|
||||
}
|
||||
}
|
||||
|
||||
extension ExternalProject: JSONEncodable {
|
||||
public func toJSONValue() -> Any {
|
||||
return [
|
||||
"path": path,
|
||||
]
|
||||
var dictionary: JSONDictionary = [:]
|
||||
dictionary["name"] = name
|
||||
dictionary["options"] = options.toJSONValue()
|
||||
dictionary["settings"] = settings.toJSONValue()
|
||||
dictionary["fileGroups"] = fileGroups
|
||||
dictionary["configFiles"] = configFiles
|
||||
dictionary["include"] = include
|
||||
dictionary["attributes"] = attributes
|
||||
dictionary["packages"] = packages.mapValues { $0.toJSONValue() }
|
||||
dictionary["localPackages"] = localPackages
|
||||
dictionary["targets"] = Dictionary(uniqueKeysWithValues: targetPairs)
|
||||
dictionary["configs"] = Dictionary(uniqueKeysWithValues: configsPairs)
|
||||
dictionary["aggregateTargets"] = Dictionary(uniqueKeysWithValues: aggregateTargetsPairs)
|
||||
dictionary["schemes"] = Dictionary(uniqueKeysWithValues: schemesPairs)
|
||||
dictionary["settingGroups"] = settingGroups.mapValues { $0.toJSONValue() }
|
||||
dictionary["projectReferences"] = projectReferencesPairs
|
||||
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
27
Sources/ProjectSpec/ProjectReference.swift
Normal file
27
Sources/ProjectSpec/ProjectReference.swift
Normal file
@ -0,0 +1,27 @@
|
||||
import Foundation
|
||||
import JSONUtilities
|
||||
|
||||
public struct ProjectReference: Hashable {
|
||||
public var name: String
|
||||
public var path: String
|
||||
|
||||
public init(name: String, path: String) {
|
||||
self.name = name
|
||||
self.path = path
|
||||
}
|
||||
}
|
||||
|
||||
extension ProjectReference: NamedJSONDictionaryConvertible {
|
||||
public init(name: String, jsonDictionary: JSONDictionary) throws {
|
||||
self.name = name
|
||||
self.path = try jsonDictionary.json(atKeyPath: "path")
|
||||
}
|
||||
}
|
||||
|
||||
extension ProjectReference: JSONEncodable {
|
||||
public func toJSONValue() -> Any {
|
||||
return [
|
||||
"path": path,
|
||||
]
|
||||
}
|
||||
}
|
@ -146,7 +146,7 @@ public struct Scheme: Equatable {
|
||||
|
||||
public init(stringLiteral value: String) {
|
||||
do {
|
||||
targetReference = try TargetReference(string: value)
|
||||
targetReference = try TargetReference(value)
|
||||
randomExecutionOrder = false
|
||||
parallelizable = false
|
||||
skippedTests = []
|
||||
@ -246,7 +246,7 @@ public struct Scheme: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct BuildTarget: Equatable {
|
||||
public struct BuildTarget: Equatable, Hashable {
|
||||
public var target: TargetReference
|
||||
public var buildTypes: [BuildType]
|
||||
|
||||
@ -257,50 +257,6 @@ public struct Scheme: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct TargetReference: Equatable {
|
||||
public let name: String
|
||||
public let location: Location
|
||||
|
||||
public enum Location: Equatable {
|
||||
case local
|
||||
case project(String)
|
||||
}
|
||||
|
||||
public init(name: String, location: Location = .local) {
|
||||
self.name = name
|
||||
self.location = location
|
||||
}
|
||||
}
|
||||
|
||||
extension TargetReference {
|
||||
public init(string: String) throws {
|
||||
let paths = string.split(separator: "/")
|
||||
guard paths.count <= 2 && !paths.isEmpty else {
|
||||
throw SpecParsingError.invalidTargetReference(string)
|
||||
}
|
||||
switch paths.count {
|
||||
case 2:
|
||||
location = .project(String(paths[0]))
|
||||
name = String(paths[1])
|
||||
case 1:
|
||||
location = .local
|
||||
name = String(paths[0])
|
||||
default: fatalError("unreachable")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TargetReference {
|
||||
public func toString() -> String {
|
||||
switch location {
|
||||
case .local: return name
|
||||
case .project(let projectPath):
|
||||
return "\(projectPath)/\(name)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol BuildAction: Equatable {
|
||||
var config: String? { get }
|
||||
}
|
||||
@ -367,13 +323,13 @@ extension Scheme.Test: JSONObjectConvertible {
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
config = jsonDictionary.json(atKeyPath: "config")
|
||||
gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? Scheme.Test.gatherCoverageDataDefault
|
||||
coverageTargets = try (jsonDictionary.json(atKeyPath: "coverageTargets") ?? []).map { try TargetReference(string: $0) }
|
||||
coverageTargets = try (jsonDictionary.json(atKeyPath: "coverageTargets") ?? []).map { try TargetReference($0) }
|
||||
disableMainThreadChecker = jsonDictionary.json(atKeyPath: "disableMainThreadChecker") ?? Scheme.Test.disableMainThreadCheckerDefault
|
||||
commandLineArguments = jsonDictionary.json(atKeyPath: "commandLineArguments") ?? [:]
|
||||
if let targets = jsonDictionary["targets"] as? [Any] {
|
||||
self.targets = try targets.compactMap { target in
|
||||
if let string = target as? String {
|
||||
return TestTarget(stringLiteral: string)
|
||||
return try TestTarget(targetReference: TargetReference(string))
|
||||
} else if let dictionary = target as? JSONDictionary {
|
||||
return try TestTarget(jsonDictionary: dictionary)
|
||||
} else {
|
||||
@ -403,7 +359,7 @@ extension Scheme.Test: JSONEncodable {
|
||||
"config": config,
|
||||
"language": language,
|
||||
"region": region,
|
||||
"coverageTargets": coverageTargets.map { $0.toString() },
|
||||
"coverageTargets": coverageTargets.map { $0.reference },
|
||||
]
|
||||
|
||||
if gatherCoverageData != Scheme.Test.gatherCoverageDataDefault {
|
||||
@ -425,7 +381,7 @@ extension Scheme.Test: JSONEncodable {
|
||||
extension Scheme.Test.TestTarget: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
targetReference = try TargetReference(string: jsonDictionary.json(atKeyPath: "name"))
|
||||
targetReference = try TargetReference(jsonDictionary.json(atKeyPath: "name"))
|
||||
randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? Scheme.Test.TestTarget.randomExecutionOrderDefault
|
||||
parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? Scheme.Test.TestTarget.parallelizableDefault
|
||||
skippedTests = jsonDictionary.json(atKeyPath: "skippedTests") ?? []
|
||||
@ -436,11 +392,11 @@ extension Scheme.Test.TestTarget: JSONEncodable {
|
||||
public func toJSONValue() -> Any {
|
||||
if randomExecutionOrder == Scheme.Test.TestTarget.randomExecutionOrderDefault,
|
||||
parallelizable == Scheme.Test.TestTarget.parallelizableDefault {
|
||||
return targetReference.toString()
|
||||
return targetReference.reference
|
||||
}
|
||||
|
||||
var dict: JSONDictionary = [
|
||||
"name": targetReference.toString(),
|
||||
"name": targetReference.reference,
|
||||
]
|
||||
|
||||
if randomExecutionOrder != Scheme.Test.TestTarget.randomExecutionOrderDefault {
|
||||
@ -568,7 +524,7 @@ extension Scheme.Build: JSONObjectConvertible {
|
||||
} else {
|
||||
buildTypes = BuildType.all
|
||||
}
|
||||
let target = try TargetReference(string: targetRepr)
|
||||
let target = try TargetReference(targetRepr)
|
||||
targets.append(Scheme.BuildTarget(target: target, buildTypes: buildTypes))
|
||||
}
|
||||
self.targets = targets.sorted { $0.target.name < $1.target.name }
|
||||
@ -581,7 +537,7 @@ extension Scheme.Build: JSONObjectConvertible {
|
||||
|
||||
extension Scheme.Build: JSONEncodable {
|
||||
public func toJSONValue() -> Any {
|
||||
let targetPairs = targets.map { ($0.target.toString(), $0.buildTypes.map { $0.toJSONValue() }) }
|
||||
let targetPairs = targets.map { ($0.target.reference, $0.buildTypes.map { $0.toJSONValue() }) }
|
||||
|
||||
var dict: JSONDictionary = [
|
||||
"targets": Dictionary(uniqueKeysWithValues: targetPairs),
|
||||
|
@ -158,7 +158,11 @@ extension Dictionary where Key == String, Value: Any {
|
||||
func replaceString(_ template: String, with replacement: String) -> JSONDictionary {
|
||||
var replaced: JSONDictionary = self
|
||||
for (key, value) in self {
|
||||
replaced[key] = replace(value: value, template, with: replacement)
|
||||
let newKey = key.replacingOccurrences(of: template, with: replacement)
|
||||
if newKey != key {
|
||||
replaced.removeValue(forKey: key)
|
||||
}
|
||||
replaced[newKey] = replace(value: value, template, with: replacement)
|
||||
}
|
||||
return replaced
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public struct SpecOptions: Equatable {
|
||||
public var groupSortPosition: GroupSortPosition
|
||||
public var generateEmptyDirectories: Bool
|
||||
public var findCarthageFrameworks: Bool
|
||||
public var localPackagesGroup: String?
|
||||
|
||||
public enum ValidationType: String {
|
||||
case missingConfigs
|
||||
@ -82,7 +83,8 @@ public struct SpecOptions: Equatable {
|
||||
transitivelyLinkDependencies: Bool = transitivelyLinkDependenciesDefault,
|
||||
groupSortPosition: GroupSortPosition = groupSortPositionDefault,
|
||||
generateEmptyDirectories: Bool = generateEmptyDirectoriesDefault,
|
||||
findCarthageFrameworks: Bool = findCarthageFrameworksDefault
|
||||
findCarthageFrameworks: Bool = findCarthageFrameworksDefault,
|
||||
localPackagesGroup: String? = nil
|
||||
) {
|
||||
self.minimumXcodeGenVersion = minimumXcodeGenVersion
|
||||
self.carthageBuildPath = carthageBuildPath
|
||||
@ -102,6 +104,7 @@ public struct SpecOptions: Equatable {
|
||||
self.groupSortPosition = groupSortPosition
|
||||
self.generateEmptyDirectories = generateEmptyDirectories
|
||||
self.findCarthageFrameworks = findCarthageFrameworks
|
||||
self.localPackagesGroup = localPackagesGroup
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,6 +132,7 @@ extension SpecOptions: JSONObjectConvertible {
|
||||
groupSortPosition = jsonDictionary.json(atKeyPath: "groupSortPosition") ?? SpecOptions.groupSortPositionDefault
|
||||
generateEmptyDirectories = jsonDictionary.json(atKeyPath: "generateEmptyDirectories") ?? SpecOptions.generateEmptyDirectoriesDefault
|
||||
findCarthageFrameworks = jsonDictionary.json(atKeyPath: "findCarthageFrameworks") ?? SpecOptions.findCarthageFrameworksDefault
|
||||
localPackagesGroup = jsonDictionary.json(atKeyPath: "localPackagesGroup")
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,6 +153,7 @@ extension SpecOptions: JSONEncodable {
|
||||
"indentWidth": indentWidth.flatMap { Int($0) },
|
||||
"tabWidth": tabWidth.flatMap { Int($0) },
|
||||
"defaultConfig": defaultConfig,
|
||||
"localPackagesGroup": localPackagesGroup,
|
||||
]
|
||||
|
||||
if settingPresets != SpecOptions.settingPresetsDefault {
|
||||
|
@ -4,6 +4,7 @@ public enum SpecParsingError: Error, CustomStringConvertible {
|
||||
case unknownTargetType(String)
|
||||
case unknownTargetPlatform(String)
|
||||
case invalidDependency([String: Any])
|
||||
case unknownPackageRequirement([String: Any])
|
||||
case invalidSourceBuildPhase(String)
|
||||
case invalidTargetReference(String)
|
||||
case invalidVersion(String)
|
||||
@ -22,6 +23,8 @@ public enum SpecParsingError: Error, CustomStringConvertible {
|
||||
return "Invalid Target Reference Syntax: \(targetReference)"
|
||||
case let .invalidVersion(version):
|
||||
return "Invalid version: \(version)"
|
||||
case let .unknownPackageRequirement(package):
|
||||
return "Unknown package requirement: \(package)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,12 @@ extension Project {
|
||||
}
|
||||
}
|
||||
|
||||
for package in localPackages {
|
||||
if !(basePath + Path(package).normalize()).exists {
|
||||
errors.append(.invalidLocalPackage(package))
|
||||
}
|
||||
}
|
||||
|
||||
for (config, configFile) in configFiles {
|
||||
if !options.disabledValidations.contains(.missingConfigFiles) && !(basePath + configFile).exists {
|
||||
errors.append(.invalidConfigFile(configFile: configFile, config: config))
|
||||
@ -156,6 +162,10 @@ extension Project {
|
||||
errors.append(.invalidSDKDependency(target: target.name, dependency: dependency.reference))
|
||||
}
|
||||
}
|
||||
case .package:
|
||||
if packages[dependency.reference] == nil {
|
||||
errors.append(.invalidSwiftPackage(name: dependency.reference, target: target.name))
|
||||
}
|
||||
default: break
|
||||
}
|
||||
}
|
||||
@ -170,9 +180,15 @@ extension Project {
|
||||
|
||||
for scheme in schemes {
|
||||
for buildTarget in scheme.build.targets {
|
||||
guard buildTarget.target.location == .local else { continue }
|
||||
if getProjectTarget(buildTarget.target.name) == nil {
|
||||
errors.append(.invalidSchemeTarget(scheme: scheme.name, target: buildTarget.target.name))
|
||||
switch buildTarget.target.location {
|
||||
case .local:
|
||||
if getProjectTarget(buildTarget.target.name) == nil {
|
||||
errors.append(.invalidSchemeTarget(scheme: scheme.name, target: buildTarget.target.name))
|
||||
}
|
||||
case .project(let project):
|
||||
if getProjectReference(project) == nil {
|
||||
errors.append(.invalidProjectReference(scheme: scheme.name, reference: project))
|
||||
}
|
||||
}
|
||||
}
|
||||
if let action = scheme.run, let config = action.config, getConfig(config) == nil {
|
||||
|
@ -18,6 +18,8 @@ public struct SpecValidationError: Error, CustomStringConvertible {
|
||||
case invalidTargetSchemeTest(target: String, testTarget: String)
|
||||
case invalidSchemeTarget(scheme: String, target: String)
|
||||
case invalidSchemeConfig(scheme: String, config: String)
|
||||
case invalidSwiftPackage(name: String, target: String)
|
||||
case invalidLocalPackage(String)
|
||||
case invalidConfigFile(configFile: String, config: String)
|
||||
case invalidBuildSettingConfig(String)
|
||||
case invalidSettingsGroup(String)
|
||||
@ -27,6 +29,7 @@ public struct SpecValidationError: Error, CustomStringConvertible {
|
||||
case missingConfigForTargetScheme(target: String, configType: ConfigType)
|
||||
case missingDefaultConfig(configName: String)
|
||||
case invalidPerConfigSettings
|
||||
case invalidProjectReference(scheme: String, reference: String)
|
||||
case deprecatedUsageOfPlaceholder(placeholderName: String)
|
||||
|
||||
public var description: String {
|
||||
@ -61,12 +64,18 @@ public struct SpecValidationError: Error, CustomStringConvertible {
|
||||
return "Invalid file group \(group.quoted)"
|
||||
case let .invalidConfigFileConfig(config):
|
||||
return "Config file has invalid config \(config.quoted)"
|
||||
case let .invalidSwiftPackage(name, target):
|
||||
return "Target \(target.quoted) has an invalid package dependency \(name.quoted)"
|
||||
case let .invalidLocalPackage(path):
|
||||
return "Invalid local package \(path.quoted)"
|
||||
case let .missingConfigForTargetScheme(target, configType):
|
||||
return "Target \(target.quoted) is missing a config of type \(configType.rawValue) to generate its scheme"
|
||||
case let .missingDefaultConfig(name):
|
||||
return "Default configuration \(name) doesn't exist"
|
||||
case .invalidPerConfigSettings:
|
||||
return "Settings that are for a specific config must go in \"configs\". \"base\" can be used for common settings"
|
||||
case let .invalidProjectReference(scheme, project):
|
||||
return "Scheme \(scheme.quoted) has invalid project reference \(project.quoted)"
|
||||
case let .deprecatedUsageOfPlaceholder(placeholderName: placeholderName):
|
||||
return "Usage of $\(placeholderName) is deprecated and will stop working in an upcoming version. Use ${\(placeholderName)} instead."
|
||||
}
|
||||
|
77
Sources/ProjectSpec/SwiftPackage.swift
Normal file
77
Sources/ProjectSpec/SwiftPackage.swift
Normal file
@ -0,0 +1,77 @@
|
||||
import Foundation
|
||||
import XcodeProj
|
||||
import JSONUtilities
|
||||
|
||||
public struct SwiftPackage: Equatable {
|
||||
|
||||
public typealias VersionRequirement = XCRemoteSwiftPackageReference.VersionRequirement
|
||||
|
||||
public let url: String
|
||||
public let versionRequirement: VersionRequirement
|
||||
|
||||
public init(url: String, versionRequirement: VersionRequirement) {
|
||||
self.url = url
|
||||
self.versionRequirement = versionRequirement
|
||||
}
|
||||
}
|
||||
|
||||
extension SwiftPackage: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
url = try jsonDictionary.json(atKeyPath: "url")
|
||||
versionRequirement = try VersionRequirement(jsonDictionary: jsonDictionary)
|
||||
}
|
||||
}
|
||||
|
||||
extension SwiftPackage: JSONEncodable {
|
||||
|
||||
public func toJSONValue() -> Any {
|
||||
var dictionary: JSONDictionary = [:]
|
||||
dictionary["url"] = url
|
||||
|
||||
switch versionRequirement {
|
||||
|
||||
case .upToNextMajorVersion(let version):
|
||||
dictionary["majorVersion"] = version
|
||||
case .upToNextMinorVersion(let version):
|
||||
dictionary["minorVersion"] = version
|
||||
case .range(let from, let to):
|
||||
dictionary["minVersion"] = from
|
||||
dictionary["maxVersion"] = to
|
||||
case .exact(let version):
|
||||
dictionary["exactVersion"] = version
|
||||
case .branch(let branch):
|
||||
dictionary["branch"] = branch
|
||||
case .revision(let revision):
|
||||
dictionary["revision"] = revision
|
||||
}
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
extension SwiftPackage.VersionRequirement: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
if jsonDictionary["exactVersion"] != nil {
|
||||
self = try .exact(jsonDictionary.json(atKeyPath: "exactVersion"))
|
||||
} else if jsonDictionary["version"] != nil {
|
||||
self = try .exact(jsonDictionary.json(atKeyPath: "version"))
|
||||
} else if jsonDictionary["revision"] != nil {
|
||||
self = try .revision(jsonDictionary.json(atKeyPath: "revision"))
|
||||
} else if jsonDictionary["branch"] != nil {
|
||||
self = try .branch(jsonDictionary.json(atKeyPath: "branch"))
|
||||
} else if jsonDictionary["minVersion"] != nil && jsonDictionary["maxVersion"] != nil {
|
||||
let minimum: String = try jsonDictionary.json(atKeyPath: "minVersion")
|
||||
let maximum: String = try jsonDictionary.json(atKeyPath: "maxVersion")
|
||||
self = .range(from: minimum, to: maximum)
|
||||
} else if jsonDictionary["minorVersion"] != nil {
|
||||
self = try .upToNextMinorVersion(jsonDictionary.json(atKeyPath: "minorVersion"))
|
||||
} else if jsonDictionary["majorVersion"] != nil {
|
||||
self = try .upToNextMajorVersion(jsonDictionary.json(atKeyPath: "majorVersion"))
|
||||
} else if jsonDictionary["from"] != nil {
|
||||
self = try .upToNextMajorVersion(jsonDictionary.json(atKeyPath: "from"))
|
||||
} else {
|
||||
throw SpecParsingError.unknownPackageRequirement(jsonDictionary)
|
||||
}
|
||||
}
|
||||
}
|
@ -134,59 +134,7 @@ extension Target: PathContainer {
|
||||
|
||||
extension Target {
|
||||
|
||||
static func resolveTargetTemplates(jsonDictionary: JSONDictionary) throws -> JSONDictionary {
|
||||
guard var targetsDictionary: [String: JSONDictionary] = jsonDictionary["targets"] as? [String: JSONDictionary] else {
|
||||
return jsonDictionary
|
||||
}
|
||||
|
||||
let targetTemplatesDictionary: [String: JSONDictionary] = jsonDictionary["targetTemplates"] as? [String: JSONDictionary] ?? [:]
|
||||
|
||||
// Recursively collects all nested template names of a given dictionary.
|
||||
func collectTemplates(of jsonDictionary: JSONDictionary,
|
||||
into allTemplates: inout [String],
|
||||
insertAt insertionIndex: inout Int) {
|
||||
guard let templates = jsonDictionary["templates"] as? [String] else {
|
||||
return
|
||||
}
|
||||
for template in templates where !allTemplates.contains(template) {
|
||||
guard let templateDictionary = targetTemplatesDictionary[template] else {
|
||||
continue
|
||||
}
|
||||
allTemplates.insert(template, at: insertionIndex)
|
||||
collectTemplates(of: templateDictionary, into: &allTemplates, insertAt: &insertionIndex)
|
||||
insertionIndex += 1
|
||||
}
|
||||
}
|
||||
|
||||
for (targetName, var target) in targetsDictionary {
|
||||
var templates: [String] = []
|
||||
var index: Int = 0
|
||||
collectTemplates(of: target, into: &templates, insertAt: &index)
|
||||
if !templates.isEmpty {
|
||||
var mergedDictionary: JSONDictionary = [:]
|
||||
for template in templates {
|
||||
if let templateDictionary = targetTemplatesDictionary[template] {
|
||||
mergedDictionary = templateDictionary.merged(onto: mergedDictionary)
|
||||
}
|
||||
}
|
||||
target = target.merged(onto: mergedDictionary)
|
||||
target = target.replaceString("$target_name", with: targetName) // Will be removed in upcoming version
|
||||
target = target.replaceString("${target_name}", with: targetName)
|
||||
if let templateAttributes = target["templateAttributes"] as? [String: String] {
|
||||
for (templateAttribute, value) in templateAttributes {
|
||||
target = target.replaceString("${\(templateAttribute)}", with: value)
|
||||
}
|
||||
}
|
||||
}
|
||||
targetsDictionary[targetName] = target
|
||||
}
|
||||
|
||||
var jsonDictionary = jsonDictionary
|
||||
jsonDictionary["targets"] = targetsDictionary
|
||||
return jsonDictionary
|
||||
}
|
||||
|
||||
static func resolveMultiplatformTargets(jsonDictionary: JSONDictionary) throws -> JSONDictionary {
|
||||
static func resolveMultiplatformTargets(jsonDictionary: JSONDictionary) -> JSONDictionary {
|
||||
guard let targetsDictionary: [String: JSONDictionary] = jsonDictionary["targets"] as? [String: JSONDictionary] else {
|
||||
return jsonDictionary
|
||||
}
|
||||
|
57
Sources/ProjectSpec/TargetReference.swift
Normal file
57
Sources/ProjectSpec/TargetReference.swift
Normal file
@ -0,0 +1,57 @@
|
||||
import Foundation
|
||||
import JSONUtilities
|
||||
|
||||
public struct TargetReference: Hashable {
|
||||
public var name: String
|
||||
public var location: Location
|
||||
|
||||
public enum Location: Hashable {
|
||||
case local
|
||||
case project(String)
|
||||
}
|
||||
|
||||
public init(name: String, location: Location) {
|
||||
self.name = name
|
||||
self.location = location
|
||||
}
|
||||
}
|
||||
|
||||
extension TargetReference {
|
||||
public init(_ string: String) throws {
|
||||
let paths = string.split(separator: "/")
|
||||
switch paths.count {
|
||||
case 2:
|
||||
location = .project(String(paths[0]))
|
||||
name = String(paths[1])
|
||||
case 1:
|
||||
location = .local
|
||||
name = String(paths[0])
|
||||
default:
|
||||
throw SpecParsingError.invalidTargetReference(string)
|
||||
}
|
||||
}
|
||||
|
||||
public static func local(_ name: String) -> TargetReference {
|
||||
return TargetReference(name: name, location: .local)
|
||||
}
|
||||
}
|
||||
|
||||
extension TargetReference: ExpressibleByStringLiteral {
|
||||
public init(stringLiteral value: String) {
|
||||
try! self.init(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension TargetReference: CustomStringConvertible {
|
||||
public var reference: String {
|
||||
switch location {
|
||||
case .local: return name
|
||||
case .project(let projectPath):
|
||||
return "\(projectPath)/\(name)"
|
||||
}
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
return reference
|
||||
}
|
||||
}
|
@ -42,7 +42,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(stringLiteral: string)
|
||||
return .init(targetReference: try TargetReference(string))
|
||||
} else if let dictionary = target as? JSONDictionary {
|
||||
return try .init(jsonDictionary: dictionary)
|
||||
} else {
|
||||
|
78
Sources/ProjectSpec/Template.swift
Normal file
78
Sources/ProjectSpec/Template.swift
Normal file
@ -0,0 +1,78 @@
|
||||
import Foundation
|
||||
import JSONUtilities
|
||||
|
||||
struct TemplateStructure {
|
||||
let baseKey: String
|
||||
let templatesKey: String
|
||||
let nameToReplace: String
|
||||
}
|
||||
|
||||
extension Target {
|
||||
static func resolveTargetTemplates(jsonDictionary: JSONDictionary) -> JSONDictionary {
|
||||
return resolveTemplates(jsonDictionary: jsonDictionary,
|
||||
templateStructure: TemplateStructure(baseKey: "targets",
|
||||
templatesKey: "targetTemplates",
|
||||
nameToReplace: "target_name"))
|
||||
}
|
||||
}
|
||||
|
||||
extension Scheme {
|
||||
static func resolveSchemeTemplates(jsonDictionary: JSONDictionary) -> JSONDictionary {
|
||||
return resolveTemplates(jsonDictionary: jsonDictionary,
|
||||
templateStructure: TemplateStructure(baseKey: "schemes",
|
||||
templatesKey: "schemeTemplates",
|
||||
nameToReplace: "scheme_name"))
|
||||
}
|
||||
}
|
||||
|
||||
private func resolveTemplates(jsonDictionary: JSONDictionary, templateStructure: TemplateStructure) -> JSONDictionary {
|
||||
guard var baseDictionary: [String: JSONDictionary] = jsonDictionary[templateStructure.baseKey] as? [String: JSONDictionary] else {
|
||||
return jsonDictionary
|
||||
}
|
||||
|
||||
let templatesDictionary: [String: JSONDictionary] = jsonDictionary[templateStructure.templatesKey] as? [String: JSONDictionary] ?? [:]
|
||||
|
||||
// Recursively collects all nested template names of a given dictionary.
|
||||
func collectTemplates(of jsonDictionary: JSONDictionary,
|
||||
into allTemplates: inout [String],
|
||||
insertAt insertionIndex: inout Int) {
|
||||
guard let templates = jsonDictionary["templates"] as? [String] else {
|
||||
return
|
||||
}
|
||||
for template in templates where !allTemplates.contains(template) {
|
||||
guard let templateDictionary = templatesDictionary[template] else {
|
||||
continue
|
||||
}
|
||||
allTemplates.insert(template, at: insertionIndex)
|
||||
collectTemplates(of: templateDictionary, into: &allTemplates, insertAt: &insertionIndex)
|
||||
insertionIndex += 1
|
||||
}
|
||||
}
|
||||
|
||||
for (referenceName, var reference) in baseDictionary {
|
||||
var templates: [String] = []
|
||||
var index: Int = 0
|
||||
collectTemplates(of: reference, into: &templates, insertAt: &index)
|
||||
if !templates.isEmpty {
|
||||
var mergedDictionary: JSONDictionary = [:]
|
||||
for template in templates {
|
||||
if let templateDictionary = templatesDictionary[template] {
|
||||
mergedDictionary = templateDictionary.merged(onto: mergedDictionary)
|
||||
}
|
||||
}
|
||||
reference = reference.merged(onto: mergedDictionary)
|
||||
reference = reference.replaceString("$\(templateStructure.nameToReplace)", with: referenceName) // Will be removed in upcoming version
|
||||
reference = reference.replaceString("${\(templateStructure.nameToReplace)}", with: referenceName)
|
||||
if let templateAttributes = reference["templateAttributes"] as? [String: String] {
|
||||
for (templateAttribute, value) in templateAttributes {
|
||||
reference = reference.replaceString("${\(templateAttribute)}", with: value)
|
||||
}
|
||||
}
|
||||
}
|
||||
baseDictionary[referenceName] = reference
|
||||
}
|
||||
|
||||
var jsonDictionary = jsonDictionary
|
||||
jsonDictionary[templateStructure.baseKey] = baseDictionary
|
||||
return jsonDictionary
|
||||
}
|
@ -2,6 +2,6 @@ import Foundation
|
||||
import ProjectSpec
|
||||
import XcodeGenCLI
|
||||
|
||||
let version = Version("2.7.0")
|
||||
let version = Version("2.9.0")
|
||||
let cli = XcodeGenCLI(version: version)
|
||||
cli.execute()
|
||||
|
@ -1,20 +0,0 @@
|
||||
import Foundation
|
||||
import SwiftCLI
|
||||
|
||||
class CommandRouter: Router {
|
||||
|
||||
let defaultCommand: Command
|
||||
|
||||
init(defaultCommand: Command) {
|
||||
self.defaultCommand = defaultCommand
|
||||
}
|
||||
|
||||
func parse(commandGroup: CommandGroup, arguments: ArgumentList) throws -> (CommandPath, OptionRegistry) {
|
||||
if !arguments.hasNext() || arguments.nextIsOption() {
|
||||
arguments.manipulate { existing in
|
||||
[defaultCommand.name] + existing
|
||||
}
|
||||
}
|
||||
return try DefaultRouter().parse(commandGroup: commandGroup, arguments: arguments)
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ import ProjectSpec
|
||||
import SwiftCLI
|
||||
|
||||
public class XcodeGenCLI {
|
||||
|
||||
let cli: CLI
|
||||
|
||||
public init(version: Version) {
|
||||
@ -15,7 +14,7 @@ public class XcodeGenCLI {
|
||||
description: "Generates Xcode projects",
|
||||
commands: [generateCommand]
|
||||
)
|
||||
cli.parser = Parser(router: CommandRouter(defaultCommand: generateCommand))
|
||||
cli.parser.routeBehavior = .searchWithFallback(generateCommand)
|
||||
}
|
||||
|
||||
public func execute(arguments: [String]? = nil) {
|
||||
|
@ -9,7 +9,7 @@ public class CacheFile {
|
||||
|
||||
guard #available(OSX 10.13, *) else { return nil }
|
||||
|
||||
let files = Array(Set(project.allFiles))
|
||||
let files = Set(project.allFiles)
|
||||
.map { ((try? $0.relativePath(from: project.basePath)) ?? $0).string }
|
||||
.sorted { $0.localizedStandardCompare($1) == .orderedAscending }
|
||||
.joined(separator: "\n")
|
||||
|
@ -43,7 +43,7 @@ struct CarthageVersionFile: Decodable {
|
||||
let container = try decoder.container(keyedBy: Platform.self)
|
||||
data = try Platform.allCases.reduce(into: [:]) { data, platform in
|
||||
let references = try container.decodeIfPresent([Reference].self, forKey: platform) ?? []
|
||||
let frameworks = Array(Set(references.map { $0.name })).sorted()
|
||||
let frameworks = Set(references.map { $0.name }).sorted()
|
||||
data[platform] = frameworks
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ public class PBXProjGenerator {
|
||||
var targetAggregateObjects: [String: PBXAggregateTarget] = [:]
|
||||
var targetFileReferences: [String: PBXFileReference] = [:]
|
||||
var sdkFileReferences: [String: PBXFileReference] = [:]
|
||||
var packageReferences: [String: XCRemoteSwiftPackageReference] = [:]
|
||||
|
||||
var carthageFrameworksByPlatform: [String: Set<PBXFileElement>] = [:]
|
||||
var frameworkFiles: [PBXFileElement] = []
|
||||
@ -30,6 +31,7 @@ public class PBXProjGenerator {
|
||||
sourceGenerator = SourceGenerator(project: project, pbxProj: pbxProj)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func addObject<T: PBXObject>(_ object: T, context: String? = nil) -> T {
|
||||
pbxProj.add(object: object)
|
||||
object.context = context
|
||||
@ -46,6 +48,12 @@ public class PBXProjGenerator {
|
||||
try sourceGenerator.getFileGroups(path: group)
|
||||
}
|
||||
|
||||
let localPackages = Set(project.localPackages)
|
||||
for package in localPackages {
|
||||
let path = project.basePath + Path(package).normalize()
|
||||
try sourceGenerator.createLocalPackage(path: path)
|
||||
}
|
||||
|
||||
let buildConfigs: [XCBuildConfiguration] = project.configs.map { config in
|
||||
let buildSettings = project.getProjectBuildSettings(config: config)
|
||||
var baseConfiguration: PBXFileReference?
|
||||
@ -149,6 +157,12 @@ public class PBXProjGenerator {
|
||||
targetAggregateObjects[target.name] = aggregateTarget
|
||||
}
|
||||
|
||||
for (name, package) in project.packages {
|
||||
let packageReference = XCRemoteSwiftPackageReference(repositoryURL: package.url, versionRequirement: package.versionRequirement)
|
||||
packageReferences[name] = packageReference
|
||||
addObject(packageReference)
|
||||
}
|
||||
|
||||
try project.targets.forEach(generateTarget)
|
||||
try project.aggregateTargets.forEach(generateAggregateTarget)
|
||||
|
||||
@ -208,8 +222,9 @@ public class PBXProjGenerator {
|
||||
|
||||
let knownRegions = sourceGenerator.knownRegions.sorted()
|
||||
pbxProject.knownRegions = knownRegions.isEmpty ? ["en"] : knownRegions
|
||||
pbxProject.packages = packageReferences.sorted { $0.key < $1.key }.map { $1 }
|
||||
|
||||
let allTargets: [PBXTarget] = Array(targetObjects.values) + Array(targetAggregateObjects.values)
|
||||
let allTargets: [PBXTarget] = targetObjects.valueArray + targetAggregateObjects.valueArray
|
||||
pbxProject.targets = allTargets
|
||||
.sorted { $0.name < $1.name }
|
||||
pbxProject.attributes = projectAttributes
|
||||
@ -415,6 +430,7 @@ public class PBXProjGenerator {
|
||||
var copyFrameworksReferences: [PBXBuildFile] = []
|
||||
var copyResourcesReferences: [PBXBuildFile] = []
|
||||
var copyWatchReferences: [PBXBuildFile] = []
|
||||
var packageDependencies: [XCSwiftPackageProductDependency] = []
|
||||
var extensions: [PBXBuildFile] = []
|
||||
var carthageFrameworksToEmbed: [String] = []
|
||||
|
||||
@ -457,10 +473,10 @@ public class PBXProjGenerator {
|
||||
guard let dependencyTarget = project.getTarget(dependencyTargetName) else { continue }
|
||||
|
||||
let dependecyLinkage = dependencyTarget.defaultLinkage
|
||||
let link = dependency.link ?? (
|
||||
(dependecyLinkage == .dynamic && target.type != .staticLibrary)
|
||||
|| (dependecyLinkage == .static && target.type.isExecutable)
|
||||
)
|
||||
let link = dependency.link ??
|
||||
(dependecyLinkage == .dynamic && target.type != .staticLibrary) ||
|
||||
(dependecyLinkage == .static && target.type.isExecutable)
|
||||
|
||||
if link {
|
||||
let dependencyFile = targetFileReferences[dependencyTarget.name]!
|
||||
let buildFile = addObject(
|
||||
@ -604,6 +620,29 @@ public class PBXProjGenerator {
|
||||
}
|
||||
}
|
||||
// Embedding handled by iterating over `carthageDependencies` below
|
||||
case .package(let product):
|
||||
guard let packageReference = packageReferences[dependency.reference] else {
|
||||
return
|
||||
}
|
||||
|
||||
let productName = product ?? dependency.reference
|
||||
let packageDependency = addObject(
|
||||
XCSwiftPackageProductDependency(productName: productName, package: packageReference)
|
||||
)
|
||||
packageDependencies.append(packageDependency)
|
||||
|
||||
let link = dependency.link ?? (target.type != .staticLibrary)
|
||||
if link {
|
||||
let buildFile = addObject(
|
||||
PBXBuildFile(product: packageDependency)
|
||||
)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
}
|
||||
|
||||
let targetDependency = addObject(
|
||||
PBXTargetDependency(product: packageDependency)
|
||||
)
|
||||
dependencies.append(targetDependency)
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,9 +918,9 @@ public class PBXProjGenerator {
|
||||
let configFrameworkBuildPaths: [String]
|
||||
if !carthageDependencies.isEmpty {
|
||||
let carthagePlatformBuildPath = "$(PROJECT_DIR)/" + carthageResolver.buildPath(for: target.platform)
|
||||
configFrameworkBuildPaths = [carthagePlatformBuildPath] + Array(frameworkBuildPaths).sorted()
|
||||
configFrameworkBuildPaths = [carthagePlatformBuildPath] + frameworkBuildPaths.sorted()
|
||||
} else {
|
||||
configFrameworkBuildPaths = Array(frameworkBuildPaths).sorted()
|
||||
configFrameworkBuildPaths = frameworkBuildPaths.sorted()
|
||||
}
|
||||
|
||||
// set framework search paths
|
||||
@ -925,6 +964,7 @@ public class PBXProjGenerator {
|
||||
targetObject.dependencies = dependencies
|
||||
targetObject.productName = target.name
|
||||
targetObject.buildRules = buildRules
|
||||
targetObject.packageProductDependencies = packageDependencies
|
||||
targetObject.product = targetFileReference
|
||||
if !target.isLegacy {
|
||||
targetObject.productType = target.type
|
||||
@ -969,7 +1009,7 @@ public class PBXProjGenerator {
|
||||
switch dependency.type {
|
||||
case .sdk:
|
||||
dependencies[dependency.reference] = dependency
|
||||
case .framework, .carthage:
|
||||
case .framework, .carthage, .package:
|
||||
if isTopLevel || dependency.embed == nil {
|
||||
dependencies[dependency.reference] = dependency
|
||||
}
|
||||
|
@ -2,6 +2,14 @@ import Foundation
|
||||
import ProjectSpec
|
||||
import XcodeProj
|
||||
|
||||
private func suitableConfig(for type: ConfigType, in project: Project) -> Config {
|
||||
if let defaultConfig = Config.defaultConfigs.first(where: { $0.type == type }),
|
||||
project.configs.contains(defaultConfig) {
|
||||
return defaultConfig
|
||||
}
|
||||
return project.configs.first { $0.type == type }!
|
||||
}
|
||||
|
||||
public class SchemeGenerator {
|
||||
|
||||
let project: Project
|
||||
@ -20,6 +28,17 @@ public class SchemeGenerator {
|
||||
self.pbxProj = pbxProj
|
||||
}
|
||||
|
||||
private var projects: [ProjectReference: PBXProj] = [:]
|
||||
|
||||
func getPBXProj(from reference: ProjectReference) throws -> PBXProj {
|
||||
if let cachedProject = projects[reference] {
|
||||
return cachedProject
|
||||
}
|
||||
let pbxproj = try XcodeProj(pathString: reference.path).pbxproj
|
||||
projects[reference] = pbxproj
|
||||
return pbxproj
|
||||
}
|
||||
|
||||
public func generateSchemes() throws -> [XCScheme] {
|
||||
var xcschemes: [XCScheme] = []
|
||||
|
||||
@ -34,8 +53,8 @@ public class SchemeGenerator {
|
||||
if targetScheme.configVariants.isEmpty {
|
||||
let schemeName = target.name
|
||||
|
||||
let debugConfig = project.configs.first { $0.type == .debug }!
|
||||
let releaseConfig = project.configs.first { $0.type == .release }!
|
||||
let debugConfig = suitableConfig(for: .debug, in: project)
|
||||
let releaseConfig = suitableConfig(for: .release, in: project)
|
||||
|
||||
let scheme = Scheme(
|
||||
name: schemeName,
|
||||
@ -80,27 +99,39 @@ public class SchemeGenerator {
|
||||
let projectFilePath: String
|
||||
switch target.location {
|
||||
case .project(let project):
|
||||
guard let externalProject = self.project.getExternalProject(project) else {
|
||||
fatalError("Unable to find external project named \"\(project)\" in project.yml")
|
||||
guard let projectReference = self.project.getProjectReference(project) else {
|
||||
throw SchemeGenerationError.missingProject(project)
|
||||
}
|
||||
pbxProj = try XcodeProj(pathString: externalProject.path).pbxproj
|
||||
projectFilePath = externalProject.path
|
||||
pbxProj = try getPBXProj(from: projectReference)
|
||||
projectFilePath = projectReference.path
|
||||
case .local:
|
||||
pbxProj = self.pbxProj
|
||||
projectFilePath = "\(self.project.name).xcodeproj"
|
||||
}
|
||||
|
||||
guard let pbxTarget = pbxProj.targets(named: target.name).first else {
|
||||
fatalError("Unable to find target named \"\(target.name)\" in \"PBXProj.targets\"")
|
||||
throw SchemeGenerationError.missingTarget(target, projectPath: projectFilePath)
|
||||
}
|
||||
let buildableName: String
|
||||
|
||||
switch target.location {
|
||||
case .project:
|
||||
buildableName = pbxTarget.productNameWithExtension() ?? pbxTarget.name
|
||||
case .local:
|
||||
guard let _buildableName =
|
||||
project.getTarget(target.name)?.filename ??
|
||||
project.getAggregateTarget(target.name)?.name else {
|
||||
fatalError("Unable to determinate \"buildableName\" for build target: \(target)")
|
||||
}
|
||||
buildableName = _buildableName
|
||||
}
|
||||
|
||||
let buildableName = pbxTarget.productNameWithExtension() ?? pbxTarget.name
|
||||
return XCScheme.BuildableReference(
|
||||
referencedContainer: "container:\(projectFilePath)",
|
||||
blueprint: pbxTarget,
|
||||
buildableName: buildableName,
|
||||
blueprintName: target.name
|
||||
)
|
||||
referencedContainer: "container:\(projectFilePath)",
|
||||
blueprint: pbxTarget,
|
||||
buildableName: buildableName,
|
||||
blueprintName: target.name
|
||||
)
|
||||
}
|
||||
|
||||
func getBuildEntry(_ buildTarget: Scheme.BuildTarget) throws -> XCScheme.BuildAction.Entry {
|
||||
@ -229,11 +260,26 @@ public class SchemeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
enum SchemeGenerationError: Error, CustomStringConvertible {
|
||||
|
||||
case missingTarget(TargetReference, projectPath: String)
|
||||
case missingProject(String)
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .missingTarget(let target, let projectPath):
|
||||
return "Unable to find target named \"\(target)\" in \"\(projectPath)\""
|
||||
case .missingProject(let project):
|
||||
return "Unable to find project reference named \"\(project)\" in project.yml"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Scheme {
|
||||
public init(name: String, target: Target, targetScheme: TargetScheme, debugConfig: String, releaseConfig: String) {
|
||||
self.init(
|
||||
name: name,
|
||||
build: .init(targets: [Scheme.BuildTarget(target: TargetReference(name: target.name, location: .local))]),
|
||||
build: .init(targets: [Scheme.BuildTarget(target: TargetReference.local(target.name))]),
|
||||
run: .init(
|
||||
config: debugConfig,
|
||||
commandLineArguments: targetScheme.commandLineArguments,
|
||||
|
@ -16,6 +16,7 @@ class SourceGenerator {
|
||||
private var fileReferencesByPath: [String: PBXFileElement] = [:]
|
||||
private var groupsByPath: [Path: PBXGroup] = [:]
|
||||
private var variantGroupsByPath: [Path: PBXVariantGroup] = [:]
|
||||
private var localPackageGroup: PBXGroup?
|
||||
|
||||
private let project: Project
|
||||
let pbxProj: PBXProj
|
||||
@ -34,12 +35,32 @@ class SourceGenerator {
|
||||
self.pbxProj = pbxProj
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func addObject<T: PBXObject>(_ object: T, context: String? = nil) -> T {
|
||||
pbxProj.add(object: object)
|
||||
object.context = context
|
||||
return object
|
||||
}
|
||||
|
||||
func createLocalPackage(path: Path) throws {
|
||||
|
||||
|
||||
if localPackageGroup == nil {
|
||||
let groupName = project.options.localPackagesGroup ?? "Packages"
|
||||
localPackageGroup = addObject(PBXGroup(sourceTree: .sourceRoot, name: groupName))
|
||||
rootGroups.insert(localPackageGroup!)
|
||||
}
|
||||
let fileReference = addObject(
|
||||
PBXFileReference(
|
||||
sourceTree: .sourceRoot,
|
||||
name: path.lastComponent,
|
||||
lastKnownFileType: "folder",
|
||||
path: try path.relativePath(from: project.basePath).string
|
||||
)
|
||||
)
|
||||
localPackageGroup!.children.append(fileReference)
|
||||
}
|
||||
|
||||
func getAllSourceFiles(targetType: PBXProductType, sources: [TargetSource]) throws -> [SourceFile] {
|
||||
return try sources.flatMap { try getSourceFiles(targetType: targetType, targetSource: $0, path: project.basePath + $0.path) }
|
||||
}
|
||||
@ -200,7 +221,8 @@ class SourceGenerator {
|
||||
"xcdatamodeld",
|
||||
"intentdefinition",
|
||||
"metal",
|
||||
"mlmodel":
|
||||
"mlmodel",
|
||||
"rcproject":
|
||||
return .sources
|
||||
case "h",
|
||||
"hh",
|
||||
@ -246,7 +268,7 @@ class SourceGenerator {
|
||||
for child in children {
|
||||
// only add the children that aren't already in the cachedGroup
|
||||
// Check equality by path and sourceTree because XcodeProj.PBXObject.== is very slow.
|
||||
if !cachedGroupChildren.contains(where: { $0.path == child.path && $0.sourceTree == child.sourceTree }) {
|
||||
if !cachedGroupChildren.contains(where: { $0.name == child.name && $0.path == child.path && $0.sourceTree == child.sourceTree }) {
|
||||
cachedGroupChildren.append(child)
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,17 @@ extension Dictionary {
|
||||
extension Xcode {
|
||||
|
||||
public static func fileType(path: Path) -> String? {
|
||||
return path.extension.flatMap { Xcode.filetype(extension: $0) }
|
||||
guard let fileExtension = path.extension else { return nil}
|
||||
switch fileExtension {
|
||||
// cases that aren't handled (yet) in XcodeProj.
|
||||
// they can be removed once XcodeProj supports them
|
||||
case "stringsdict": return "text.plist.stringsdict"
|
||||
case "tbd": return "sourcecode.text-based-dylib-definition"
|
||||
case "xpc": return "wrapper.xpc-service"
|
||||
case "xcfilelist": return "text.xcfilelist"
|
||||
default:
|
||||
// fallback to XcodeProj defaults
|
||||
return Xcode.filetype(extension: fileExtension)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +429,10 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
||||
);
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_NAME = Framework;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@ -474,7 +477,10 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/tvOS",
|
||||
);
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_NAME = Framework;
|
||||
SDKROOT = appletvos;
|
||||
SKIP_INSTALL = YES;
|
||||
@ -519,7 +525,10 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
||||
);
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_NAME = Framework;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@ -601,7 +610,10 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
);
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
PRODUCT_NAME = Framework;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
@ -624,7 +636,10 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
);
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
PRODUCT_NAME = Framework;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
@ -646,7 +661,10 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/tvOS",
|
||||
);
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_NAME = Framework;
|
||||
SDKROOT = appletvos;
|
||||
SKIP_INSTALL = YES;
|
||||
|
469
Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj
Normal file
469
Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,469 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 51;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2DA7998902987953B119E4CE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26F7EFEE613987D1E1258A60 /* AppDelegate.swift */; };
|
||||
578E78BC3627CF48FB2CE129 /* App.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = A9601593D0AD02931266A4E5 /* App.xctestplan */; };
|
||||
78E2E1F9F271C0C4CDA04BD9 /* StaticLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F7AFEF8ECCC678519EA643C /* StaticLibrary.a */; };
|
||||
9C4AD0711D706FD3ED0E436D /* StaticLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C17B77601A9D1B7895AB42 /* StaticLibrary.swift */; };
|
||||
CE46CBA5671B951B546C8673 /* Codability in Frameworks */ = {isa = PBXBuildFile; productRef = 16E6FE01D5BD99F78D4A17E2 /* Codability */; };
|
||||
E368431019ABC696E4FFC0CF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E22B8BCC18A29EFE1DE3BE4 /* Assets.xcassets */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
29147E1DDAEB1AAC20CB0CF9 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F7B09D77DB7447B17DCDA3C4 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 3F8D94C4EFC431F646AAFB28;
|
||||
remoteInfo = StaticLibrary;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
097F2DB5622B591E21BC3C73 /* App.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
26F7EFEE613987D1E1258A60 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
3F7AFEF8ECCC678519EA643C /* StaticLibrary.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = StaticLibrary.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
464ACF8D8F2D9F219BCFD3E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
4E22B8BCC18A29EFE1DE3BE4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
61C17B77601A9D1B7895AB42 /* StaticLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLibrary.swift; sourceTree = "<group>"; };
|
||||
A9601593D0AD02931266A4E5 /* App.xctestplan */ = {isa = PBXFileReference; path = App.xctestplan; sourceTree = "<group>"; };
|
||||
C1DE9A872F470EAA65B9B0B0 /* XcodeGen */ = {isa = PBXFileReference; lastKnownFileType = folder; name = XcodeGen; path = ../../..; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
796E7DE873F16699BD82FFEA /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CE46CBA5671B951B546C8673 /* Codability in Frameworks */,
|
||||
78E2E1F9F271C0C4CDA04BD9 /* StaticLibrary.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
17DD374CC81D710476AFF41C /* SPM */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A9601593D0AD02931266A4E5 /* App.xctestplan */,
|
||||
26F7EFEE613987D1E1258A60 /* AppDelegate.swift */,
|
||||
4E22B8BCC18A29EFE1DE3BE4 /* Assets.xcassets */,
|
||||
464ACF8D8F2D9F219BCFD3E7 /* Info.plist */,
|
||||
);
|
||||
path = SPM;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1FA59BFD192FB5A68D5F587C /* StaticLibrary */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
61C17B77601A9D1B7895AB42 /* StaticLibrary.swift */,
|
||||
);
|
||||
path = StaticLibrary;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
218F6C96DF9E182F526258CF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AD0F3623091EEA8D1EA3DFF8 /* Packages */,
|
||||
17DD374CC81D710476AFF41C /* SPM */,
|
||||
1FA59BFD192FB5A68D5F587C /* StaticLibrary */,
|
||||
5D68FDDE55EE935627A1B376 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5D68FDDE55EE935627A1B376 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
097F2DB5622B591E21BC3C73 /* App.app */,
|
||||
3F7AFEF8ECCC678519EA643C /* StaticLibrary.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AD0F3623091EEA8D1EA3DFF8 /* Packages */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C1DE9A872F470EAA65B9B0B0 /* XcodeGen */,
|
||||
);
|
||||
name = Packages;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
3F8D94C4EFC431F646AAFB28 /* StaticLibrary */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 3B861439E878E4B7EE6EE131 /* Build configuration list for PBXNativeTarget "StaticLibrary" */;
|
||||
buildPhases = (
|
||||
B070E114B1D62BD5A07B61DF /* Sources */,
|
||||
723C19B61A1AD980BD7C9DF0 /* Copy Swift Objective-C Interface Header */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
D85FFB99444DD260A72DDDA7 /* PBXTargetDependency */,
|
||||
);
|
||||
name = StaticLibrary;
|
||||
packageProductDependencies = (
|
||||
AF233B61592982A7F6431FC6 /* Codability */,
|
||||
);
|
||||
productName = StaticLibrary;
|
||||
productReference = 3F7AFEF8ECCC678519EA643C /* StaticLibrary.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
C99E3C420D63D5219CE57E33 /* App */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 091BBC493EA2F0A446682C48 /* Build configuration list for PBXNativeTarget "App" */;
|
||||
buildPhases = (
|
||||
460F52476B5219D2CDA494C2 /* Sources */,
|
||||
F77D37B94534F63D9B461F30 /* Resources */,
|
||||
796E7DE873F16699BD82FFEA /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
E157C6348B8AD6A28C706801 /* PBXTargetDependency */,
|
||||
078202CF7B08B66ACF7FEC23 /* PBXTargetDependency */,
|
||||
);
|
||||
name = App;
|
||||
packageProductDependencies = (
|
||||
16E6FE01D5BD99F78D4A17E2 /* Codability */,
|
||||
);
|
||||
productName = App;
|
||||
productReference = 097F2DB5622B591E21BC3C73 /* App.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
F7B09D77DB7447B17DCDA3C4 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1020;
|
||||
};
|
||||
buildConfigurationList = 425866ADA259DB93FC4AF1E3 /* Build configuration list for PBXProject "SPM" */;
|
||||
compatibilityVersion = "Xcode 10.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 218F6C96DF9E182F526258CF;
|
||||
packageReferences = (
|
||||
5BA91390AE78D2EE15C60091 /* XCRemoteSwiftPackageReference "Codability" */,
|
||||
);
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
C99E3C420D63D5219CE57E33 /* App */,
|
||||
3F8D94C4EFC431F646AAFB28 /* StaticLibrary */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
F77D37B94534F63D9B461F30 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
578E78BC3627CF48FB2CE129 /* App.xctestplan in Resources */,
|
||||
E368431019ABC696E4FFC0CF /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
723C19B61A1AD980BD7C9DF0 /* Copy Swift Objective-C Interface Header */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"$(DERIVED_SOURCES_DIR)/$(SWIFT_OBJC_INTERFACE_HEADER_NAME)",
|
||||
);
|
||||
name = "Copy Swift Objective-C Interface Header";
|
||||
outputPaths = (
|
||||
"$(BUILT_PRODUCTS_DIR)/include/$(PRODUCT_MODULE_NAME)/$(SWIFT_OBJC_INTERFACE_HEADER_NAME)",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "ditto \"${SCRIPT_INPUT_FILE_0}\" \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
460F52476B5219D2CDA494C2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2DA7998902987953B119E4CE /* AppDelegate.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B070E114B1D62BD5A07B61DF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9C4AD0711D706FD3ED0E436D /* StaticLibrary.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
078202CF7B08B66ACF7FEC23 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 3F8D94C4EFC431F646AAFB28 /* StaticLibrary */;
|
||||
targetProxy = 29147E1DDAEB1AAC20CB0CF9 /* PBXContainerItemProxy */;
|
||||
};
|
||||
D85FFB99444DD260A72DDDA7 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
productRef = AF233B61592982A7F6431FC6 /* Codability */;
|
||||
};
|
||||
E157C6348B8AD6A28C706801 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
productRef = 16E6FE01D5BD99F78D4A17E2 /* Codability */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0CCC06807E5CD8361D899B7F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1640ABF22E84A6AB9FFFB0D9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
41B31B6C4A1D9194EC6FFF6B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = SPM/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
7A384B9B9CF42FCF9EF02057 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = SPM/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B4F2839AD4756B475B2005F2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"DEBUG=1",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
BC33B43DF18620E6CCC43E96 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_VERSION = 5.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
091BBC493EA2F0A446682C48 /* Build configuration list for PBXNativeTarget "App" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
41B31B6C4A1D9194EC6FFF6B /* Debug */,
|
||||
7A384B9B9CF42FCF9EF02057 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = "";
|
||||
};
|
||||
3B861439E878E4B7EE6EE131 /* Build configuration list for PBXNativeTarget "StaticLibrary" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0CCC06807E5CD8361D899B7F /* Debug */,
|
||||
1640ABF22E84A6AB9FFFB0D9 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = "";
|
||||
};
|
||||
425866ADA259DB93FC4AF1E3 /* Build configuration list for PBXProject "SPM" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B4F2839AD4756B475B2005F2 /* Debug */,
|
||||
BC33B43DF18620E6CCC43E96 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Debug;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
5BA91390AE78D2EE15C60091 /* XCRemoteSwiftPackageReference "Codability" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/yonaskolb/Codability";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 0.2.1;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
16E6FE01D5BD99F78D4A17E2 /* Codability */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 5BA91390AE78D2EE15C60091 /* XCRemoteSwiftPackageReference "Codability" */;
|
||||
productName = Codability;
|
||||
};
|
||||
AF233B61592982A7F6431FC6 /* Codability */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 5BA91390AE78D2EE15C60091 /* XCRemoteSwiftPackageReference "Codability" */;
|
||||
productName = Codability;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = F7B09D77DB7447B17DCDA3C4 /* Project object */;
|
||||
}
|
7
Tests/Fixtures/SPM/SPM.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
Tests/Fixtures/SPM/SPM.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,97 @@
|
||||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "AEXML",
|
||||
"repositoryURL": "https://github.com/tadija/AEXML",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "e4d517844dd03dac557e35d77a8e9ab438de91a6",
|
||||
"version": "4.4.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Codability",
|
||||
"repositoryURL": "https://github.com/yonaskolb/Codability",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "eb5bac78e0679f521c3f058c1eb9be0dd657dadd",
|
||||
"version": "0.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "JSONUtilities",
|
||||
"repositoryURL": "https://github.com/yonaskolb/JSONUtilities.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "128d2ffc22467f69569ef8ff971683e2393191a0",
|
||||
"version": "4.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "PathKit",
|
||||
"repositoryURL": "https://github.com/kylef/PathKit.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "73f8e9dca9b7a3078cb79128217dc8f2e585a511",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Rainbow",
|
||||
"repositoryURL": "https://github.com/onevcat/Rainbow.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "9c52c1952e9b2305d4507cf473392ac2d7c9b155",
|
||||
"version": "3.1.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Shell",
|
||||
"repositoryURL": "https://github.com/tuist/Shell",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "d38121f89401db902b0d0bfc30b987e2c84c254e",
|
||||
"version": "2.0.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Spectre",
|
||||
"repositoryURL": "https://github.com/kylef/Spectre.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "f14ff47f45642aa5703900980b014c2e9394b6e5",
|
||||
"version": "0.9.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "SwiftCLI",
|
||||
"repositoryURL": "https://github.com/jakeheis/SwiftCLI.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "5318c37d3cacc8780f50b87a8840a6774320ebdf",
|
||||
"version": "5.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "XcodeProj",
|
||||
"repositoryURL": "https://github.com/tuist/xcodeproj.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "aefcbf59cea5b0831837ed2f385e6dfd80d82cc9",
|
||||
"version": "7.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Yams",
|
||||
"repositoryURL": "https://github.com/jpsim/Yams.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "c947a306d2e80ecb2c0859047b35c73b8e1ca27f",
|
||||
"version": "2.0.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C99E3C420D63D5219CE57E33"
|
||||
BuildableName = "App.app"
|
||||
BlueprintName = "App"
|
||||
ReferencedContainer = "container:SPM.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C99E3C420D63D5219CE57E33"
|
||||
BuildableName = "App.app"
|
||||
BlueprintName = "App"
|
||||
ReferencedContainer = "container:SPM.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<CommandLineArguments>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
<CodeCoverageTargets>
|
||||
</CodeCoverageTargets>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C99E3C420D63D5219CE57E33"
|
||||
BuildableName = "App.app"
|
||||
BlueprintName = "App"
|
||||
ReferencedContainer = "container:SPM.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C99E3C420D63D5219CE57E33"
|
||||
BuildableName = "App.app"
|
||||
BlueprintName = "App"
|
||||
ReferencedContainer = "container:SPM.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
</CommandLineArguments>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
23
Tests/Fixtures/SPM/SPM/App.xctestplan
Normal file
23
Tests/Fixtures/SPM/SPM/App.xctestplan
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"configurations" : [
|
||||
{
|
||||
"id" : "521B6958-2D62-4961-B353-91EF8F252F4B",
|
||||
"name" : "Configuration 1",
|
||||
"options" : {
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
"defaultOptions" : {
|
||||
"codeCoverage" : false,
|
||||
"targetForVariableExpansion" : {
|
||||
"containerPath" : "container:SPM.xcodeproj",
|
||||
"identifier" : "C99E3C420D63D5219CE57E33",
|
||||
"name" : "App"
|
||||
}
|
||||
},
|
||||
"testTargets" : [
|
||||
|
||||
],
|
||||
"version" : 1
|
||||
}
|
22
Tests/Fixtures/SPM/SPM/AppDelegate.swift
Normal file
22
Tests/Fixtures/SPM/SPM/AppDelegate.swift
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// SPM
|
||||
//
|
||||
// Created by Yonas Kolb on 13/8/19.
|
||||
// Copyright © 2019 BeemIt. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Codability
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
64
Tests/Fixtures/SPM/SPM/Info.plist
Normal file
64
Tests/Fixtures/SPM/SPM/Info.plist
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
<key>UISceneStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
5
Tests/Fixtures/SPM/StaticLibrary/StaticLibrary.swift
Normal file
5
Tests/Fixtures/SPM/StaticLibrary/StaticLibrary.swift
Normal file
@ -0,0 +1,5 @@
|
||||
import Codability
|
||||
|
||||
func doThing() {
|
||||
_ = AnyCodable.self
|
||||
}
|
22
Tests/Fixtures/SPM/project.yml
Normal file
22
Tests/Fixtures/SPM/project.yml
Normal file
@ -0,0 +1,22 @@
|
||||
name: SPM
|
||||
packages:
|
||||
Codability:
|
||||
url: https://github.com/yonaskolb/Codability
|
||||
majorVersion: 0.2.1
|
||||
localPackages:
|
||||
- ../../.. #XcodeGen itself
|
||||
targets:
|
||||
App:
|
||||
type: application
|
||||
platform: iOS
|
||||
sources: [SPM]
|
||||
scheme: {}
|
||||
dependencies:
|
||||
- package: Codability
|
||||
- target: StaticLibrary
|
||||
StaticLibrary:
|
||||
type: library.static
|
||||
platform: iOS
|
||||
sources: StaticLibrary
|
||||
dependencies:
|
||||
- package: Codability
|
12
Tests/Fixtures/TestProject/Carthage/Build/.Result.version
generated
vendored
12
Tests/Fixtures/TestProject/Carthage/Build/.Result.version
generated
vendored
@ -2,26 +2,30 @@
|
||||
"Mac" : [
|
||||
{
|
||||
"name" : "Result",
|
||||
"hash" : "f14569d60b4947d7467d06912c9969bac4caa5c2b62e19dec21bfd37ae146a9f"
|
||||
"hash" : "62e4384d0cce7e469b9f0dc7f736c274e671cce26504e299f77918ed0a5233f6",
|
||||
"swiftToolchainVersion" : "5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)"
|
||||
}
|
||||
],
|
||||
"watchOS" : [
|
||||
{
|
||||
"name" : "Result",
|
||||
"hash" : "80ed6de84fe4e9a468a10ca021db53f5a91edfa70874fdab0b5c1e61487604ea"
|
||||
"hash" : "ffdf4671a69099751c25a1d75458a167d80fa6a4a3da54411baa2ae3d27da37d",
|
||||
"swiftToolchainVersion" : "5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)"
|
||||
}
|
||||
],
|
||||
"tvOS" : [
|
||||
{
|
||||
"name" : "Result",
|
||||
"hash" : "28ba58a2f0caf9db17d544ea3f01908b3f100bca5777a10c8238386be054b9ce"
|
||||
"hash" : "c14d1468b641dd44eaa03cd1802dbdd5e428a9529456915e49f0d49208eee73a",
|
||||
"swiftToolchainVersion" : "5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)"
|
||||
}
|
||||
],
|
||||
"commitish" : "4.1.0",
|
||||
"iOS" : [
|
||||
{
|
||||
"name" : "Result",
|
||||
"hash" : "328ec56ff90373242dc848bda9f214eeb58c456ea5e4703855b3f7f207861a24"
|
||||
"hash" : "78dba477b2c36e23b8578d032c469e95970db392f8ededd1ec1c7dec712f2cdf",
|
||||
"swiftToolchainVersion" : "5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)"
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AE3F93DB94E7208F2F1D9A78"
|
||||
BuildableName = "Framework_iOS.framework"
|
||||
BuildableName = "Framework.framework"
|
||||
BlueprintName = "Framework_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
@ -33,7 +33,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AE3F93DB94E7208F2F1D9A78"
|
||||
BuildableName = "Framework_iOS.framework"
|
||||
BuildableName = "Framework.framework"
|
||||
BlueprintName = "Framework_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
@ -54,7 +54,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AE3F93DB94E7208F2F1D9A78"
|
||||
BuildableName = "Framework_iOS.framework"
|
||||
BuildableName = "Framework.framework"
|
||||
BlueprintName = "Framework_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
@ -80,7 +80,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AE3F93DB94E7208F2F1D9A78"
|
||||
BuildableName = "Framework_iOS.framework"
|
||||
BuildableName = "Framework.framework"
|
||||
BlueprintName = "Framework_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
@ -109,7 +109,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AE3F93DB94E7208F2F1D9A78"
|
||||
BuildableName = "Framework_iOS.framework"
|
||||
BuildableName = "Framework.framework"
|
||||
BlueprintName = "Framework_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
@ -0,0 +1,98 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
@ -128,7 +128,7 @@ targets:
|
||||
App_watchOS:
|
||||
type: application.watchapp2
|
||||
platform: watchOS
|
||||
deploymentTarget: 3.0
|
||||
deploymentTarget: 4.0
|
||||
sources:
|
||||
App_watchOS
|
||||
settings:
|
||||
@ -151,7 +151,7 @@ targets:
|
||||
iMessageApp:
|
||||
type: application.messages
|
||||
platform: iOS
|
||||
sources: iMessage
|
||||
sources: iMessageApp
|
||||
scheme: {}
|
||||
dependencies:
|
||||
- target: iMessageExtension
|
||||
@ -159,7 +159,7 @@ targets:
|
||||
iMessageExtension:
|
||||
type: app-extension.messages
|
||||
platform: iOS
|
||||
sources: iMessage MessagesExtension
|
||||
sources: iMessageExtension
|
||||
settings:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.project.iMessageApp.extension
|
||||
|
||||
@ -167,7 +167,7 @@ targets:
|
||||
type: app-extension.messages-sticker-pack
|
||||
platform: iOS
|
||||
sources:
|
||||
- path: iMessage Stickers
|
||||
- path: iMessageStickers
|
||||
|
||||
StaticLibrary_ObjC:
|
||||
type: library.static
|
||||
|
@ -140,7 +140,10 @@
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@ -158,7 +161,10 @@
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
|
@ -8,18 +8,22 @@ import Yams
|
||||
|
||||
extension Project {
|
||||
|
||||
func generateXcodeProject(file: String = #file, line: Int = #line) throws -> XcodeProj {
|
||||
func generateXcodeProject(validate: Bool = true, file: String = #file, line: Int = #line) throws -> XcodeProj {
|
||||
return try doThrowing(file: file, line: line) {
|
||||
try validate()
|
||||
if validate {
|
||||
try self.validate()
|
||||
}
|
||||
let generator = ProjectGenerator(project: self)
|
||||
return try generator.generateXcodeProject()
|
||||
}
|
||||
}
|
||||
|
||||
func generatePbxProj(file: String = #file, line: Int = #line) throws -> PBXProj {
|
||||
func generatePbxProj(specValidate: Bool = true, projectValidate: Bool = true, file: String = #file, line: Int = #line) throws -> PBXProj {
|
||||
return try doThrowing(file: file, line: line) {
|
||||
let xcodeProject = try generateXcodeProject().pbxproj
|
||||
try xcodeProject.validate()
|
||||
let xcodeProject = try generateXcodeProject(validate: specValidate).pbxproj
|
||||
if projectValidate {
|
||||
try xcodeProject.validate()
|
||||
}
|
||||
return xcodeProject
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,10 @@ class ProjectFixtureTests: XCTestCase {
|
||||
|
||||
func testProjectFixture() {
|
||||
describe {
|
||||
$0.it("generates") {
|
||||
$0.it("generates fixtures") {
|
||||
try generateXcodeProject(specPath: fixturePath + "TestProject/project.yml")
|
||||
try generateXcodeProject(specPath: fixturePath + "CarthageProject/project.yml")
|
||||
try generateXcodeProject(specPath: fixturePath + "SPM/project.yml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -907,6 +907,53 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
try expect(buildFileSettings.compactMap { $0?["ATTRIBUTES"] as? [String] }.first) == ["Weak"]
|
||||
}
|
||||
|
||||
$0.it("generates swift packages") {
|
||||
let app = Target(
|
||||
name: "MyApp",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .package(product: "ProjectSpec"), reference: "XcodeGen"),
|
||||
Dependency(type: .package(product: nil), reference: "Codability"),
|
||||
]
|
||||
)
|
||||
|
||||
let project = Project(name: "test", targets: [app], packages: [
|
||||
"XcodeGen": SwiftPackage(url: "http://github.com/yonaskolb/XcodeGen", versionRequirement: .branch("master")),
|
||||
"Codability": SwiftPackage(url: "http://github.com/yonaskolb/Codability", versionRequirement: .exact("1.0.0")),
|
||||
], localPackages: ["../XcodeGen"], options: .init(localPackagesGroup: "MyPackages"))
|
||||
|
||||
let pbxProject = try project.generatePbxProj(specValidate: false)
|
||||
guard let nativeTarget = pbxProject.nativeTargets.first(where: { $0.name == app.name }) else {
|
||||
throw failure("PBXNativeTarget for \(app.name) not found")
|
||||
}
|
||||
|
||||
guard let projectSpecDependency = nativeTarget.packageProductDependencies.first(where: { $0.productName == "ProjectSpec" }) else {
|
||||
throw failure("XCSwiftPackageProductDependency for \(app.name) not found")
|
||||
}
|
||||
|
||||
try expect(projectSpecDependency.package?.name) == "XcodeGen"
|
||||
try expect(projectSpecDependency.package?.versionRequirement) == .branch("master")
|
||||
|
||||
guard let codabilityDependency = nativeTarget.packageProductDependencies.first(where: { $0.productName == "Codability" }) else {
|
||||
throw failure("XCSwiftPackageProductDependency for \(app.name) not found")
|
||||
}
|
||||
|
||||
try expect(codabilityDependency.package?.name) == "Codability"
|
||||
try expect(codabilityDependency.package?.versionRequirement) == .exact("1.0.0")
|
||||
|
||||
guard let localPackagesGroup = try pbxProject.getMainGroup().children.first(where: { $0.name == "MyPackages" }) as? PBXGroup else {
|
||||
throw failure("Group not found")
|
||||
}
|
||||
|
||||
guard let localPackageFile = pbxProject.fileReferences.first(where: { $0.path == "../XcodeGen" }) else {
|
||||
throw failure("FileReference not found")
|
||||
}
|
||||
|
||||
try expect(localPackagesGroup.children.contains(localPackageFile)) == true
|
||||
try expect(localPackageFile.lastKnownFileType) == "folder"
|
||||
}
|
||||
|
||||
$0.it("generates info.plist") {
|
||||
let plist = Plist(path: "Info.plist", attributes: ["UISupportedInterfaceOrientations": ["UIInterfaceOrientationPortrait", "UIInterfaceOrientationLandscapeLeft"]])
|
||||
let tempPath = Path.temporary + "info"
|
||||
|
@ -96,6 +96,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
project.settings = invalidSettings
|
||||
project.configFiles = ["invalidConfig": "invalidConfigFile"]
|
||||
project.fileGroups = ["invalidFileGroup"]
|
||||
project.localPackages = ["invalidLocalPackage"]
|
||||
project.settingGroups = ["settingGroup1": Settings(
|
||||
configSettings: ["invalidSettingGroupConfig": [:]],
|
||||
groups: ["invalidSettingGroupSettingGroup"]
|
||||
@ -106,6 +107,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
try expectValidationError(project, .invalidConfigFile(configFile: "invalidConfigFile", config: "invalidConfig"))
|
||||
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroup"))
|
||||
try expectValidationError(project, .invalidFileGroup("invalidFileGroup"))
|
||||
try expectValidationError(project, .invalidLocalPackage("invalidLocalPackage"))
|
||||
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroupSettingGroup"))
|
||||
try expectValidationError(project, .invalidBuildSettingConfig("invalidSettingGroupConfig"))
|
||||
}
|
||||
@ -134,7 +136,10 @@ class ProjectSpecTests: XCTestCase {
|
||||
settings: invalidSettings,
|
||||
configFiles: ["invalidConfig": "invalidConfigFile"],
|
||||
sources: ["invalidSource"],
|
||||
dependencies: [Dependency(type: .target, reference: "invalidDependency")],
|
||||
dependencies: [
|
||||
Dependency(type: .target, reference: "invalidDependency"),
|
||||
Dependency(type: .package(product: nil), reference: "invalidPackage")
|
||||
],
|
||||
preBuildScripts: [BuildScript(script: .path("invalidPreBuildScript"), name: "preBuildScript1")],
|
||||
postCompileScripts: [BuildScript(script: .path("invalidPostCompileScript"))],
|
||||
postBuildScripts: [BuildScript(script: .path("invalidPostBuildScript"))],
|
||||
@ -142,6 +147,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
)]
|
||||
|
||||
try expectValidationError(project, .invalidTargetDependency(target: "target1", dependency: "invalidDependency"))
|
||||
try expectValidationError(project, .invalidSwiftPackage(name: "invalidPackage", target: "target1"))
|
||||
try expectValidationError(project, .invalidTargetConfigFile(target: "target1", configFile: "invalidConfigFile", config: "invalidConfig"))
|
||||
try expectValidationError(project, .invalidTargetSchemeTest(target: "target1", testTarget: "invalidTarget"))
|
||||
try expectValidationError(project, .invalidTargetSource(target: "target1", source: "invalidSource"))
|
||||
@ -201,7 +207,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
var project = baseProject
|
||||
project.schemes = [Scheme(
|
||||
name: "scheme1",
|
||||
build: .init(targets: [.init(target: .init(name: "invalidTarget", location: .local))]),
|
||||
build: .init(targets: [.init(target: "invalidTarget")]),
|
||||
run: .init(config: "debugInvalid"),
|
||||
archive: .init(config: "releaseInvalid")
|
||||
)]
|
||||
@ -211,6 +217,15 @@ class ProjectSpecTests: XCTestCase {
|
||||
try expectValidationError(project, .invalidSchemeConfig(scheme: "scheme1", config: "releaseInvalid"))
|
||||
}
|
||||
|
||||
$0.it("fails with invalid project reference") {
|
||||
var project = baseProject
|
||||
project.schemes = [Scheme(
|
||||
name: "scheme1",
|
||||
build: .init(targets: [.init(target: "invalidProjectRef/target1")])
|
||||
)]
|
||||
try expectValidationError(project, .invalidProjectReference(scheme: "scheme1", reference: "invalidProjectRef"))
|
||||
}
|
||||
|
||||
$0.it("allows missing optional file") {
|
||||
var project = baseProject
|
||||
project.targets = [Target(
|
||||
@ -249,7 +264,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
attributes: [:]
|
||||
)
|
||||
project.aggregateTargets = [aggregatedTarget]
|
||||
let buildTarget = Scheme.BuildTarget(target: .init(name: "target1"))
|
||||
let buildTarget = Scheme.BuildTarget(target: "target1")
|
||||
let scheme = Scheme(name: "target1-Scheme", build: Scheme.Build(targets: [buildTarget]))
|
||||
project.schemes = [scheme]
|
||||
try project.validate()
|
||||
@ -332,7 +347,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
name: nil,
|
||||
outputFiles: ["bar"],
|
||||
outputFilesCompilerFlags: ["foo"])],
|
||||
scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(targetReference: .init(name: "test target"),
|
||||
scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(targetReference: "test target",
|
||||
randomExecutionOrder: false,
|
||||
parallelizable: false)],
|
||||
configVariants: ["foo"],
|
||||
@ -370,7 +385,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
shell: "/bin/bash",
|
||||
runOnlyWhenInstalling: true,
|
||||
showEnvVars: false)],
|
||||
scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(targetReference: .init(name: "test target"),
|
||||
scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(targetReference: "test target",
|
||||
randomExecutionOrder: false,
|
||||
parallelizable: false)],
|
||||
configVariants: ["foo"],
|
||||
@ -398,7 +413,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
groups: ["config-setting-group"])],
|
||||
groups: ["setting-group"])],
|
||||
schemes: [Scheme(name: "scheme",
|
||||
build: Scheme.Build(targets: [Scheme.BuildTarget(target: .init(name: "foo"),
|
||||
build: Scheme.Build(targets: [Scheme.BuildTarget(target: "foo",
|
||||
buildTypes: [.archiving, .analyzing])],
|
||||
parallelizeBuild: false,
|
||||
buildImplicitDependencies: false,
|
||||
@ -425,7 +440,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
randomExecutionOrder: false,
|
||||
parallelizable: false,
|
||||
commandLineArguments: ["foo": true],
|
||||
targets: [Scheme.Test.TestTarget(targetReference: .init(name: "foo"),
|
||||
targets: [Scheme.Test.TestTarget(targetReference: "foo",
|
||||
randomExecutionOrder: false,
|
||||
parallelizable: false)],
|
||||
preActions: [Scheme.ExecutionAction(name: "preAction",
|
||||
@ -458,6 +473,12 @@ class ProjectSpecTests: XCTestCase {
|
||||
postActions: [Scheme.ExecutionAction(name: "postAction",
|
||||
script: "bar",
|
||||
settingsTarget: "foo")]))],
|
||||
packages: [
|
||||
"Yams": SwiftPackage(
|
||||
url: "https://github.com/jpsim/Yams",
|
||||
versionRequirement: .upToNextMajorVersion("2.0.0"))
|
||||
],
|
||||
localPackages: ["../../Package"],
|
||||
options: SpecOptions(minimumXcodeGenVersion: Version(major: 3, minor: 4, patch: 5),
|
||||
carthageBuildPath: "carthageBuildPath",
|
||||
carthageExecutablePath: "carthageExecutablePath",
|
||||
@ -496,6 +517,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
try expect(proj.options) == restoredProj.options
|
||||
try expect(proj.settingGroups) == restoredProj.settingGroups
|
||||
try expect(proj.targets) == restoredProj.targets
|
||||
try expect(proj.packages) == restoredProj.packages
|
||||
|
||||
try expect(proj) == restoredProj
|
||||
}
|
||||
|
@ -19,6 +19,12 @@ private let framework = Target(
|
||||
platform: .iOS
|
||||
)
|
||||
|
||||
private let frameworkTest = Target(
|
||||
name: "MyFrameworkTests",
|
||||
type: .unitTestBundle,
|
||||
platform: .iOS
|
||||
)
|
||||
|
||||
private let optionalFramework = Target(
|
||||
name: "MyOptionalFramework",
|
||||
type: .framework,
|
||||
@ -37,7 +43,7 @@ class SchemeGeneratorTests: XCTestCase {
|
||||
func testSchemes() {
|
||||
describe {
|
||||
|
||||
let buildTarget = Scheme.BuildTarget(target: .init(name: app.name, location: .local))
|
||||
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 scheme = Scheme(
|
||||
@ -92,6 +98,36 @@ class SchemeGeneratorTests: XCTestCase {
|
||||
try expect(xcscheme.testAction?.selectedDebuggerIdentifier) == XCScheme.defaultDebugger
|
||||
}
|
||||
|
||||
$0.it("generates scheme with multiple configs") {
|
||||
let configs: [Config] = [
|
||||
Config(name: "Beta", type: .debug),
|
||||
Config(name: "Debug", type: .debug),
|
||||
Config(name: "Production", type: .release),
|
||||
Config(name: "Release", type: .release),
|
||||
]
|
||||
let framework = Target(
|
||||
name: "MyFramework",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
scheme: TargetScheme(testTargets: ["MyFrameworkTests"])
|
||||
)
|
||||
let project = Project(
|
||||
name: "test",
|
||||
configs: configs,
|
||||
targets: [framework, frameworkTest]
|
||||
)
|
||||
let xcodeProject = try project.generateXcodeProject()
|
||||
guard let xcscheme = xcodeProject.sharedData?.schemes.first else {
|
||||
throw failure("Scheme not found")
|
||||
}
|
||||
|
||||
try expect(xcscheme.launchAction?.buildConfiguration) == "Debug"
|
||||
try expect(xcscheme.testAction?.buildConfiguration) == "Debug"
|
||||
try expect(xcscheme.profileAction?.buildConfiguration) == "Release"
|
||||
try expect(xcscheme.analyzeAction?.buildConfiguration) == "Debug"
|
||||
try expect(xcscheme.archiveAction?.buildConfiguration) == "Release"
|
||||
}
|
||||
|
||||
$0.it("sets environment variables for a scheme") {
|
||||
let runVariables: [XCScheme.EnvironmentVariable] = [
|
||||
XCScheme.EnvironmentVariable(variable: "RUN_ENV", value: "ENABLED", enabled: true),
|
||||
@ -234,7 +270,7 @@ class SchemeGeneratorTests: XCTestCase {
|
||||
try! writer.writePlists()
|
||||
}
|
||||
let externalProjectPath = fixturePath + "scheme_test/TestProject.xcodeproj"
|
||||
let externalProject = ExternalProject(name: "ExternalProject", path: externalProjectPath.string)
|
||||
let projectReference = ProjectReference(name: "ExternalProject", path: externalProjectPath.string)
|
||||
let target = Scheme.BuildTarget(target: .init(name: "ExternalTarget", location: .project("ExternalProject")))
|
||||
let scheme = Scheme(
|
||||
name: "ExternalProjectScheme",
|
||||
@ -244,7 +280,7 @@ class SchemeGeneratorTests: XCTestCase {
|
||||
name: "test",
|
||||
targets: [],
|
||||
schemes: [scheme],
|
||||
externalProjects: [externalProject]
|
||||
projectReferences: [projectReference]
|
||||
)
|
||||
let xcodeProject = try project.generateXcodeProject()
|
||||
guard let xcscheme = xcodeProject.sharedData?.schemes.first else {
|
||||
|
@ -167,6 +167,69 @@ class SourceGeneratorTests: XCTestCase {
|
||||
try expect(variableGroup.children.filter { $0 == refs.first }.count) == 1
|
||||
}
|
||||
}
|
||||
|
||||
$0.it("handles localized resources") {
|
||||
let directories = """
|
||||
App:
|
||||
Resources:
|
||||
en-CA.lproj:
|
||||
- empty.json
|
||||
- Localizable.strings
|
||||
en-US.lproj:
|
||||
- empty.json
|
||||
- Localizable.strings
|
||||
en.lproj:
|
||||
- empty.json
|
||||
- Localizable.strings
|
||||
fonts:
|
||||
SFUI:
|
||||
- SFUILight.ttf
|
||||
"""
|
||||
try createDirectories(directories)
|
||||
|
||||
let target = Target(name: "Test", type: .application, platform: .iOS, sources: [TargetSource(path: "App/Resources")])
|
||||
|
||||
let options = SpecOptions(createIntermediateGroups: true)
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target], options: options)
|
||||
|
||||
let outputXcodeProj = try project.generateXcodeProject()
|
||||
try outputXcodeProj.write(path: directoryPath)
|
||||
|
||||
let inputXcodeProj = try XcodeProj(path: directoryPath)
|
||||
let pbxProj = inputXcodeProj.pbxproj
|
||||
|
||||
func getFileReferences(_ path: String) -> [PBXFileReference] {
|
||||
return pbxProj.fileReferences.filter { $0.path == path }
|
||||
}
|
||||
|
||||
func getVariableGroups(_ name: String?) -> [PBXVariantGroup] {
|
||||
return pbxProj.variantGroups.filter { $0.name == name }
|
||||
}
|
||||
|
||||
let stringsResourceName = "Localizable.strings"
|
||||
let jsonResourceName = "empty.json"
|
||||
|
||||
guard let stringsVariableGroup = getVariableGroups(stringsResourceName).first else { throw failure("Couldn't find the variable group") }
|
||||
|
||||
guard let jsonVariableGroup = getVariableGroups(jsonResourceName).first else { throw failure("Couldn't find the variable group") }
|
||||
|
||||
let stringsResource = "en.lproj/Localizable.strings"
|
||||
let jsonResource = "en-CA.lproj/empty.json"
|
||||
|
||||
do {
|
||||
let refs = getFileReferences(stringsResource)
|
||||
try expect(refs.count) == 1
|
||||
try expect(refs.first!.uuid.hasPrefix("TEMP")) == false
|
||||
try expect(stringsVariableGroup.children.filter { $0 == refs.first }.count) == 1
|
||||
}
|
||||
|
||||
do {
|
||||
let refs = getFileReferences(jsonResource)
|
||||
try expect(refs.count) == 1
|
||||
try expect(refs.first!.uuid.hasPrefix("TEMP")) == false
|
||||
try expect(jsonVariableGroup.children.filter { $0 == refs.first }.count) == 1
|
||||
}
|
||||
}
|
||||
|
||||
$0.it("handles duplicate names") {
|
||||
let directories = """
|
||||
|
@ -775,13 +775,13 @@ class SpecLoadingTests: XCTestCase {
|
||||
]
|
||||
let scheme = try Scheme(name: "Scheme", jsonDictionary: schemeDictionary)
|
||||
let expectedTargets: [Scheme.BuildTarget] = [
|
||||
Scheme.BuildTarget(target: .init(name: "Target1"), buildTypes: BuildType.all),
|
||||
Scheme.BuildTarget(target: .init(name: "Target2"), buildTypes: [.testing, .analyzing]),
|
||||
Scheme.BuildTarget(target: .init(name: "Target3"), buildTypes: []),
|
||||
Scheme.BuildTarget(target: .init(name: "Target4"), buildTypes: [.testing]),
|
||||
Scheme.BuildTarget(target: .init(name: "Target5"), buildTypes: []),
|
||||
Scheme.BuildTarget(target: .init(name: "Target6"), buildTypes: [.testing, .analyzing]),
|
||||
Scheme.BuildTarget(target: .init(name: "Target7", location: .project("ExternalProject")), buildTypes: [.running]),
|
||||
Scheme.BuildTarget(target: "Target1", buildTypes: BuildType.all),
|
||||
Scheme.BuildTarget(target: "Target2", buildTypes: [.testing, .analyzing]),
|
||||
Scheme.BuildTarget(target: "Target3", buildTypes: []),
|
||||
Scheme.BuildTarget(target: "Target4", buildTypes: [.testing]),
|
||||
Scheme.BuildTarget(target: "Target5", buildTypes: []),
|
||||
Scheme.BuildTarget(target: "Target6", buildTypes: [.testing, .analyzing]),
|
||||
Scheme.BuildTarget(target: "ExternalProject/Target7", buildTypes: [.running]),
|
||||
]
|
||||
try expect(scheme.name) == "Scheme"
|
||||
try expect(scheme.build.targets) == expectedTargets
|
||||
@ -799,7 +799,7 @@ class SpecLoadingTests: XCTestCase {
|
||||
targets: [
|
||||
"Target1",
|
||||
Scheme.Test.TestTarget(
|
||||
targetReference: .init(name: "Target2", location: .project("ExternalProject")),
|
||||
targetReference: "ExternalProject/Target2",
|
||||
randomExecutionOrder: true,
|
||||
parallelizable: true,
|
||||
skippedTests: ["Test/testExample()"]
|
||||
@ -855,6 +855,121 @@ class SpecLoadingTests: XCTestCase {
|
||||
try expect(scheme.profile?.environmentVariables.isEmpty) == true
|
||||
}
|
||||
|
||||
$0.it("parses scheme templates") {
|
||||
let targetDictionary: [String: Any] = [
|
||||
"deploymentTarget": "1.2.0",
|
||||
"sources": ["targetSource"],
|
||||
"templates": ["temp2", "temp"],
|
||||
"templateAttributes": [
|
||||
"source": "replacedSource",
|
||||
],
|
||||
]
|
||||
|
||||
let project = try getProjectSpec([
|
||||
"targets": ["Framework": targetDictionary],
|
||||
"targetTemplates": [
|
||||
"temp": [
|
||||
"platform": "iOS",
|
||||
"sources": [
|
||||
"templateSource",
|
||||
["path": "Sources/${target_name}"]
|
||||
],
|
||||
],
|
||||
"temp2": [
|
||||
"type": "framework",
|
||||
"platform": "tvOS",
|
||||
"deploymentTarget": "1.1.0",
|
||||
"configFiles": [
|
||||
"debug": "Configs/$target_name/debug.xcconfig",
|
||||
"release": "Configs/${target_name}/release.xcconfig",
|
||||
],
|
||||
"sources": ["${source}"],
|
||||
],
|
||||
],
|
||||
"schemeTemplates": [
|
||||
"base_scheme": [
|
||||
"build": [
|
||||
"parallelizeBuild": false,
|
||||
"buildImplicitDependencies": false,
|
||||
"targets": [
|
||||
"Target${name_1}": "all",
|
||||
"Target2": "testing",
|
||||
"Target${name_3}": "none",
|
||||
"Target4": ["testing": true],
|
||||
"Target5": ["testing": false],
|
||||
"Target6": ["test", "analyze"],
|
||||
],
|
||||
"preActions": [
|
||||
[
|
||||
"script": "${pre-action-name}",
|
||||
"name": "Before Build ${scheme_name}",
|
||||
"settingsTarget": "Target${name_1}",
|
||||
],
|
||||
],
|
||||
],
|
||||
"test": [
|
||||
"config": "debug",
|
||||
"targets": [
|
||||
"Target${name_1}",
|
||||
[
|
||||
"name": "Target2",
|
||||
"parallelizable": true,
|
||||
"randomExecutionOrder": true,
|
||||
"skippedTests": ["Test/testExample()"],
|
||||
],
|
||||
],
|
||||
"gatherCoverageData": true,
|
||||
"disableMainThreadChecker": true,
|
||||
],
|
||||
],
|
||||
],
|
||||
"schemes": [
|
||||
"temp2": [
|
||||
"templates": ["base_scheme"],
|
||||
"templateAttributes": [
|
||||
"pre-action-name": "modified-name",
|
||||
"name_1": "FirstTarget",
|
||||
"name_3": "ThirdTarget",
|
||||
],
|
||||
],
|
||||
],
|
||||
])
|
||||
|
||||
let scheme = project.schemes.first!
|
||||
let expectedTargets: [Scheme.BuildTarget] = [
|
||||
Scheme.BuildTarget(target: "TargetFirstTarget", buildTypes: BuildType.all),
|
||||
Scheme.BuildTarget(target: "Target2", buildTypes: [.testing, .analyzing]),
|
||||
Scheme.BuildTarget(target: "TargetThirdTarget", buildTypes: []),
|
||||
Scheme.BuildTarget(target: "Target4", buildTypes: [.testing]),
|
||||
Scheme.BuildTarget(target: "Target5", buildTypes: []),
|
||||
Scheme.BuildTarget(target: "Target6", buildTypes: [.testing, .analyzing]),
|
||||
]
|
||||
try expect(scheme.name) == "temp2"
|
||||
try expect(Set(scheme.build.targets)) == Set(expectedTargets)
|
||||
try expect(scheme.build.preActions.first?.script) == "modified-name"
|
||||
try expect(scheme.build.preActions.first?.name) == "Before Build temp2"
|
||||
try expect(scheme.build.preActions.first?.settingsTarget) == "TargetFirstTarget"
|
||||
|
||||
try expect(scheme.build.parallelizeBuild) == false
|
||||
try expect(scheme.build.buildImplicitDependencies) == false
|
||||
|
||||
let expectedTest = Scheme.Test(
|
||||
config: "debug",
|
||||
gatherCoverageData: true,
|
||||
disableMainThreadChecker: true,
|
||||
targets: [
|
||||
"TargetFirstTarget",
|
||||
Scheme.Test.TestTarget(
|
||||
targetReference: "Target2",
|
||||
randomExecutionOrder: true,
|
||||
parallelizable: true,
|
||||
skippedTests: ["Test/testExample()"]
|
||||
),
|
||||
]
|
||||
)
|
||||
try expect(scheme.test) == expectedTest
|
||||
}
|
||||
|
||||
$0.it("parses settings") {
|
||||
let project = try Project(path: fixturePath + "settings_test.yml")
|
||||
let buildSettings: BuildSettings = ["SETTING": "value"]
|
||||
@ -962,6 +1077,39 @@ class SpecLoadingTests: XCTestCase {
|
||||
let parsedSpec = try getProjectSpec(dictionary)
|
||||
try expect(parsedSpec) == expected
|
||||
}
|
||||
|
||||
$0.it("parses packages") {
|
||||
let project = Project(name: "spm", packages: [
|
||||
"package1": SwiftPackage(url: "package.git", versionRequirement: .exact("1.2.2")),
|
||||
"package2": SwiftPackage(url: "package.git", versionRequirement: .upToNextMajorVersion("1.2.2")),
|
||||
"package3": SwiftPackage(url: "package.git", versionRequirement: .upToNextMinorVersion("1.2.2")),
|
||||
"package4": SwiftPackage(url: "package.git", versionRequirement: .branch("master")),
|
||||
"package5": SwiftPackage(url: "package.git", versionRequirement: .revision("x")),
|
||||
"package6": SwiftPackage(url: "package.git", versionRequirement: .range(from: "1.2.0", to: "1.2.5")),
|
||||
"package7": SwiftPackage(url: "package.git", versionRequirement: .exact("1.2.2")),
|
||||
],
|
||||
localPackages: ["../../Package"],
|
||||
options: .init(localPackagesGroup: "MyPackages"))
|
||||
|
||||
let dictionary: [String: Any] = [
|
||||
"name": "spm",
|
||||
"options": [
|
||||
"localPackagesGroup": "MyPackages"
|
||||
],
|
||||
"packages": [
|
||||
"package1": ["url": "package.git", "exactVersion": "1.2.2"],
|
||||
"package2": ["url": "package.git", "majorVersion": "1.2.2"],
|
||||
"package3": ["url": "package.git", "minorVersion": "1.2.2"],
|
||||
"package4": ["url": "package.git", "branch": "master"],
|
||||
"package5": ["url": "package.git", "revision": "x"],
|
||||
"package6": ["url": "package.git", "minVersion": "1.2.0", "maxVersion": "1.2.5"],
|
||||
"package7": ["url": "package.git", "version": "1.2.2"],
|
||||
],
|
||||
"localPackages": ["../../Package"]
|
||||
]
|
||||
let parsedSpec = try getProjectSpec(dictionary)
|
||||
try expect(parsedSpec) == project
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,3 +3,4 @@ set -e
|
||||
|
||||
swift run xcodegen --spec Tests/Fixtures/TestProject/project.yml
|
||||
swift run xcodegen --spec Tests/Fixtures/CarthageProject/project.yml
|
||||
swift run xcodegen --spec Tests/Fixtures/SPM/project.yml
|
||||
|
Loading…
Reference in New Issue
Block a user