Merge remote-tracking branch 'upstream/master' into ts-no-overwriting-xcconfig-value

This commit is contained in:
toshi0383
2017-11-03 22:00:44 +09:00
63 changed files with 3037 additions and 1825 deletions
+33 -32
View File
@@ -4,12 +4,12 @@
## 1.3.0
### Added
#### Added
- generate output files for Carthage copy-frameworks script [#84](https://github.com/yonaskolb/XcodeGen/pull/84) @mironal
- added options.settingPreset to choose which setting presets get applied [#100](https://github.com/yonaskolb/XcodeGen/pull/101) @yonaskolb
- added `link` option for target dependencies [#109](https://github.com/yonaskolb/XcodeGen/pull/109) @keith
### Changed
#### Changed
- updated to xcproj 0.4.1 [#85](https://github.com/yonaskolb/XcodeGen/pull/85) @enmiller
- don't copy base settings if config type has been left out [#100](https://github.com/yonaskolb/XcodeGen/pull/100) @yonaskolb
- generate localised files under a single variant group [#70](https://github.com/yonaskolb/XcodeGen/pull/70) @ryohey
@@ -17,7 +17,7 @@
- config references in settings can now be partially matched and are case insensitive [#111](https://github.com/yonaskolb/XcodeGen/pull/111) @yonaskolb
- other small internal changes @yonaskolb
### Fixed
#### Fixed
- embed Carthage frameworks for macOS [#82](https://github.com/yonaskolb/XcodeGen/pull/82) @toshi0383
- fixed copying of watchOS app resources [#96](https://github.com/yonaskolb/XcodeGen/pull/96) @keith
- automatically ignore more file types for a target's sources (entitlements, gpx, apns) [#94](https://github.com/yonaskolb/XcodeGen/pull/94) @keith
@@ -31,19 +31,19 @@
## 1.2.4
### Fixed
#### Fixed
- setting presets only apply `ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: YES` to applications
- don't add carthage dependency to `copy-frameworks` script if `embed: false`
- sort group children on APFS
### Changed
#### Changed
- update to xcproj 0.3.0
[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.2.3...1.2.4)
## 1.2.3
### Fixed
#### Fixed
- Fixed wrong carthage directory name reference for macOS [#74](https://github.com/yonaskolb/XcodeGen/pull/74) @toshi0383
- Removed unnecessary `carthage copy-frameworks` for macOS app target [#76](https://github.com/yonaskolb/XcodeGen/pull/76) @toshi0383
- Added some missing default settings for framework targets. `SKIP_INSTALL: YES` fixes archiving
@@ -53,10 +53,10 @@
## 1.2.2
### Added
#### Added
- automatically set `TEST_TARGET_NAME` on UI test targets if one of the dependencies is an application target
### Fixed
#### Fixed
- set `DYLIB_INSTALL_NAME_BASE` to `@rpath` in framework target presets
- fixed tvOS launch screen setting. `ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME` is now `LaunchImage` not `tvOS LaunchImage`
@@ -65,7 +65,7 @@
## 1.2.0
### Added
#### Added
- `include` now supports a single string as well as a list
- add support setting xcconfig files on a project with `configFiles` [PR#64](https://github.com/yonaskolb/XcodeGen/pull/64)
- add `fileGroups` to project spec for adding groups of files that aren't target source files [PR#64](https://github.com/yonaskolb/XcodeGen/pull/64)
@@ -74,7 +74,7 @@
- add `:REPLACE` syntax when merging `include` [PR#68](https://github.com/yonaskolb/XcodeGen/pull/68)
- add `mint` installation support
### Fixed
#### Fixed
- fixed homebrew installation
- fixed target xcconfig files not working via `configFiles` [PR#64](https://github.com/yonaskolb/XcodeGen/pull/64)
- look for `INFOPLIST_FILE` setting in project and xcconfig files before adding it automatically. It was just looking in target settings before [PR#64](https://github.com/yonaskolb/XcodeGen/pull/64)
@@ -84,13 +84,13 @@
## 1.1.0
### Changed
#### Changed
- set project version to Xcode 9 - `LastUpgradeVersion` attribute to `0900`
- set default Swift version to 4.0 - `SWIFT_VERSION` build setting to `4.0`
[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.0.1...1.1.0)
## 1.0.1
### 1.0.1
### Fixed
- fixed incorrect default build script shell path
@@ -100,15 +100,15 @@
## 1.0.0
### Added
#### Added
- Swift 4 support [PR#52](https://github.com/yonaskolb/XcodeGen/pull/52)
- Support for C and C++ files [PR#48](https://github.com/yonaskolb/XcodeGen/pull/48) by @antoniocasero
- Xcode 9 default settings
### Fixed
#### Fixed
- fixed empty string in YAML not being parsed properly [PR#50](https://github.com/yonaskolb/XcodeGen/pull/50) by @antoniocasero
### Changed
#### Changed
- updated to xcodeproj 0.1.2 [PR#56](https://github.com/yonaskolb/XcodeGen/pull/56)
- **BREAKING**: changed target definitions from list to map [PR#54](https://github.com/yonaskolb/XcodeGen/pull/54) See [Project Spec](docs/ProjectSpec.md)
@@ -117,10 +117,10 @@
## 0.6.1
### Added
#### Added
- Ability to set PBXProject attributes [PR#45](https://github.com/yonaskolb/XcodeGen/pull/45)
### Changed
#### Changed
- Don't bother linking target frameworks for target dependencies.
- Move code signing default settings from all iOS targets to iOS application targets, via Product + Platform setting preset files [PR#46](https://github.com/yonaskolb/XcodeGen/pull/46)
@@ -128,10 +128,10 @@
## 0.6.0
### Added
#### Added
- Allow a project spec to include other project specs [PR#44](https://github.com/yonaskolb/XcodeGen/pull/44)
### Changed
#### Changed
- Changed default spec path to `project.yml`
- Changed default project directory to the current directory instead of the spec file's directory
@@ -139,7 +139,7 @@
## 0.5.1
### Fixed
#### Fixed
- Fix embedded framework dependencies
- Add `CODE_SIGN_IDENTITY[sdk=iphoneos*]` back to iOS targets
- Fix build scripts with "" generating invalid projects [PR#43](https://github.com/yonaskolb/XcodeGen/pull/43)
@@ -147,60 +147,61 @@
[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.5.0...0.5.1)
## 0.5.0
### Added
#### Added
- Added multi platform targets [PR#35](https://github.com/yonaskolb/XcodeGen/pull/35)
- Automatically generate platform specific `FRAMEWORK_SEARCH_PATHS` for Carthage dependencies [PR#38](https://github.com/yonaskolb/XcodeGen/pull/38)
- Automatically find Info.plist and set `INFOPLIST_FILE` build setting if it doesn't exist on a target [PR#40](https://github.com/yonaskolb/XcodeGen/pull/40)
- Add options for controlling embedding of dependencies [PR#37](https://github.com/yonaskolb/XcodeGen/pull/37)
### Fixed
#### Fixed
- Fixed localized files not being added to a target's resources
### Changed
#### Changed
- Renamed Setting Presets to Setting Groups
- Carthage group is now created under top level Frameworks group
[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.4.0...0.5.0)
## 0.4.0
### Added
##### Added
- Homebrew support [PR#16](https://github.com/yonaskolb/XcodeGen/pull/16) by @pepibumur
- Added `runOnlyWhenInstalling` to build scripts [PR#32](https://github.com/yonaskolb/XcodeGen/pull/32)
- Added `carthageBuildPath` option [PR#34](https://github.com/yonaskolb/XcodeGen/pull/34)
### Fixed
#### Fixed
- Fixed installations of XcodeGen not applying build setting presets for configs, products, and platforms, due to missing resources
### Changed
#### Changed
- Upgraded to https://github.com/swift-xcode/xcodeproj 0.1.1 [PR#33](https://github.com/yonaskolb/XcodeGen/pull/33)
[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.3.0...0.4.0)
## 0.3.0 - Extensions and Scheme Tests
### Added
#### Added
- Support for app extension dependencies, using the same `target: MyExtension` syntax [PR#19](https://github.com/yonaskolb/XcodeGen/pull/19)
- Added test targets to generated target schemes via `Target.scheme.testTargets` [PR#21](https://github.com/yonaskolb/XcodeGen/pull/21)
### Changed
#### Changed
- Updated xcodeproj to 0.0.9
### Fixed
#### Fixed
- Fixed watch and messages apps not copying carthage dependencies
### Breaking changes
#### Breaking changes
- Changed `Target.generatedSchemes` to `Target.scheme.configVariants`
[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.2...0.3.0)
## 0.2.0 - Build scripts
### Added
#### Added
- Added Target build scripts with `Target.prebuildScripts` and `Target.postbuildScripts` [PR#17](https://github.com/yonaskolb/XcodeGen/pull/17)
- Support for absolute paths in target sources, run script files, and config files
- Add validation for incorrect `Target.configFiles`
### Fixed
#### Fixed
- Fixed some project objects sometimes having duplicate ids
[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.1...0.2)
+1
View File
@@ -0,0 +1 @@
Carthage
@@ -7,7 +7,7 @@
//
import UIKit
import MyFramework
import Framework
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -17,7 +17,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let frameworkStruct = FrameworkStruct()
_ = FrameworkStruct()
// Standalone files added to project by path-to-file.
_ = standaloneHello()
return true
}
@@ -0,0 +1,7 @@
/*
Localizable.strings
Project
Created by ryohey on 2017/11/03.
*/
@@ -0,0 +1,30 @@
<?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>StringKey</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@VARIABLE@</string>
<key>Variable</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string></string>
<key>zero</key>
<string></string>
<key>one</key>
<string></string>
<key>two</key>
<string></string>
<key>few</key>
<string></string>
<key>many</key>
<string></string>
<key>other</key>
<string></string>
</dict>
</dict>
</dict>
</plist>
@@ -0,0 +1,7 @@
/*
Localizable.strings
Project
Created by ryohey on 2017/11/03.
*/
@@ -0,0 +1,30 @@
<?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>StringKey</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@VARIABLE@</string>
<key>Variable</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string></string>
<key>zero</key>
<string></string>
<key>one</key>
<string></string>
<key>two</key>
<string></string>
<key>few</key>
<string></string>
<key>many</key>
<string></string>
<key>other</key>
<string></string>
</dict>
</dict>
</dict>
</plist>
+1
View File
@@ -0,0 +1 @@
github "Alamofire/Alamofire"
+1
View File
@@ -0,0 +1 @@
github "Alamofire/Alamofire" "4.5.1"
@@ -0,0 +1,9 @@
//
// MyFramework.h
// MyFramework
//
// Created by Yonas Kolb on 21/7/17.
// Copyright © 2017 Yonas Kolb. All rights reserved.
//
@@ -1,725 +0,0 @@
// !$*UTF8*$!
{
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
BF1073850101 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR1332263601 /* AppDelegate.swift */; };
BF1462768401 = {isa = PBXBuildFile; fileRef = FR2653659501 /* TestProjectTests.xctest */; };
BF1744565901 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR6218091901 /* ViewController.swift */; };
BF2250910101 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG2043127501 /* Main.storyboard */; };
BF2445564001 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG2858723001 /* LaunchScreen.storyboard */; };
BF2513089601 /* LocalizedStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG3182922801 /* LocalizedStoryboard.storyboard */; };
BF2753556301 = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; };
BF3154421201 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FR5980633301 /* Assets.xcassets */; };
BF3515549501 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = FR7740960501 /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; };
BF3862341101 /* MyFramework.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BF5986511201 = {isa = PBXBuildFile; fileRef = FR6523263101 /* TestProject.app */; };
BF6182896901 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR9215298301 /* Result.framework */; };
BF7015992001 /* MyFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; };
BF9001417701 /* TestProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR6877173101 /* TestProjectTests.swift */; };
BF9155249601 /* FrameworkFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR7078510801 /* FrameworkFile.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
CIP265365901 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = P81399456601 /* Project object */;
proxyType = 1;
remoteGlobalIDString = NT6523263101;
remoteInfo = TestProject;
};
CIP652326301 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = P81399456601 /* Project object */;
proxyType = 1;
remoteGlobalIDString = NT2993497801;
remoteInfo = MyFramework;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
CFBP50493301 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
dstPath = "";
dstSubfolderSpec = 10;
files = (
BF3862341101 /* MyFramework.framework in CopyFiles */,
);
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
FR1332263601 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
FR1345298501 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
FR1345298502 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
FR1345298503 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
FR1473702401 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
FR2653659501 /* TestProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = xctest; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = TestProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
FR2993497801 /* MyFramework.framework */ = {isa = PBXFileReference; explicitFileType = framework; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = MyFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
FR3546283901 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
FR4822987701 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LocalizedStoryboard.storyboard; sourceTree = "<group>"; };
FR5980633301 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
FR6218091901 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
FR6334256101 /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = "<group>"; };
FR6405436301 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
FR6523263101 /* TestProject.app */ = {isa = PBXFileReference; explicitFileType = app; includeInIndex = 0; lastKnownFileType = wrapper.application; path = TestProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
FR6877173101 /* TestProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProjectTests.swift; sourceTree = "<group>"; };
FR7078510801 /* FrameworkFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameworkFile.swift; sourceTree = "<group>"; };
FR7740960501 /* MyFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyFramework.h; sourceTree = "<group>"; };
FR8182352201 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LocalizedStoryboard.strings; sourceTree = "<group>"; };
FR9215298301 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
FBP652326301 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
BF7015992001 /* MyFramework.framework in Frameworks */,
BF6182896901 /* Result.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
G19527407101 /* Frameworks */ = {
isa = PBXGroup;
children = (
G28836901501 /* Carthage */,
);
name = Frameworks;
sourceTree = "<group>";
};
G26536595301 /* TestProjectTests */ = {
isa = PBXGroup;
children = (
FR1345298503 /* Info.plist */,
FR6877173101 /* TestProjectTests.swift */,
);
name = TestProjectTests;
path = TestProjectTests;
sourceTree = "<group>";
};
G28836901501 /* Carthage */ = {
isa = PBXGroup;
children = (
G47994500501 /* iOS */,
);
name = Carthage;
path = Carthage/Build;
sourceTree = "<group>";
};
G29934978701 /* MyFramework */ = {
isa = PBXGroup;
children = (
FR7078510801 /* FrameworkFile.swift */,
FR1345298501 /* Info.plist */,
FR7740960501 /* MyFramework.h */,
);
name = MyFramework;
path = MyFramework;
sourceTree = "<group>";
};
G47994500501 /* iOS */ = {
isa = PBXGroup;
children = (
FR9215298301 /* Result.framework */,
);
name = iOS;
path = iOS;
sourceTree = "<group>";
};
G65232631501 /* TestProject */ = {
isa = PBXGroup;
children = (
FR1332263601 /* AppDelegate.swift */,
FR5980633301 /* Assets.xcassets */,
FR1345298502 /* Info.plist */,
FR6218091901 /* ViewController.swift */,
VG2858723001 /* LaunchScreen.storyboard */,
VG3182922801 /* LocalizedStoryboard.storyboard */,
VG2043127501 /* Main.storyboard */,
);
name = TestProject;
path = TestProject;
sourceTree = "<group>";
};
G83406189501 /* Configs */ = {
isa = PBXGroup;
children = (
FR3546283901 /* base.xcconfig */,
FR6334256101 /* config.xcconfig */,
);
name = Configs;
path = Configs;
sourceTree = "<group>";
};
G84487712001 = {
isa = PBXGroup;
children = (
G83406189501 /* Configs */,
G29934978701 /* MyFramework */,
G65232631501 /* TestProject */,
G26536595301 /* TestProjectTests */,
G86202385201 /* Products */,
G19527407101 /* Frameworks */,
);
sourceTree = "<group>";
};
G86202385201 /* Products */ = {
isa = PBXGroup;
children = (
FR2993497801 /* MyFramework.framework */,
FR2653659501 /* TestProjectTests.xctest */,
FR6523263101 /* TestProject.app */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
HBP265365901 /* Frameworks */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
};
HBP299349701 /* Frameworks */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
BF3515549501 /* MyFramework.h in Headers */,
);
};
HBP652326301 /* Frameworks */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
NT2653659501 /* TestProjectTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = XCCL26536501 /* Build configuration list for PBXNativeTarget "TestProjectTests" */;
buildPhases = (
SBP265365901 /* Sources */,
RBP265365901 /* Resources */,
HBP265365901 /* Headers */,
);
buildRules = (
);
dependencies = (
TD8877980201 /* PBXTargetDependency */,
);
name = TestProjectTests;
productReference = FR2653659501;
productType = "com.apple.product-type.bundle.unit-test";
};
NT2993497801 /* MyFramework */ = {
isa = PBXNativeTarget;
buildConfigurationList = XCCL29934901 /* Build configuration list for PBXNativeTarget "MyFramework" */;
buildPhases = (
SBP299349701 /* Sources */,
RBP299349701 /* Resources */,
HBP299349701 /* Headers */,
SSBP35382101 /* Swiftlint */,
);
buildRules = (
);
dependencies = (
);
name = MyFramework;
productReference = FR2993497801;
productType = "com.apple.product-type.framework";
};
NT6523263101 /* TestProject */ = {
isa = PBXNativeTarget;
buildConfigurationList = XCCL65232601 /* Build configuration list for PBXNativeTarget "TestProject" */;
buildPhases = (
SBP652326301 /* Sources */,
RBP652326301 /* Resources */,
HBP652326301 /* Headers */,
FBP652326301 /* Frameworks */,
CFBP50493301 /* CopyFiles */,
SSBP58567701 /* Carthage */,
SSBP24648001 /* Strip Unused Architectures from Frameworks */,
SSBP19207501 /* Swiftlint */,
);
buildRules = (
);
dependencies = (
TD6170761801 /* PBXTargetDependency */,
);
name = TestProject;
productReference = FR6523263101;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
P81399456601 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
};
buildConfigurationList = XCCL81399401 /* Build configuration list for PBXProject "GeneratedProject" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
knownRegions = (
en,
Base,
);
mainGroup = G84487712001;
targets = (
NT2993497801 /* MyFramework */,
NT6523263101 /* TestProject */,
NT2653659501 /* TestProjectTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
RBP265365901 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
};
RBP299349701 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
};
RBP652326301 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF3154421201 /* Assets.xcassets in Resources */,
BF2445564001 /* LaunchScreen.storyboard in Resources */,
BF2513089601 /* LocalizedStoryboard.storyboard in Resources */,
BF2250910101 /* Main.storyboard in Resources */,
);
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
SSBP19207501 /* Swiftlint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = Swiftlint;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
SSBP24648001 /* Strip Unused Architectures from Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Strip Unused Architectures from Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
shellScript = "################################################################################\n#\n# Copyright 2015 Realm Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n################################################################################\n\n# This script strips all non-valid architectures from dynamic libraries in\n# the application's `Frameworks` directory.\n#\n# The following environment variables are required:\n#\n# BUILT_PRODUCTS_DIR\n# FRAMEWORKS_FOLDER_PATH\n# VALID_ARCHS\n# EXPANDED_CODE_SIGN_IDENTITY\n\n\n# Signs a framework with the provided identity\ncode_sign() {\n # Use the current code_sign_identitiy\n echo \"Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}\"\n echo \"/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements $1\"\n /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"\n}\n\n# Set working directory to product’s embedded frameworks\ncd \"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\n\nif [ \"$ACTION\" = \"install\" ]; then\n echo \"Copy .bcsymbolmap files to .xcarchive\"\n find . -name '*.bcsymbolmap' -type f -exec mv {} \"${CONFIGURATION_BUILD_DIR}\" \;\nelse\n # Delete *.bcsymbolmap files from framework bundle unless archiving\n find . -name '*.bcsymbolmap' -type f -exec rm -rf \"{}\" +\;\nfi\n\necho \"Stripping frameworks\"\n\nfor file in $(find . -type f -perm +111); do\n # Skip non-dynamic libraries\n if ! [[ \"$(file \"$file\")\" == *\"dynamically linked shared library\"* ]]; then\n continue\n fi\n # Get architectures for current file\n archs=\"$(lipo -info \"${file}\" | rev | cut -d ':' -f1 | rev)\"\n stripped=\"\"\n for arch in $archs; do\n if ! [[ \"${VALID_ARCHS}\" == *\"$arch\"* ]]; then\n # Strip non-valid architectures in-place\n lipo -remove \"$arch\" -output \"$file\" \"$file\" || exit 1\n stripped=\"$stripped $arch\"\n fi\n done\n if [[ \"$stripped\" != \"\" ]]; then\n echo \"Stripped $file of architectures:$stripped\"\n if [ \"${CODE_SIGNING_REQUIRED}\" == \"YES\" ]; then\n code_sign \"${file}\"\n fi\n fi\ndone\n";
};
SSBP35382101 /* Swiftlint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = Swiftlint;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
SSBP58567701 /* Carthage */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/Carthage/Build/iOS/Result.framework",
);
name = Carthage;
outputPaths = (
"$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Result.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/local/bin/carthage copy-frameworks\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
SBP265365901 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF9001417701 /* TestProjectTests.swift in Sources */,
);
};
SBP299349701 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF9155249601 /* FrameworkFile.swift in Sources */,
);
};
SBP652326301 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF1073850101 /* AppDelegate.swift in Sources */,
BF1744565901 /* ViewController.swift in Sources */,
);
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
TD6170761801 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = NT2993497801 /* MyFramework */;
targetProxy = CIP652326301 /* PBXContainerItemProxy */;
};
TD8877980201 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = NT6523263101 /* TestProject */;
targetProxy = CIP265365901 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
VG2043127501 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
FR1473702401 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
VG2858723001 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
FR6405436301 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
VG3182922801 /* LocalizedStoryboard.storyboard */ = {
isa = PBXVariantGroup;
children = (
FR4822987701 /* Base */,
FR8182352201 /* en */,
);
name = LocalizedStoryboard.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
XCBC19846901 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_TESTABILITY = YES;
INFOPLIST_FILE = MyFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.test.MyFramework;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
XCBC37128501 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FR6334256101 /* config.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = TestProject/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestProject;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
XCBC47994501 /* 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_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_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)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
XCBC60448901 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = TestProjectTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks @loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestProjectTests;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestProject.app/TestProject";
};
name = Release;
};
XCBC86437501 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = TestProject/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestProject;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
XCBC88111401 /* 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_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_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)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
XCBC89077001 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = TestProjectTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks @loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestProjectTests;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestProject.app/TestProject";
};
name = Debug;
};
XCBC89204001 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_TESTABILITY = YES;
INFOPLIST_FILE = MyFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.test.MyFramework;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
XCCL26536501 /* Build configuration list for PBXNativeTarget "TestProjectTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
XCBC89077001 /* Debug */,
XCBC60448901 /* Release */,
);
defaultConfigurationName = "";
};
XCCL29934901 /* Build configuration list for PBXNativeTarget "MyFramework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
XCBC19846901 /* Debug */,
XCBC89204001 /* Release */,
);
defaultConfigurationName = "";
};
XCCL65232601 /* Build configuration list for PBXNativeTarget "TestProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
XCBC37128501 /* Debug */,
XCBC86437501 /* Release */,
);
defaultConfigurationName = "";
};
XCCL81399401 /* Build configuration list for PBXProject "GeneratedProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
XCBC47994501 /* Debug */,
XCBC88111401 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = P81399456601 /* Project object */;
}
@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Scheme LastUpgradeVersion="0900" version="1.3">
<AnalyzeAction buildConfiguration="Debug" />
<ArchiveAction buildConfiguration="Release" revealArchiveInOrganizer="YES" />
<TestAction selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv="YES" buildConfiguration="Debug">
<Testables>
<TestableReference skipped="NO">
<BuildableReference BlueprintIdentifier="NT2653659501" ReferencedContainer="container:GeneratedProject.xcodeproj" BuildableName="TestProjectTests.xctest" BlueprintName="TestProject" BuildableIdentifier="primary" />
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference BlueprintIdentifier="NT6523263101" ReferencedContainer="container:GeneratedProject.xcodeproj" BuildableName="TestProject.app" BlueprintName="TestProject" BuildableIdentifier="primary" />
</MacroExpansion>
</TestAction>
<ProfileAction savedToolIdentifier="" useCustomWorkingDirectory="NO" shouldUseLaunchSchemeArgsEnv="YES" buildConfiguration="Release" debugDocumentVersioning="YES">
<BuildableProductRunnable runnableDebuggingMode="0">
<BuildableReference BlueprintIdentifier="NT6523263101" ReferencedContainer="container:GeneratedProject.xcodeproj" BuildableName="TestProject.app" BlueprintName="TestProject" BuildableIdentifier="primary" />
</BuildableProductRunnable>
</ProfileAction>
<BuildAction parallelizeBuildables="YES" buildImplicitDependencies="YES">
<BuildActionEntries>
<BuildActionEntry buildForArchiving="YES" buildForTesting="YES" buildForRunning="YES" buildForProfiling="YES" buildForAnalyzing="YES">
<BuildableReference BlueprintIdentifier="NT6523263101" ReferencedContainer="container:GeneratedProject.xcodeproj" BuildableName="TestProject.app" BlueprintName="TestProject" BuildableIdentifier="primary" />
</BuildActionEntry>
<BuildActionEntry buildForArchiving="NO" buildForTesting="YES" buildForRunning="NO" buildForProfiling="NO" buildForAnalyzing="YES">
<BuildableReference BlueprintIdentifier="NT2653659501" ReferencedContainer="container:GeneratedProject.xcodeproj" BuildableName="TestProjectTests.xctest" BlueprintName="TestProject" BuildableIdentifier="primary" />
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<LaunchAction selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle="0" buildConfiguration="Debug" debugServiceExtension="internal" ignoresPersistentStateOnLaunch="NO" useCustomWorkingDirectory="NO" allowLocationSimulation="YES" debugDocumentVersioning="YES">
<BuildableProductRunnable runnableDebuggingMode="0">
<BuildableReference BlueprintIdentifier="NT6523263101" ReferencedContainer="container:GeneratedProject.xcodeproj" BuildableName="TestProject.app" BlueprintName="TestProject" BuildableIdentifier="primary" />
</BuildableProductRunnable>
</LaunchAction>
</Scheme>
@@ -1,19 +0,0 @@
//
// MyFramework.h
// MyFramework
//
// Created by Yonas Kolb on 21/7/17.
// Copyright © 2017 Yonas Kolb. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for MyFramework.
FOUNDATION_EXPORT double MyFrameworkVersionNumber;
//! Project version string for MyFramework.
FOUNDATION_EXPORT const unsigned char MyFrameworkVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <MyFramework/PublicHeader.h>
@@ -0,0 +1,3 @@
func nested() -> String {
return "Nested"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Scheme LastUpgradeVersion="0900" version="1.3">
<AnalyzeAction buildConfiguration="Production Debug" />
<ArchiveAction buildConfiguration="Production Release" revealArchiveInOrganizer="YES" />
<TestAction selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv="YES" buildConfiguration="Production Debug">
<Testables>
<TestableReference skipped="NO">
<BuildableReference BlueprintIdentifier="NT7831228901" ReferencedContainer="container:Project.xcodeproj" BuildableName="App_iOS_Tests.xctest" BlueprintName="App_iOS" BuildableIdentifier="primary" />
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference BlueprintIdentifier="NT8252321101" ReferencedContainer="container:Project.xcodeproj" BuildableName="App_iOS.app" BlueprintName="App_iOS" BuildableIdentifier="primary" />
</MacroExpansion>
</TestAction>
<ProfileAction savedToolIdentifier="" useCustomWorkingDirectory="NO" shouldUseLaunchSchemeArgsEnv="YES" buildConfiguration="Production Release" debugDocumentVersioning="YES">
<BuildableProductRunnable runnableDebuggingMode="0">
<BuildableReference BlueprintIdentifier="NT8252321101" ReferencedContainer="container:Project.xcodeproj" BuildableName="App_iOS.app" BlueprintName="App_iOS" BuildableIdentifier="primary" />
</BuildableProductRunnable>
</ProfileAction>
<BuildAction parallelizeBuildables="YES" buildImplicitDependencies="YES">
<BuildActionEntries>
<BuildActionEntry buildForArchiving="YES" buildForTesting="YES" buildForRunning="YES" buildForProfiling="YES" buildForAnalyzing="YES">
<BuildableReference BlueprintIdentifier="NT8252321101" ReferencedContainer="container:Project.xcodeproj" BuildableName="App_iOS.app" BlueprintName="App_iOS" BuildableIdentifier="primary" />
</BuildActionEntry>
<BuildActionEntry buildForArchiving="NO" buildForTesting="YES" buildForRunning="NO" buildForProfiling="NO" buildForAnalyzing="YES">
<BuildableReference BlueprintIdentifier="NT7831228901" ReferencedContainer="container:Project.xcodeproj" BuildableName="App_iOS_Tests.xctest" BlueprintName="App_iOS" BuildableIdentifier="primary" />
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<LaunchAction selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle="0" buildConfiguration="Production Debug" debugServiceExtension="internal" ignoresPersistentStateOnLaunch="NO" useCustomWorkingDirectory="NO" allowLocationSimulation="YES" debugDocumentVersioning="YES">
<BuildableProductRunnable runnableDebuggingMode="0">
<BuildableReference BlueprintIdentifier="NT8252321101" ReferencedContainer="container:Project.xcodeproj" BuildableName="App_iOS.app" BlueprintName="App_iOS" BuildableIdentifier="primary" />
</BuildableProductRunnable>
</LaunchAction>
</Scheme>
@@ -0,0 +1,3 @@
func standaloneHello() -> String {
return "Hello"
}
@@ -1,640 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
CC2A0EC21F33D50E00C324B9 /* TestProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2A0EC11F33D50E00C324B9 /* TestProjectTests.swift */; };
CCA4B60E1F1FC00500DF34A1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA4B60D1F1FC00500DF34A1 /* AppDelegate.swift */; };
CCA4B6101F1FC00500DF34A1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA4B60F1F1FC00500DF34A1 /* ViewController.swift */; };
CCA4B6131F1FC00500DF34A1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CCA4B6111F1FC00500DF34A1 /* Main.storyboard */; };
CCA4B6151F1FC00500DF34A1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CCA4B6141F1FC00500DF34A1 /* Assets.xcassets */; };
CCA4B6181F1FC00500DF34A1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CCA4B6161F1FC00500DF34A1 /* LaunchScreen.storyboard */; };
CCA71FEC1F225E4C00F772C1 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA71FEA1F225E4C00F772C1 /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; };
CCA71FEF1F225E4C00F772C1 /* MyFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCA71FE81F225E4C00F772C1 /* MyFramework.framework */; };
CCA71FF11F225E4C00F772C1 /* MyFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = CCA71FE81F225E4C00F772C1 /* MyFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CCA720171F22A3C400F772C1 /* FrameworkFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA720161F22A3C400F772C1 /* FrameworkFile.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
CC2A0EC41F33D50E00C324B9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = CCA4B6021F1FC00500DF34A1 /* Project object */;
proxyType = 1;
remoteGlobalIDString = CCA4B6091F1FC00500DF34A1;
remoteInfo = TestProject;
};
CCA71FED1F225E4C00F772C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = CCA4B6021F1FC00500DF34A1 /* Project object */;
proxyType = 1;
remoteGlobalIDString = CCA71FE71F225E4C00F772C1;
remoteInfo = MyFramework;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
CCA71FF01F225E4C00F772C1 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
CCA71FF11F225E4C00F772C1 /* MyFramework.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
CC2A0EBF1F33D50E00C324B9 /* TestProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
CC2A0EC11F33D50E00C324B9 /* TestProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProjectTests.swift; sourceTree = "<group>"; };
CC2A0EC31F33D50E00C324B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CC9393011F79483C00C1934A /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
CC9393021F79483C00C1934A /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = "<group>"; };
CCA4B60A1F1FC00500DF34A1 /* TestProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
CCA4B60D1F1FC00500DF34A1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
CCA4B60F1F1FC00500DF34A1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
CCA4B6121F1FC00500DF34A1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
CCA4B6141F1FC00500DF34A1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
CCA4B6171F1FC00500DF34A1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
CCA4B6191F1FC00500DF34A1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CCA71FE81F225E4C00F772C1 /* MyFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MyFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CCA71FEA1F225E4C00F772C1 /* MyFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyFramework.h; sourceTree = "<group>"; };
CCA71FEB1F225E4C00F772C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CCA720161F22A3C400F772C1 /* FrameworkFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrameworkFile.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CC2A0EBC1F33D50E00C324B9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
CCA4B6071F1FC00500DF34A1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CCA71FEF1F225E4C00F772C1 /* MyFramework.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CCA71FE41F225E4C00F772C1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
CC2A0EC01F33D50E00C324B9 /* TestProjectTests */ = {
isa = PBXGroup;
children = (
CC2A0EC11F33D50E00C324B9 /* TestProjectTests.swift */,
CC2A0EC31F33D50E00C324B9 /* Info.plist */,
);
path = TestProjectTests;
sourceTree = "<group>";
};
CC9393001F79483C00C1934A /* Configs */ = {
isa = PBXGroup;
children = (
CC9393011F79483C00C1934A /* base.xcconfig */,
CC9393021F79483C00C1934A /* config.xcconfig */,
);
path = Configs;
sourceTree = "<group>";
};
CCA4B6011F1FC00500DF34A1 = {
isa = PBXGroup;
children = (
CC9393001F79483C00C1934A /* Configs */,
CCA4B60C1F1FC00500DF34A1 /* TestProject */,
CCA71FE91F225E4C00F772C1 /* MyFramework */,
CC2A0EC01F33D50E00C324B9 /* TestProjectTests */,
CCA4B60B1F1FC00500DF34A1 /* Products */,
);
sourceTree = "<group>";
};
CCA4B60B1F1FC00500DF34A1 /* Products */ = {
isa = PBXGroup;
children = (
CCA4B60A1F1FC00500DF34A1 /* TestProject.app */,
CCA71FE81F225E4C00F772C1 /* MyFramework.framework */,
CC2A0EBF1F33D50E00C324B9 /* TestProjectTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
CCA4B60C1F1FC00500DF34A1 /* TestProject */ = {
isa = PBXGroup;
children = (
CCA4B60D1F1FC00500DF34A1 /* AppDelegate.swift */,
CCA4B60F1F1FC00500DF34A1 /* ViewController.swift */,
CCA4B6111F1FC00500DF34A1 /* Main.storyboard */,
CCA4B6141F1FC00500DF34A1 /* Assets.xcassets */,
CCA4B6161F1FC00500DF34A1 /* LaunchScreen.storyboard */,
CCA4B6191F1FC00500DF34A1 /* Info.plist */,
);
path = TestProject;
sourceTree = "<group>";
};
CCA71FE91F225E4C00F772C1 /* MyFramework */ = {
isa = PBXGroup;
children = (
CCA720161F22A3C400F772C1 /* FrameworkFile.swift */,
CCA71FEA1F225E4C00F772C1 /* MyFramework.h */,
CCA71FEB1F225E4C00F772C1 /* Info.plist */,
);
path = MyFramework;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
CCA71FE51F225E4C00F772C1 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
CCA71FEC1F225E4C00F772C1 /* MyFramework.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
CC2A0EBE1F33D50E00C324B9 /* TestProjectTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = CC2A0EC81F33D50E00C324B9 /* Build configuration list for PBXNativeTarget "TestProjectTests" */;
buildPhases = (
CC2A0EBB1F33D50E00C324B9 /* Sources */,
CC2A0EBC1F33D50E00C324B9 /* Frameworks */,
CC2A0EBD1F33D50E00C324B9 /* Resources */,
);
buildRules = (
);
dependencies = (
CC2A0EC51F33D50E00C324B9 /* PBXTargetDependency */,
);
name = TestProjectTests;
productName = TestProjectTests;
productReference = CC2A0EBF1F33D50E00C324B9 /* TestProjectTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
CCA4B6091F1FC00500DF34A1 /* TestProject */ = {
isa = PBXNativeTarget;
buildConfigurationList = CCA4B61C1F1FC00500DF34A1 /* Build configuration list for PBXNativeTarget "TestProject" */;
buildPhases = (
CCA4B6061F1FC00500DF34A1 /* Sources */,
CCA4B6071F1FC00500DF34A1 /* Frameworks */,
CCA4B6081F1FC00500DF34A1 /* Resources */,
CCA71FF01F225E4C00F772C1 /* Embed Frameworks */,
CC2DB89A1F30E29600B4B0FA /* Swiftlint */,
);
buildRules = (
);
dependencies = (
CCA71FEE1F225E4C00F772C1 /* PBXTargetDependency */,
);
name = TestProject;
productName = TestProject;
productReference = CCA4B60A1F1FC00500DF34A1 /* TestProject.app */;
productType = "com.apple.product-type.application";
};
CCA71FE71F225E4C00F772C1 /* MyFramework */ = {
isa = PBXNativeTarget;
buildConfigurationList = CCA71FF41F225E4C00F772C1 /* Build configuration list for PBXNativeTarget "MyFramework" */;
buildPhases = (
CCA71FE31F225E4C00F772C1 /* Sources */,
CCA71FE41F225E4C00F772C1 /* Frameworks */,
CCA71FE51F225E4C00F772C1 /* Headers */,
CCA71FE61F225E4C00F772C1 /* Resources */,
CC2DB89B1F30E2AC00B4B0FA /* Swiftlint */,
);
buildRules = (
);
dependencies = (
);
name = MyFramework;
productName = MyFramework;
productReference = CCA71FE81F225E4C00F772C1 /* MyFramework.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CCA4B6021F1FC00500DF34A1 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0830;
LastUpgradeCheck = 0830;
ORGANIZATIONNAME = "Yonas Kolb";
TargetAttributes = {
CC2A0EBE1F33D50E00C324B9 = {
CreatedOnToolsVersion = 8.3.3;
DevelopmentTeam = U7E5MQU624;
ProvisioningStyle = Automatic;
TestTargetID = CCA4B6091F1FC00500DF34A1;
};
CCA4B6091F1FC00500DF34A1 = {
CreatedOnToolsVersion = 8.3.3;
DevelopmentTeam = U7E5MQU624;
ProvisioningStyle = Automatic;
};
CCA71FE71F225E4C00F772C1 = {
CreatedOnToolsVersion = 8.3.3;
DevelopmentTeam = U7E5MQU624;
LastSwiftMigration = 0830;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = CCA4B6051F1FC00500DF34A1 /* Build configuration list for PBXProject "TestProject" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CCA4B6011F1FC00500DF34A1;
productRefGroup = CCA4B60B1F1FC00500DF34A1 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CCA4B6091F1FC00500DF34A1 /* TestProject */,
CCA71FE71F225E4C00F772C1 /* MyFramework */,
CC2A0EBE1F33D50E00C324B9 /* TestProjectTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
CC2A0EBD1F33D50E00C324B9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
CCA4B6081F1FC00500DF34A1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CCA4B6181F1FC00500DF34A1 /* LaunchScreen.storyboard in Resources */,
CCA4B6151F1FC00500DF34A1 /* Assets.xcassets in Resources */,
CCA4B6131F1FC00500DF34A1 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CCA71FE61F225E4C00F772C1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
CC2DB89A1F30E29600B4B0FA /* Swiftlint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = Swiftlint;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
};
CC2DB89B1F30E2AC00B4B0FA /* Swiftlint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = Swiftlint;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CC2A0EBB1F33D50E00C324B9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CC2A0EC21F33D50E00C324B9 /* TestProjectTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CCA4B6061F1FC00500DF34A1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CCA4B6101F1FC00500DF34A1 /* ViewController.swift in Sources */,
CCA4B60E1F1FC00500DF34A1 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CCA71FE31F225E4C00F772C1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CCA720171F22A3C400F772C1 /* FrameworkFile.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
CC2A0EC51F33D50E00C324B9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CCA4B6091F1FC00500DF34A1 /* TestProject */;
targetProxy = CC2A0EC41F33D50E00C324B9 /* PBXContainerItemProxy */;
};
CCA71FEE1F225E4C00F772C1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CCA71FE71F225E4C00F772C1 /* MyFramework */;
targetProxy = CCA71FED1F225E4C00F772C1 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
CCA4B6111F1FC00500DF34A1 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
CCA4B6121F1FC00500DF34A1 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
CCA4B6161F1FC00500DF34A1 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
CCA4B6171F1FC00500DF34A1 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
CC2A0EC61F33D50E00C324B9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
DEVELOPMENT_TEAM = U7E5MQU624;
INFOPLIST_FILE = TestProjectTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yonaskolb.TestProjectTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestProject.app/TestProject";
};
name = Debug;
};
CC2A0EC71F33D50E00C324B9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
DEVELOPMENT_TEAM = U7E5MQU624;
INFOPLIST_FILE = TestProjectTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yonaskolb.TestProjectTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestProject.app/TestProject";
};
name = Release;
};
CCA4B61A1F1FC00500DF34A1 /* 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++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
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;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
CCA4B61B1F1FC00500DF34A1 /* 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++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
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;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
CCA4B61D1F1FC00500DF34A1 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = CC9393021F79483C00C1934A /* config.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = U7E5MQU624;
INFOPLIST_FILE = TestProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yonaskolb.TestProject;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
CCA4B61E1F1FC00500DF34A1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = U7E5MQU624;
INFOPLIST_FILE = TestProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yonaskolb.TestProject;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
CCA71FF21F225E4C00F772C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = U7E5MQU624;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = MyFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yonaskolb.MyFramework;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
CCA71FF31F225E4C00F772C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = U7E5MQU624;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = MyFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yonaskolb.MyFramework;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CC2A0EC81F33D50E00C324B9 /* Build configuration list for PBXNativeTarget "TestProjectTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CC2A0EC61F33D50E00C324B9 /* Debug */,
CC2A0EC71F33D50E00C324B9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CCA4B6051F1FC00500DF34A1 /* Build configuration list for PBXProject "TestProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CCA4B61A1F1FC00500DF34A1 /* Debug */,
CCA4B61B1F1FC00500DF34A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CCA4B61C1F1FC00500DF34A1 /* Build configuration list for PBXNativeTarget "TestProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CCA4B61D1F1FC00500DF34A1 /* Debug */,
CCA4B61E1F1FC00500DF34A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CCA71FF41F225E4C00F772C1 /* Build configuration list for PBXNativeTarget "MyFramework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CCA71FF21F225E4C00F772C1 /* Debug */,
CCA71FF31F225E4C00F772C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CCA4B6021F1FC00500DF34A1 /* Project object */;
}
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:TestProject.xcodeproj">
</FileRef>
</Workspace>
-24
View File
@@ -1,24 +0,0 @@
name: EnvironmentTest
settingGroups:
app:
PRODUCT_BUNDLE_IDENTIFIER: com.app$(BUNDLE_ID_SUFFIX)$(BUNDLE_ID_EXTENSION_SUFFIX)
test:
BUNDLE_ID_SUFFIX: .test
staging:
BUNDLE_ID_SUFFIX: .staging
settings:
configs:
Test Debug:
configs:
Test Debug:
type: debug
Staging Debug:
type: debug
Production Debug:
type: debug
Test Release:
type: release
Staging Release:
type: release
Production Release:
type: release
+13
View File
@@ -0,0 +1,13 @@
settings:
configs:
Test:
BUNDLE_ID_SUFFIX: .test
Staging:
BUNDLE_ID_SUFFIX: .staging
configs:
Test Debug: debug
Staging Debug: debug
Production Debug: debug
Test Release: release
Staging Release: release
Production Release: release
+1
View File
@@ -0,0 +1 @@
echo "You ran a script"
@@ -1,5 +0,0 @@
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
+28 -26
View File
@@ -1,49 +1,51 @@
name: GeneratedProject
name: Project
include: [environments.yml]
options:
bundleIdPrefix: com.test
bundleIdPrefix: com.project
fileGroups:
- Configs
configFiles:
Test Debug: Configs/config.xcconfig
targets:
TestProject:
App_iOS:
type: application
platform: iOS
sources: TestProject
sources:
- path: App_iOS
compilerFlags:
- "-Werror"
- path: StandaloneFiles/Standalone.swift
settings:
INFOPLIST_FILE: TestProject/Info.plist
PRODUCT_BUNDLE_IDENTIFIER: com.project$(BUNDLE_ID_SUFFIX)
INFOPLIST_FILE: App_iOS/Info.plist
dependencies:
- target: MyFramework
- carthage: Result
- target: Framework_iOS
- carthage: Alamofire
scheme:
testTargets:
- TestProjectTests
- App_iOS_Tests
postbuildScripts:
- path: scripts/strip-frameworks.sh
name: Strip Unused Architectures from Frameworks
runOnlyWhenInstalling: true
- name: Swiftlint
- name: MyScript
script: |
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
configFiles:
Debug: Configs/config.xcconfig
MyFramework:
echo "You ran a script!"
Framework:
type: framework
platform: iOS
sources: MyFramework
settings:
INFOPLIST_FILE: MyFramework/Info.plist
platform: [iOS, tvOS, watchOS, macOS]
sources: Framework
postbuildScripts:
- name: Swiftlint
path: scripts/swiftlint.sh
TestProjectTests:
- name: MyScript
path: scripts/script.sh
dependencies:
- carthage: Alamofire
App_iOS_Tests:
type: bundle.unit-test
platform: iOS
sources: TestProjectTests
sources: App_iOS_Tests
settings:
TEST_HOST: $(BUILT_PRODUCTS_DIR)/TestProject.app/TestProject
INFOPLIST_FILE: TestProjectTests/Info.plist
dependencies:
- target: TestProject
- target: App_iOS
+23 -8
View File
@@ -4,17 +4,19 @@ VERSION = 1.3.0
PREFIX = /usr/local
INSTALL_PATH = $(PREFIX)/bin/$(TOOL_NAME)
SHARE_PATH = $(PREFIX)/share/$(TOOL_NAME)
BUILD_PATH = .build/release/$(TOOL_NAME)
CURRENT_PATH = $(PWD)
TAR_FILENAME = $(TOOL_NAME)-$(VERSION).tar.gz
REPO = https://github.com/yonaskolb/$(TOOL_NAME)
RELEASE_TAR = $(REPO)/archive/$(VERSION).tar.gz
SHA = $(shell curl -L -s $(RELEASE_TAR) | shasum -a 256 | sed 's/ .*//')
.PHONY: install build uninstall format_code update_brew release
install: build
mkdir -p $(PREFIX)/bin
cp -f $(BUILD_PATH) $(INSTALL_PATH)
cp -f .build/release/$(TOOL_NAME) $(INSTALL_PATH)
mkdir -p $(SHARE_PATH)
cp -R $(CURRENT_PATH)/SettingPresets $(SHARE_PATH)/SettingPresets
.PHONY: build
build:
swift build --disable-sandbox -c release -Xswiftc -static-stdlib
@@ -22,7 +24,20 @@ uninstall:
rm -f $(INSTALL_PATH)
rm -rf $(SHARE_PATH)
get_sha:
wget https://github.com/yonaskolb/$(TOOL_NAME)/archive/$(VERSION).tar.gz -O $(TAR_FILENAME)
shasum -a 256 $(TAR_FILENAME)
rm $(TAR_FILENAME)
format_code:
swiftformat Tests --stripunusedargs closure-only
swiftformat sources --stripunusedargs closure-only
update_brew:
sed -i '' 's|\(url ".*/archive/\)\(.*\)\(.tar\)|\1$(VERSION)\3|' Formula/xcodegen.rb
sed -i '' 's|\(sha256 "\)\(.*\)\("\)|\1$(SHA)\3|' Formula/xcodegen.rb
git add .
git commit -m "Update brew to $(VERSION)"
release: format_code
sed -i '' 's|\(let version = "\)\(.*\)\("\)|\1$(VERSION)\3|' Sources/XcodeGen/main.swift
git add .
git commit -m "Update to $(VERSION)"
git tag $(VERSION)
+2 -2
View File
@@ -22,7 +22,7 @@ public struct BuildScript: Equatable {
case path(String)
case script(String)
public static func ==(lhs: ScriptType, rhs: ScriptType) -> Bool {
public static func == (lhs: ScriptType, rhs: ScriptType) -> Bool {
switch (lhs, rhs) {
case let (.path(lhs), .path(rhs)): return lhs == rhs
case let (.script(lhs), .script(rhs)): return lhs == rhs
@@ -40,7 +40,7 @@ public struct BuildScript: Equatable {
self.runOnlyWhenInstalling = runOnlyWhenInstalling
}
public static func ==(lhs: BuildScript, rhs: BuildScript) -> Bool {
public static func == (lhs: BuildScript, rhs: BuildScript) -> Bool {
return lhs.script == rhs.script &&
lhs.name == rhs.name &&
lhs.script == rhs.script &&
+3 -1
View File
@@ -19,9 +19,11 @@ public struct Config: Equatable {
self.type = type
}
public static func ==(lhs: Config, rhs: Config) -> Bool {
public static func == (lhs: Config, rhs: Config) -> Bool {
return lhs.name == rhs.name && lhs.type == rhs.type
}
public static var defaultConfigs: [Config] = [Config(name: "Debug", type: .debug), Config(name: "Release", type: .release)]
}
public enum ConfigType: String {
+82
View File
@@ -0,0 +1,82 @@
//
// Dependency.swift
// ProjectSpec
//
// Created by Yonas Kolb on 29/10/17.
//
import Foundation
import xcproj
import JSONUtilities
public struct Dependency: Equatable {
public var type: DependencyType
public var reference: String
public var embed: Bool?
public var codeSign: Bool = true
public var removeHeaders: Bool = true
public var link: Bool = true
public init(type: DependencyType, reference: String, embed: Bool? = nil) {
self.type = type
self.reference = reference
self.embed = embed
}
public enum DependencyType {
case target
case framework
case carthage
}
public static func == (lhs: Dependency, rhs: Dependency) -> Bool {
return lhs.reference == rhs.reference &&
lhs.type == rhs.type &&
lhs.codeSign == rhs.codeSign &&
lhs.removeHeaders == rhs.removeHeaders &&
lhs.embed == rhs.embed &&
lhs.link == rhs.link
}
public var buildSettings: [String: Any] {
var attributes: [String] = []
if codeSign {
attributes.append("CodeSignOnCopy")
}
if removeHeaders {
attributes.append("RemoveHeadersOnCopy")
}
return ["ATTRIBUTES": attributes]
}
}
extension Dependency: JSONObjectConvertible {
public init(jsonDictionary: JSONDictionary) throws {
if let target: String = jsonDictionary.json(atKeyPath: "target") {
type = .target
reference = target
} else if let framework: String = jsonDictionary.json(atKeyPath: "framework") {
type = .framework
reference = framework
} else if let carthage: String = jsonDictionary.json(atKeyPath: "carthage") {
type = .carthage
reference = carthage
} else {
throw SpecParsingError.invalidDependency(jsonDictionary)
}
embed = jsonDictionary.json(atKeyPath: "embed")
if let bool: Bool = jsonDictionary.json(atKeyPath: "link") {
link = bool
}
if let bool: Bool = jsonDictionary.json(atKeyPath: "codeSign") {
codeSign = bool
}
if let bool: Bool = jsonDictionary.json(atKeyPath: "removeHeaders") {
removeHeaders = bool
}
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ public enum Platform: String {
case .macOS:
return "Mac"
default:
return self.rawValue
return rawValue
}
}
}
+10 -7
View File
@@ -29,22 +29,23 @@ public struct ProjectSpec {
public struct Options {
public var carthageBuildPath: String?
public var createIntermediateGroups: Bool
public var bundleIdPrefix: String?
public var settingPresets: SettingPresets = .all
public enum SettingPresets: String {
case all
case none
case project
case targets
public var applyTarget: Bool {
switch self {
case .all, .targets: return true
default: return false
}
}
public var applyProject: Bool {
switch self {
case .all, .project: return true
@@ -54,10 +55,11 @@ public struct ProjectSpec {
}
public init() {
createIntermediateGroups = false
}
}
public init(basePath: Path, name: String, configs: [Config] = [], targets: [Target] = [], settings: Settings = .empty, settingGroups: [String: Settings] = [:], schemes: [Scheme] = [], options: Options = Options(), fileGroups: [String] = [], configFiles: [String: String] = [:], attributes: [String: Any] = [:]) {
public init(basePath: Path, name: String, configs: [Config] = Config.defaultConfigs, targets: [Target] = [], settings: Settings = .empty, settingGroups: [String: Settings] = [:], schemes: [Scheme] = [], options: Options = Options(), fileGroups: [String] = [], configFiles: [String: String] = [:], attributes: [String: Any] = [:]) {
self.basePath = basePath
self.name = name
self.targets = targets
@@ -103,7 +105,7 @@ extension ProjectSpec: CustomDebugStringConvertible {
extension ProjectSpec: Equatable {
public static func ==(lhs: ProjectSpec, rhs: ProjectSpec) -> Bool {
public static func == (lhs: ProjectSpec, rhs: ProjectSpec) -> Bool {
return lhs.name == rhs.name &&
lhs.targets == rhs.targets &&
lhs.settings == rhs.settings &&
@@ -119,7 +121,7 @@ extension ProjectSpec: Equatable {
extension ProjectSpec.Options: Equatable {
public static func ==(lhs: ProjectSpec.Options, rhs: ProjectSpec.Options) -> Bool {
public static func == (lhs: ProjectSpec.Options, rhs: ProjectSpec.Options) -> Bool {
return lhs.carthageBuildPath == rhs.carthageBuildPath &&
lhs.bundleIdPrefix == rhs.bundleIdPrefix &&
lhs.settingPresets == rhs.settingPresets
@@ -135,7 +137,7 @@ extension ProjectSpec {
settings = jsonDictionary.json(atKeyPath: "settings") ?? .empty
settingGroups = jsonDictionary.json(atKeyPath: "settingGroups") ?? jsonDictionary.json(atKeyPath: "settingPresets") ?? [:]
let configs: [String: String] = jsonDictionary.json(atKeyPath: "configs") ?? [:]
self.configs = configs.map { Config(name: $0, type: ConfigType(rawValue: $1)) }.sorted { $0.name < $1.name }
self.configs = configs.isEmpty ? Config.defaultConfigs : 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 }
schemes = try jsonDictionary.json(atKeyPath: "schemes")
fileGroups = jsonDictionary.json(atKeyPath: "fileGroups") ?? []
@@ -160,5 +162,6 @@ extension ProjectSpec.Options: JSONObjectConvertible {
carthageBuildPath = jsonDictionary.json(atKeyPath: "carthageBuildPath")
bundleIdPrefix = jsonDictionary.json(atKeyPath: "bundleIdPrefix")
settingPresets = jsonDictionary.json(atKeyPath: "settingPresets") ?? .all
createIntermediateGroups = jsonDictionary.json(atKeyPath: "createIntermediateGroups") ?? false
}
}
+8 -8
View File
@@ -48,7 +48,7 @@ public struct Scheme: Equatable {
self.targets = targets
}
public static func ==(lhs: Build, rhs: Build) -> Bool {
public static func == (lhs: Build, rhs: Build) -> Bool {
return lhs.targets == rhs.targets
}
}
@@ -59,7 +59,7 @@ public struct Scheme: Equatable {
self.config = config
}
public static func ==(lhs: Run, rhs: Run) -> Bool {
public static func == (lhs: Run, rhs: Run) -> Bool {
return lhs.config == rhs.config
}
}
@@ -70,7 +70,7 @@ public struct Scheme: Equatable {
self.config = config
}
public static func ==(lhs: Test, rhs: Test) -> Bool {
public static func == (lhs: Test, rhs: Test) -> Bool {
return lhs.config == rhs.config
}
}
@@ -81,7 +81,7 @@ public struct Scheme: Equatable {
self.config = config
}
public static func ==(lhs: Analyze, rhs: Analyze) -> Bool {
public static func == (lhs: Analyze, rhs: Analyze) -> Bool {
return lhs.config == rhs.config
}
}
@@ -92,7 +92,7 @@ public struct Scheme: Equatable {
self.config = config
}
public static func ==(lhs: Profile, rhs: Profile) -> Bool {
public static func == (lhs: Profile, rhs: Profile) -> Bool {
return lhs.config == rhs.config
}
}
@@ -103,7 +103,7 @@ public struct Scheme: Equatable {
self.config = config
}
public static func ==(lhs: Archive, rhs: Archive) -> Bool {
public static func == (lhs: Archive, rhs: Archive) -> Bool {
return lhs.config == rhs.config
}
}
@@ -117,12 +117,12 @@ public struct Scheme: Equatable {
self.buildTypes = buildTypes
}
public static func ==(lhs: BuildTarget, rhs: BuildTarget) -> Bool {
public static func == (lhs: BuildTarget, rhs: BuildTarget) -> Bool {
return lhs.target == rhs.target && lhs.buildTypes == rhs.buildTypes
}
}
public static func ==(lhs: Scheme, rhs: Scheme) -> Bool {
public static func == (lhs: Scheme, rhs: Scheme) -> Bool {
return lhs.build == rhs.build &&
lhs.run == rhs.run &&
lhs.test == rhs.test &&
+25 -2
View File
@@ -10,7 +10,6 @@ import Foundation
import JSONUtilities
import xcproj
import PathKit
import Yams
public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertible {
@@ -45,7 +44,7 @@ public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertibl
}
}
public static func ==(lhs: Settings, rhs: Settings) -> Bool {
public static func == (lhs: Settings, rhs: Settings) -> Bool {
return NSDictionary(dictionary: lhs.buildSettings).isEqual(to: rhs.buildSettings) &&
lhs.configSettings == rhs.configSettings &&
lhs.groups == rhs.groups
@@ -90,3 +89,27 @@ extension Settings: ExpressibleByDictionaryLiteral {
self.init(dictionary: dictionary)
}
}
extension Dictionary where Key == String, Value: Any {
public func merged(_ dictionary: [Key: Value]) -> [Key: Value] {
var mergedDictionary = self
mergedDictionary.merge(dictionary)
return mergedDictionary
}
public mutating func merge(_ dictionary: [Key: Value]) {
for (key, value) in dictionary {
self[key] = value
}
}
public func equals(_ dictionary: BuildSettings) -> Bool {
return NSDictionary(dictionary: self).isEqual(to: dictionary)
}
}
public func += (lhs: inout BuildSettings, rhs: BuildSettings?) {
guard let rhs = rhs else { return }
lhs.merge(rhs)
}
+60
View File
@@ -0,0 +1,60 @@
//
// Source.swift
// ProjectSpec
//
// Created by Yonas Kolb on 31/10/17.
//
import Foundation
import JSONUtilities
import PathKit
public struct Source {
public var path: String
public var compilerFlags: [String]
public init(path: String, compilerFlags: [String] = []) {
self.path = path
self.compilerFlags = compilerFlags
}
}
extension Source: ExpressibleByStringLiteral {
public init(stringLiteral value: String) {
self = Source(path: value)
}
public init(extendedGraphemeClusterLiteral value: String) {
self = Source(path: value)
}
public init(unicodeScalarLiteral value: String) {
self = Source(path: value)
}
}
extension Source: JSONObjectConvertible {
public init(jsonDictionary: JSONDictionary) throws {
path = try jsonDictionary.json(atKeyPath: "path")
let maybeCompilerFlagsString: String? = jsonDictionary.json(atKeyPath: "compilerFlags")
let maybeCompilerFlagsArray: [String]? = jsonDictionary.json(atKeyPath: "compilerFlags")
compilerFlags = maybeCompilerFlagsArray ??
maybeCompilerFlagsString.map{ $0.split(separator: " ").map{ String($0) } } ?? []
}
}
extension Source: Equatable {
public static func == (lhs: Source, rhs: Source) -> Bool {
return lhs.path == rhs.path && lhs.compilerFlags == rhs.compilerFlags
}
}
extension Source: Hashable {
public var hashValue: Int {
return path.hashValue ^ compilerFlags.joined(separator: ":").hashValue
}
}
@@ -7,16 +7,15 @@
//
import Foundation
import ProjectSpec
import PathKit
import Yams
import JSONUtilities
public struct SpecLoader {
extension ProjectSpec {
public static func loadSpec(path: Path) throws -> ProjectSpec {
let dictionary = try loadDictionary(path: path)
return try ProjectSpec(basePath: path.parent(), jsonDictionary: dictionary)
public init(path: Path) throws {
let dictionary = try ProjectSpec.loadDictionary(path: path)
try self.init(basePath: path.parent(), jsonDictionary: dictionary)
}
private static func loadDictionary(path: Path) throws -> JSONDictionary {
@@ -8,7 +8,7 @@
import Foundation
public enum ProjectSpecError: Error, CustomStringConvertible {
public enum SpecParsingError: Error, CustomStringConvertible {
case unknownTargetType(String)
case unknownTargetPlatform(String)
case invalidDependency([String: Any])
@@ -6,21 +6,16 @@
//
import Foundation
import ProjectSpec
import PathKit
extension ProjectSpec {
public mutating func validate() throws {
public func validate() throws {
if configs.isEmpty {
configs = [Config(name: "Debug", type: .debug), Config(name: "Release", type: .release)]
}
var errors: [SpecValidationError.ValidationError] = []
var errors: [SpecValidationError.Error] = []
func validateSettings(_ settings: Settings) -> [SpecValidationError.Error] {
var errors: [SpecValidationError.Error] = []
func validateSettings(_ settings: Settings) -> [SpecValidationError.ValidationError] {
var errors: [SpecValidationError.ValidationError] = []
for group in settings.groups {
if let settings = settingGroups[group] {
errors += validateSettings(settings)
@@ -29,13 +24,15 @@ extension ProjectSpec {
}
}
for config in settings.configSettings.keys {
if !configs.contains(where: { $0.name.lowercased().contains(config.lowercased())}) {
errors.append(.invalidConfigReference(config))
if !configs.contains(where: { $0.name.lowercased().contains(config.lowercased()) }) {
errors.append(.invalidBuildSettingConfig(config))
}
}
return errors
}
errors += validateSettings(settings)
for fileGroup in fileGroups {
if !(basePath + fileGroup).exists {
errors.append(.invalidFileGroup(fileGroup))
@@ -46,6 +43,9 @@ extension ProjectSpec {
if !(basePath + configFile).exists {
errors.append(.invalidConfigFile(configFile: configFile, config: config))
}
if getConfig(config) == nil {
errors.append(.invalidConfigFileConfig(config))
}
}
for settings in settingGroups.values {
@@ -61,20 +61,17 @@ extension ProjectSpec {
for (config, configFile) in target.configFiles {
if !(basePath + configFile).exists {
errors.append(.invalidTargetConfigFile(configFile: configFile, config: config, target: target.name))
errors.append(.invalidTargetConfigFile(target: target.name, configFile: configFile, config: config))
}
}
for config in target.settings.configSettings.keys {
if getConfig(config) == nil {
errors.append(.invalidBuildSettingConfig(config))
errors.append(.invalidConfigFileConfig(config))
}
}
for source in target.sources {
let sourcePath = basePath + source
let sourcePath = basePath + source.path
if !sourcePath.exists {
errors.append(.missingTargetSource(target: target.name, source: sourcePath.string))
errors.append(.invalidTargetSource(target: target.name, source: sourcePath.string))
}
}
@@ -110,7 +107,7 @@ extension ProjectSpec {
if case let .path(pathString) = script.script {
let scriptPath = basePath + pathString
if !scriptPath.exists {
errors.append(.invalidBuildScriptPath(target: target.name, path: pathString))
errors.append(.invalidBuildScriptPath(target: target.name, name: script.name, path: pathString))
}
}
}
@@ -146,54 +143,3 @@ extension ProjectSpec {
}
}
}
public struct SpecValidationError: Error, CustomStringConvertible {
public var errors: [Error]
public enum Error: CustomStringConvertible {
case invalidTargetDependency(target: String, dependency: String)
case invalidSchemeTarget(scheme: String, target: String)
case invalidSchemeConfig(scheme: String, config: String)
case invalidConfigFile(configFile: String, config: String)
case invalidTargetConfigFile(configFile: String, config: String, target: String)
case invalidBuildSettingConfig(String)
case invalidSettingsGroup(String)
case missingTargetSource(target: String, source: String)
case invalidBuildScriptPath(target: String, path: String)
case invalidTargetSchemeConfigVariant(target: String, configVariant: String, configType: ConfigType)
case invalidTargetSchemeTest(target: String, testTarget: String)
case invalidFileGroup(String)
case invalidConfigReference(String)
case missingConfigTypeForGeneratedTargetScheme(target: String, configType: ConfigType)
public var description: String {
switch self {
case let .invalidTargetDependency(target, dependency): return "Target \(target.quoted) has invalid dependency: \(dependency.quoted)"
case let .invalidTargetConfigFile(configFile, config, target): return "Target \(target.quoted) has invalid config file \(configFile.quoted) for config \(config.quoted)"
case let .invalidConfigFile(configFile, config): return "Invalid config file \(configFile.quoted) for config \(config.quoted)"
case let .invalidSchemeTarget(scheme, target): return "Scheme \(scheme.quoted) has invalid build target \(target.quoted)"
case let .invalidSchemeConfig(scheme, config): return "Scheme \(scheme.quoted) has invalid build configuration \(config.quoted)"
case let .invalidBuildSettingConfig(config): return "Build setting has invalid build configuration \(config.quoted)"
case let .missingTargetSource(target, source): return "Target \(target.quoted) has a missing source directory \(source.quoted)"
case let .invalidSettingsGroup(group): return "Invalid settings group \(group.quoted)"
case let .invalidBuildScriptPath(target, path): return "Target \(target.quoted) has a script path that doesn't exist \(path.quoted)"
case let .invalidTargetSchemeConfigVariant(target, configVariant, configType): return "Target \(target.quoted) has an invalid scheme config variant which requires a config that has a \(configType.rawValue.quoted) type and contains the name \(configVariant.quoted)"
case let .invalidTargetSchemeTest(target, test): return "Target \(target.quoted) scheme has invalid test \(test.quoted)"
case let .invalidFileGroup(group): return "Invalid file group \(group.quoted)"
case let .invalidConfigReference(config): return "Invalid config reference \(config.quoted)"
case let .missingConfigTypeForGeneratedTargetScheme(target, configType): return "Target \(target.quoted) is missing a config of type \(configType.rawValue) to generate its scheme"
}
}
}
public var description: String {
let title: String
if errors.count == 1 {
title = "Spec validation error: "
} else {
title = "\(errors.count) Spec validations errors:\n\t- "
}
return "\(title)" + errors.map { $0.description }.joined(separator: "\n\t- ")
}
}
@@ -0,0 +1,59 @@
//
// SpecValidationError.swift
// ProjectSpec
//
// Created by Yonas Kolb on 29/10/17.
//
import Foundation
public struct SpecValidationError: Error, CustomStringConvertible {
public var errors: [ValidationError]
public enum ValidationError: Error, CustomStringConvertible {
case invalidTargetDependency(target: String, dependency: String)
case invalidTargetSource(target: String, source: String)
case invalidTargetConfigFile(target: String, configFile: String, config: String)
case invalidTargetSchemeConfigVariant(target: String, configVariant: String, configType: ConfigType)
case invalidTargetSchemeTest(target: String, testTarget: String)
case invalidSchemeTarget(scheme: String, target: String)
case invalidSchemeConfig(scheme: String, config: String)
case invalidConfigFile(configFile: String, config: String)
case invalidBuildSettingConfig(String)
case invalidSettingsGroup(String)
case invalidBuildScriptPath(target: String, name: String?, path: String)
case invalidFileGroup(String)
case invalidConfigFileConfig(String)
case missingConfigTypeForGeneratedTargetScheme(target: String, configType: ConfigType)
public var description: String {
switch self {
case let .invalidTargetDependency(target, dependency): return "Target \(target.quoted) has invalid dependency: \(dependency.quoted)"
case let .invalidTargetConfigFile(target, configFile, config): return "Target \(target.quoted) has invalid config file \(configFile.quoted) for config \(config.quoted)"
case let .invalidTargetSource(target, source): return "Target \(target.quoted) has a missing source directory \(source.quoted)"
case let .invalidTargetSchemeConfigVariant(target, configVariant, configType): return "Target \(target.quoted) has an invalid scheme config variant which requires a config that has a \(configType.rawValue.quoted) type and contains the name \(configVariant.quoted)"
case let .invalidTargetSchemeTest(target, test): return "Target \(target.quoted) scheme has invalid test \(test.quoted)"
case let .invalidConfigFile(configFile, config): return "Invalid config file \(configFile.quoted) for config \(config.quoted)"
case let .invalidSchemeTarget(scheme, target): return "Scheme \(scheme.quoted) has invalid build target \(target.quoted)"
case let .invalidSchemeConfig(scheme, config): return "Scheme \(scheme.quoted) has invalid build configuration \(config.quoted)"
case let .invalidBuildSettingConfig(config): return "Build setting has invalid build configuration \(config.quoted)"
case let .invalidSettingsGroup(group): return "Invalid settings group \(group.quoted)"
case let .invalidBuildScriptPath(target, name, path): return "Target \(target.quoted) has a script \(name != nil ? "\(name!.quoted) which has a " : "")path that doesn't exist \(path.quoted)"
case let .invalidFileGroup(group): return "Invalid file group \(group.quoted)"
case let .invalidConfigFileConfig(config): return "Config file has invalid config \(config.quoted)"
case let .missingConfigTypeForGeneratedTargetScheme(target, configType): return "Target \(target.quoted) is missing a config of type \(configType.rawValue) to generate its scheme"
}
}
}
public var description: String {
let title: String
if errors.count == 1 {
title = "Spec validation error: "
} else {
title = "\(errors.count) Spec validations errors:\n\t- "
}
return "\(title)" + errors.map { $0.description }.joined(separator: "\n\t- ")
}
}
+20 -82
View File
@@ -15,7 +15,7 @@ public struct Target {
public var type: PBXProductType
public var platform: Platform
public var settings: Settings
public var sources: [String]
public var sources: [Source]
public var dependencies: [Dependency]
public var prebuildScripts: [BuildScript]
public var postbuildScripts: [BuildScript]
@@ -30,7 +30,7 @@ public struct Target {
return name
}
public init(name: String, type: PBXProductType, platform: Platform, settings: Settings = .empty, configFiles: [String: String] = [:], sources: [String] = [], dependencies: [Dependency] = [], prebuildScripts: [BuildScript] = [], postbuildScripts: [BuildScript] = [], scheme: TargetScheme? = nil) {
public init(name: String, type: PBXProductType, platform: Platform, settings: Settings = .empty, configFiles: [String: String] = [:], sources: [Source] = [], dependencies: [Dependency] = [], prebuildScripts: [BuildScript] = [], postbuildScripts: [BuildScript] = [], scheme: TargetScheme? = nil) {
self.name = name
self.type = type
self.platform = platform
@@ -120,7 +120,7 @@ extension Target {
extension Target: Equatable {
public static func ==(lhs: Target, rhs: Target) -> Bool {
public static func == (lhs: Target, rhs: Target) -> Bool {
return lhs.name == rhs.name &&
lhs.type == rhs.type &&
lhs.platform == rhs.platform &&
@@ -135,8 +135,8 @@ extension Target: Equatable {
}
public struct TargetScheme {
public let testTargets: [String]
public let configVariants: [String]
public var testTargets: [String]
public var configVariants: [String]
public init(testTargets: [String] = [], configVariants: [String] = []) {
self.testTargets = testTargets
@@ -146,7 +146,7 @@ public struct TargetScheme {
extension TargetScheme: Equatable {
public static func ==(lhs: TargetScheme, rhs: TargetScheme) -> Bool {
public static func == (lhs: TargetScheme, rhs: TargetScheme) -> Bool {
return lhs.testTargets == rhs.testTargets &&
lhs.configVariants == rhs.configVariants
}
@@ -168,20 +168,30 @@ extension Target: NamedJSONDictionaryConvertible {
if let type = PBXProductType(string: typeString) {
self.type = type
} else {
throw ProjectSpecError.unknownTargetType(typeString)
throw SpecParsingError.unknownTargetType(typeString)
}
let platformString: String = try jsonDictionary.json(atKeyPath: "platform")
if let platform = Platform(rawValue: platformString) {
self.platform = platform
} else {
throw ProjectSpecError.unknownTargetPlatform(platformString)
throw SpecParsingError.unknownTargetPlatform(platformString)
}
settings = jsonDictionary.json(atKeyPath: "settings") ?? .empty
configFiles = jsonDictionary.json(atKeyPath: "configFiles") ?? [:]
if let source: String = jsonDictionary.json(atKeyPath: "sources") {
sources = [source]
sources = [Source(path: source)]
} else if let array = jsonDictionary["sources"] as? [Any] {
sources = try array.flatMap { source in
if let string = source as? String {
return Source(path: string)
} else if let dictionary = source as? [String: Any] {
return try Source(jsonDictionary: dictionary)
} else {
return nil
}
}
} else {
sources = jsonDictionary.json(atKeyPath: "sources") ?? []
sources = []
}
if jsonDictionary["dependencies"] == nil {
dependencies = []
@@ -193,75 +203,3 @@ extension Target: NamedJSONDictionaryConvertible {
scheme = jsonDictionary.json(atKeyPath: "scheme")
}
}
public struct Dependency: Equatable {
public var type: DependencyType
public var reference: String
public var embed: Bool?
public var codeSign: Bool = true
public var removeHeaders: Bool = true
public var link: Bool = true
public init(type: DependencyType, reference: String, embed: Bool? = nil) {
self.type = type
self.reference = reference
self.embed = embed
}
public enum DependencyType {
case target
case framework
case carthage
}
public static func ==(lhs: Dependency, rhs: Dependency) -> Bool {
return lhs.reference == rhs.reference &&
lhs.type == rhs.type &&
lhs.codeSign == rhs.codeSign &&
lhs.removeHeaders == rhs.removeHeaders &&
lhs.embed == rhs.embed &&
lhs.link == rhs.link
}
public var buildSettings: [String: Any] {
var attributes: [String] = []
if codeSign {
attributes.append("CodeSignOnCopy")
}
if removeHeaders {
attributes.append("RemoveHeadersOnCopy")
}
return ["ATTRIBUTES": attributes]
}
}
extension Dependency: JSONObjectConvertible {
public init(jsonDictionary: JSONDictionary) throws {
if let target: String = jsonDictionary.json(atKeyPath: "target") {
type = .target
reference = target
} else if let framework: String = jsonDictionary.json(atKeyPath: "framework") {
type = .framework
reference = framework
} else if let carthage: String = jsonDictionary.json(atKeyPath: "carthage") {
type = .carthage
reference = carthage
} else {
throw ProjectSpecError.invalidDependency(jsonDictionary)
}
embed = jsonDictionary.json(atKeyPath: "embed")
if let bool: Bool = jsonDictionary.json(atKeyPath: "link") {
link = bool
}
if let bool: Bool = jsonDictionary.json(atKeyPath: "codeSign") {
codeSign = bool
}
if let bool: Bool = jsonDictionary.json(atKeyPath: "removeHeaders") {
removeHeaders = bool
}
}
}
@@ -10,30 +10,6 @@ import Foundation
import xcproj
import PathKit
extension Dictionary where Key == String, Value: Any {
public func merged(_ dictionary: [Key: Value]) -> [Key: Value] {
var mergedDictionary = self
mergedDictionary.merge(dictionary)
return mergedDictionary
}
public mutating func merge(_ dictionary: [Key: Value]) {
for (key, value) in dictionary {
self[key] = value
}
}
public func equals(_ dictionary: BuildSettings) -> Bool {
return NSDictionary(dictionary: self).isEqual(to: dictionary)
}
}
public func +=(lhs: inout BuildSettings, rhs: BuildSettings?) {
guard let rhs = rhs else { return }
lhs.merge(rhs)
}
extension PBXProductType {
init?(string: String) {
@@ -9,7 +9,7 @@ import Foundation
import Yams
import PathKit
func loadYamlDictionary(path: Path) throws -> [String: Any] {
public func loadYamlDictionary(path: Path) throws -> [String: Any] {
let string: String = try path.read()
if string == "" {
return [:]
+1 -1
View File
@@ -29,7 +29,7 @@ func generate(spec: String, project: String) {
let spec: ProjectSpec
do {
spec = try SpecLoader.loadSpec(path: specPath)
spec = try ProjectSpec(path: specPath)
print("📋 Loaded spec:\n \(spec.debugDescription.replacingOccurrences(of: "\n", with: "\n "))")
} catch let error as JSONUtilities.DecodingError {
print("Parsing spec failed: \(error.description)".red)
+125 -74
View File
@@ -65,7 +65,8 @@ public class PBXProjGenerator {
project = PBXProj(objectVersion: 46, rootObject: generateUUID(PBXProject.self, spec.name))
for group in spec.fileGroups {
_ = try getGroups(path: spec.basePath + group)
// TODO: call a seperate function that only creates groups not source files
_ = try getSources(sourceMetadata: Source(path: group), path: spec.basePath + group)
}
let buildConfigs: [XCBuildConfiguration] = spec.configs.map { config in
@@ -143,13 +144,17 @@ public class PBXProjGenerator {
let buildFile: PBXBuildFile
}
func generateSourceFile(path: Path) -> SourceFile {
func generateSourceFile(sourceMetadata source: Source, path: Path) -> SourceFile {
let fileReference = fileReferencesByPath[path]!
var settings: [String: Any]?
var settings: [String: Any] = [:]
if getBuildPhaseForPath(path) == .headers {
settings = ["ATTRIBUTES": ["Public"]]
}
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference), fileRef: fileReference, settings: settings)
if source.compilerFlags.count > 0 {
settings["COMPILER_FLAGS"] = source.compilerFlags.joined(separator: " ")
}
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference), fileRef: fileReference, settings: settings.isEmpty ? nil : settings)
return SourceFile(path: path, fileReference: fileReference, buildFile: buildFile)
}
@@ -157,17 +162,20 @@ public class PBXProjGenerator {
let carthageDependencies = getAllCarthageDependencies(target: target)
let sourcePaths = target.sources.map { spec.basePath + $0 }
var sourceFiles: [SourceFile] = []
let sourceFiles = try getAllSourceFiles(sources: target.sources)
for source in sourcePaths {
let sourceGroups = try getGroups(path: source)
sourceFiles += sourceGroups.sourceFiles
}
// find all Info.plist
let infoPlists: [Path] = sourcePaths.reduce([]) {
$0 + ((try? $1.recursiveChildren()) ?? []).filter { $0.lastComponent == "Info.plist" }
// find all Info.plist files
let infoPlists: [Path] = target.sources.map { spec.basePath + $0.path }.flatMap { (path) -> [Path] in
if path.isFile {
if path.lastComponent == "Info.plist" {
return [path]
}
} else {
if let children = try? path.recursiveChildren() {
return children.filter { $0.lastComponent == "Info.plist" }
}
}
return []
}
let configs: [XCBuildConfiguration] = spec.configs.map { config in
@@ -354,9 +362,11 @@ public class PBXProjGenerator {
addObject(resourcesBuildPhase)
buildPhases.append(resourcesBuildPhase.reference)
let headersBuildPhase = PBXHeadersBuildPhase(reference: generateUUID(PBXHeadersBuildPhase.self, target.name), files: getBuildFilesForPhase(.headers))
addObject(headersBuildPhase)
buildPhases.append(headersBuildPhase.reference)
if target.type == .framework || target.type == .dynamicLibrary {
let headersBuildPhase = PBXHeadersBuildPhase(reference: generateUUID(PBXHeadersBuildPhase.self, target.name), files: getBuildFilesForPhase(.headers))
addObject(headersBuildPhase)
buildPhases.append(headersBuildPhase.reference)
}
if !targetFrameworkBuildFiles.isEmpty {
@@ -406,8 +416,8 @@ public class PBXProjGenerator {
}
let carthageFrameworksToEmbed = Array(Set(carthageDependencies
.filter { $0.embed ?? true }
.map { $0.reference }))
.filter { $0.embed ?? true }
.map { $0.reference }))
.sorted()
if !carthageFrameworksToEmbed.isEmpty {
@@ -465,7 +475,7 @@ public class PBXProjGenerator {
}
if let fileExtension = path.extension {
switch fileExtension {
case "swift", "m", "cpp": return .sources
case "swift", "m", "mm", "cpp", "c": return .sources
case "h", "hh", "hpp", "ipp", "tpp", "hxx", "def": return .headers
case "xcconfig", "entitlements", "gpx", "lproj", "apns": return nil
default: return .resources
@@ -474,94 +484,134 @@ public class PBXProjGenerator {
return nil
}
func getFileReference(path: Path, inPath: Path) -> String {
func getFileReference(path: Path, inPath: Path, name: String? = nil) -> String {
if let fileReference = fileReferencesByPath[path] {
return fileReference
} else {
let fileReference = PBXFileReference(reference: generateUUID(PBXFileReference.self, path.lastComponent), sourceTree: .group, path: path.byRemovingBase(path: inPath).string)
let fileReference = PBXFileReference(reference: generateUUID(PBXFileReference.self, path.lastComponent), sourceTree: .group, name: name, path: path.byRemovingBase(path: inPath).string)
addObject(fileReference)
fileReferencesByPath[path] = fileReference.reference
return fileReference.reference
}
}
func getGroups(path: Path, depth: Int = 0) throws -> (sourceFiles: [SourceFile], groups: [PBXGroup]) {
func getAllSourceFiles(sources: [Source]) throws -> [SourceFile] {
return try sources.flatMap{ try getSources(sourceMetadata: $0, path: spec.basePath + $0.path).sourceFiles }
}
func getSingleGroup(path: Path, mergingChildren children: [String], depth: Int = 0) -> PBXGroup {
let group: PBXGroup
if let cachedGroup = groupsByPath[path] {
cachedGroup.children += children
group = cachedGroup
} else {
group = PBXGroup(
reference: generateUUID(PBXGroup.self, path.lastComponent),
children: children,
sourceTree: .group,
name: path.lastComponent,
path: depth == 0 && !spec.options.createIntermediateGroups ?
path.byRemovingBase(path: spec.basePath).string :
path.lastComponent
)
addObject(group)
groupsByPath[path] = group
}
return group
}
// Add groups for all parents recursively
// ex: path/foo/bar/baz/Hello.swift -> path:[foo:[bar:[baz:[Hello.swift]]]]
func getIntermediateGroups(path: Path, group: PBXGroup) -> PBXGroup {
// verify path is a subpath of spec.basePath
guard Path(components: zip(path.components, spec.basePath.components).map{ $0.0 }) == spec.basePath else {
return group
}
// base case
if path == spec.basePath {
return group
}
// recursive case
return getIntermediateGroups(
path: path.parent(),
group: getSingleGroup(path: path, mergingChildren: [group.reference])
)
}
func getVariantGroup(path: Path, inPath: Path) -> PBXVariantGroup {
let variantGroup: PBXVariantGroup
if let cachedGroup = variantGroupsByPath[path] {
variantGroup = cachedGroup
} else {
variantGroup = PBXVariantGroup(reference: generateUUID(PBXVariantGroup.self, path.byRemovingBase(path: inPath).string),
children: [],
name: path.lastComponent,
sourceTree: .group)
addObject(variantGroup)
variantGroupsByPath[path] = variantGroup
}
return variantGroup
}
func getSources(sourceMetadata source: Source, path: Path, depth: Int = 0) throws -> (sourceFiles: [SourceFile], groups: [PBXGroup]) {
// if we have a file, move it to children and use the parent as the path
let (children, path) = path.isFile ?
([path], path.parent()) :
(try path.children(), path)
let excludedFiles: [String] = [".DS_Store"]
let directories = try path.children()
let directories = children
.filter { $0.isDirectory && $0.extension == nil && $0.extension != "lproj" }
.sorted { $0.lastComponent < $1.lastComponent }
let filePaths = try path.children()
let filePaths = children
.filter { $0.isFile || $0.extension != nil && $0.extension != "lproj" }
.filter { !excludedFiles.contains($0.lastComponent) }
.sorted { $0.lastComponent < $1.lastComponent }
let localisedDirectories = try path.children()
let localisedDirectories = children
.filter { $0.extension == "lproj" }
.sorted { $0.lastComponent < $1.lastComponent }
var groupChildren: [String] = filePaths.map { getFileReference(path: $0, inPath: path) }
var allSourceFiles: [SourceFile] = filePaths.map { generateSourceFile(path: $0) }
var allSourceFiles: [SourceFile] = filePaths.map {
generateSourceFile(sourceMetadata: Source(path: $0.string, compilerFlags: source.compilerFlags), path: $0)
}
var groups: [PBXGroup] = []
for path in directories {
let subGroups = try getGroups(path: path, depth: depth + 1)
let subGroups = try getSources(sourceMetadata: source, path: path, depth: depth + 1)
allSourceFiles += subGroups.sourceFiles
groupChildren.append(subGroups.groups.first!.reference)
groups += subGroups.groups
}
// create variant groups of the base localisation first
var baseLocalisationVariantGroups:[PBXVariantGroup] = []
var baseLocalisationVariantGroups: [PBXVariantGroup] = []
if let baseLocalisedDirectory = localisedDirectories.first(where: { $0.lastComponent == "Base.lproj" }) {
for path in try baseLocalisedDirectory.children() {
let filePath = "\(baseLocalisedDirectory.lastComponent)/\(path.lastComponent)"
let variantGroup: PBXVariantGroup
if let cachedGroup = variantGroupsByPath[path] {
variantGroup = cachedGroup
} else {
variantGroup = PBXVariantGroup(reference: generateUUID(PBXVariantGroup.self, filePath),
children: [],
name: path.lastComponent,
sourceTree: .group)
variantGroupsByPath[path] = variantGroup
addObject(variantGroup)
groupChildren.append(variantGroup.reference)
}
for filePath in try baseLocalisedDirectory.children() {
let variantGroup = getVariantGroup(path: filePath, inPath: path)
groupChildren.append(variantGroup.reference)
baseLocalisationVariantGroups.append(variantGroup)
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, variantGroup.reference), fileRef: variantGroup.reference, settings: nil)
allSourceFiles.append(SourceFile(path: path, fileReference: variantGroup.reference, buildFile: buildFile))
allSourceFiles.append(SourceFile(path: filePath, fileReference: variantGroup.reference, buildFile: buildFile))
}
}
// add references to localised resources into base localisation variant groups
for localisedDirectory in localisedDirectories {
let localisationName = localisedDirectory.lastComponentWithoutExtension
for path in try localisedDirectory.children().sorted { $0.lastComponent < $1.lastComponent } {
let filePath = "\(localisedDirectory.lastComponent)/\(path.lastComponent)"
for filePath in try localisedDirectory.children().sorted { $0.lastComponent < $1.lastComponent } {
// find base localisation variant group
let name = path.lastComponentWithoutExtension
let variantGroup = baseLocalisationVariantGroups.first { Path($0.name!).lastComponentWithoutExtension == name }
// ex: Foo.strings will be added to Foo.strings or Foo.storyboard variant group
let variantGroup = baseLocalisationVariantGroups.first { Path($0.name!).lastComponent == filePath.lastComponent } ??
baseLocalisationVariantGroups.first { Path($0.name!).lastComponentWithoutExtension == filePath.lastComponentWithoutExtension }
let fileReference: String
if let cachedFileReference = fileReferencesByPath[path] {
fileReference = cachedFileReference
} else {
let reference = PBXFileReference(reference: generateUUID(PBXFileReference.self, path.lastComponent),
sourceTree: .group,
name: variantGroup != nil ? localisationName : path.lastComponent,
path: filePath)
addObject(reference)
fileReference = reference.reference
fileReferencesByPath[path] = fileReference
}
let fileReference = getFileReference(path: filePath, inPath: path, name: variantGroup != nil ? localisationName : filePath.lastComponent)
if let variantGroup = variantGroup {
if !variantGroup.children.contains(fileReference) {
@@ -572,23 +622,24 @@ public class PBXProjGenerator {
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference),
fileRef: fileReference,
settings: nil)
allSourceFiles.append(SourceFile(path: path, fileReference: fileReference, buildFile: buildFile))
allSourceFiles.append(SourceFile(path: filePath, fileReference: fileReference, buildFile: buildFile))
groupChildren.append(fileReference)
}
}
}
let groupPath: String = depth == 0 ? path.byRemovingBase(path: spec.basePath).string : path.lastComponent
let group: PBXGroup
if let cachedGroup = groupsByPath[path] {
group = cachedGroup
if spec.options.createIntermediateGroups {
group = getIntermediateGroups(
path: path.parent(),
group: getSingleGroup(path: path, mergingChildren: groupChildren, depth: depth)
)
} else {
group = PBXGroup(reference: generateUUID(PBXGroup.self, path.lastComponent), children: groupChildren, sourceTree: .group, name: path.lastComponent, path: groupPath)
addObject(group)
if depth == 0 {
topLevelGroups.append(group)
}
groupsByPath[path] = group
group = getSingleGroup(path: path, mergingChildren: groupChildren, depth: depth)
}
if depth == 0 {
topLevelGroups.append(group)
}
groups.insert(group, at: 0)
return (allSourceFiles, groups)
+1 -1
View File
@@ -15,7 +15,7 @@ import ProjectSpec
public class ProjectGenerator {
var spec: ProjectSpec
let spec: ProjectSpec
let currentXcodeVersion = "0900"
public init(spec: ProjectSpec) {
+1 -1
View File
@@ -37,7 +37,7 @@ extension ProjectSpec {
public func getTargetBuildSettings(target: Target, config: Config) -> BuildSettings {
var buildSettings = BuildSettings()
if options.settingPresets.applyTarget {
buildSettings += SettingsPresetFile.platform(target.platform).getBuildSettings()
buildSettings += SettingsPresetFile.product(target.type).getBuildSettings()
+3 -3
View File
@@ -7,7 +7,7 @@ import ProjectSpec
let fixturePath = Path(#file).parent().parent().parent() + "Fixtures"
func generate(specPath: Path, projectPath: Path) throws -> XcodeProj {
let spec = try SpecLoader.loadSpec(path: specPath)
let spec = try ProjectSpec(path: specPath)
let generator = ProjectGenerator(spec: spec)
let project = try generator.generateProject()
let oldProject = try XcodeProj(path: projectPath)
@@ -27,11 +27,11 @@ func fixtureTests() {
var project: XcodeProj?
$0.it("generates") {
project = try generate(specPath: fixturePath + "TestProject/spec.yml", projectPath: fixturePath + "TestProject/GeneratedProject.xcodeproj")
project = try generate(specPath: fixturePath + "TestProject/spec.yml", projectPath: fixturePath + "TestProject/Project.xcodeproj")
}
$0.it("generates variant group") {
guard let project = project else { throw failure("Project is not generated") }
guard let project = project else { return }
func getFileReferences(_ path: String) -> [PBXFileReference] {
return project.pbxproj.fileReferences.filter { $0.path == path }
@@ -3,6 +3,7 @@ import XcodeGenKit
import xcproj
import PathKit
import ProjectSpec
import Yams
func projectGeneratorTests() {
@@ -12,6 +13,7 @@ func projectGeneratorTests() {
}
func getPbxProj(_ spec: ProjectSpec) throws -> PBXProj {
try spec.validate()
return try getProject(spec).pbxproj
}
@@ -38,20 +40,19 @@ func projectGeneratorTests() {
let buildConfigs = project.pbxproj.configurationLists.getReference(buildConfigList),
let buildConfigReference = buildConfigs.buildConfigurations.first,
let buildConfig = project.pbxproj.buildConfigurations.getReference(buildConfigReference) else {
throw failure("Build Config not found")
throw failure("Build Config not found")
}
try expect(buildConfig.buildSettings["PRODUCT_BUNDLE_IDENTIFIER"] as? String) == "com.test.MyFramework"
}
$0.it("clears setting presets") {
var options = ProjectSpec.Options()
options.settingPresets = .none
let spec = ProjectSpec(basePath: "", name: "test", targets: [framework], options: options)
let project = try getProject(spec)
let allSettings = project.pbxproj.buildConfigurations.reduce([:]) { $0.merged($1.buildSettings)}.keys.sorted()
let allSettings = project.pbxproj.buildConfigurations.reduce([:]) { $0.merged($1.buildSettings) }.keys.sorted()
try expect(allSettings) == ["SETTING_2"]
}
}
$0.describe("Config") {
@@ -73,7 +74,7 @@ func projectGeneratorTests() {
try expect(configs).contains(name: "config1")
try expect(configs).contains(name: "config2")
}
$0.it("clears config settings when missing type") {
let spec = ProjectSpec(basePath: "", name: "test", configs: [Config(name: "config")])
let project = try getProject(spec)
@@ -84,7 +85,7 @@ func projectGeneratorTests() {
}
$0.it("merges settings") {
let spec = try SpecLoader.loadSpec(path: fixturePath + "settings_test.yml")
let spec = try ProjectSpec(path: fixturePath + "settings_test.yml")
guard let config = spec.getConfig("config1") else { throw failure("Couldn't find config1") }
let debugProjectSettings = spec.getProjectBuildSettings(config: config)
@@ -114,8 +115,9 @@ func projectGeneratorTests() {
$0.it("applies partial config settings") {
let spec = ProjectSpec(basePath: "", name: "test", configs: [
Config(name: "Staging Debug", type: .debug),
Config(name: "Staging Release", type: .release)],
settings: Settings(configSettings: ["staging": ["SETTING1": "VALUE1"], "debug": ["SETTING2": "VALUE2"]]))
Config(name: "Staging Release", type: .release),
],
settings: Settings(configSettings: ["staging": ["SETTING1": "VALUE1"], "debug": ["SETTING2": "VALUE2"]]))
var buildSettings = spec.getProjectBuildSettings(config: spec.configs.first!)
try expect(buildSettings["SETTING1"] as? String) == "VALUE1"
@@ -232,5 +234,159 @@ func projectGeneratorTests() {
try expect(xcscheme.archiveAction?.buildConfiguration) == "Test Release"
}
}
$0.describe("Sources") {
let directoryPath = Path("TestDirectory")
var target = Target(name: "Test", type: .application, platform: .iOS)
var spec = ProjectSpec(basePath: directoryPath, name: "Test", targets: [target])
func createDirectories(_ directories: String) throws {
let yaml = try Yams.load(yaml: directories)!
func getFiles(_ file: Any, path: Path) -> [Path] {
if let array = file as? [Any] {
return array.flatMap { getFiles($0, path: path) }
} else if let string = file as? String {
return [path + string]
} else if let dictionary = file as? [String: Any] {
var array: [Path] = []
for (key, value) in dictionary {
array += getFiles(value, path: path + key)
}
return array
} else {
return []
}
}
let files = getFiles(yaml, path: directoryPath).filter { $0.extension != nil }
for file in files {
try file.parent().mkpath()
try file.write("")
}
}
func removeDirectories() {
try? directoryPath.delete()
}
$0.before {
removeDirectories()
}
$0.after {
removeDirectories()
}
$0.it("generates source groups") {
let directories = """
Sources:
A:
- a.swift
- B:
- b.swift
"""
try createDirectories(directories)
target.sources = ["Sources"]
spec.targets = [target]
let project = try getPbxProj(spec)
try project.expectFile(paths: ["Sources", "A", "a.swift"], buildPhase: .sources)
try project.expectFile(paths: ["Sources", "A", "B", "b.swift"], buildPhase: .sources)
}
$0.it("generates file sources") {
let directories = """
Sources:
A:
- a.swift
- B:
- b.swift
- c.jpg
"""
try createDirectories(directories)
target.sources = [
"Sources/A/a.swift",
"Sources/A/B/b.swift",
"Sources/A/B/c.jpg",
]
spec.targets = [target]
let project = try getPbxProj(spec)
try project.expectFile(paths: ["Sources/A", "a.swift"], names: ["A", "a.swift"], buildPhase: .sources)
try project.expectFile(paths: ["Sources/A/B", "b.swift"], names: ["B", "b.swift"], buildPhase: .sources)
try project.expectFile(paths: ["Sources/A/B", "c.jpg"], names: ["B", "c.jpg"], buildPhase: .resources)
}
}
}
}
extension PBXProj {
/// expect a file within groups of the paths, using optional different names
func expectFile(paths: [String], names: [String]? = nil, buildPhase: BuildPhase? = nil) throws {
let names = names ?? paths
guard let fileReference = getFileReference(paths: paths, names: names) else {
throw failure("Could not find file at path \(paths.joined(separator: "/").quoted) and name \(paths.joined(separator: "/").quoted)")
}
if let buildPhase = buildPhase {
guard let buildFile = buildFiles.first(where: { $0.fileRef == fileReference.reference}),
getBuildPhases(buildPhase).contains(where: { $0.files.contains(buildFile.reference)}) else {
throw failure("File \(paths.joined(separator: "/").quoted) is not in a \(buildPhase.rawValue.quoted) build phase")
}
}
}
func getFileReference(paths: [String], names: [String]) -> PBXFileReference? {
guard let project = projects.first else { return nil }
guard let mainGroup = groups.getReference(project.mainGroup) else { return nil }
return getFileReference(group: mainGroup, paths: paths, names: names)
}
private func getFileReference(group: PBXGroup, paths: [String], names: [String]) -> PBXFileReference? {
guard !paths.isEmpty else { return nil }
let path = paths.first!
let name = names.first!
let restOfPath = Array(paths.dropFirst())
let restOfName = Array(names.dropFirst())
if restOfPath.isEmpty {
let fileReferences = group.children.flatMap { self.fileReferences.getReference($0) }
return fileReferences.first { $0.path == path && $0.nameOrPath == name }
} else {
let groups = group.children.flatMap { self.groups.getReference($0) }
guard let group = groups.first(where: { $0.path == path && $0.nameOrPath == name }) else { return nil }
return getFileReference(group: group, paths: restOfPath, names: restOfName)
}
}
func getBuildPhases(_ buildPhase: BuildPhase) -> [PBXBuildPhase] {
switch buildPhase {
case .copyFiles: return copyFilesBuildPhases
case .sources: return sourcesBuildPhases
case .frameworks: return frameworksBuildPhases
case .resources: return resourcesBuildPhases
case .runScript: return shellScriptBuildPhases
case .headers: return headersBuildPhases
}
}
}
extension PBXFileReference {
var nameOrPath: String? {
return name ?? path
}
}
extension PBXGroup {
var nameOrPath: String? {
return name ?? path
}
}
@@ -24,5 +24,83 @@ func projectSpecTests() {
try expect(dynamicLibrary.type.isLibrary).to.beTrue()
}
}
func expectValidationError(_ spec: ProjectSpec, _ expectedError: SpecValidationError.ValidationError) throws {
do {
try spec.validate()
} catch let error as SpecValidationError {
if !error.errors.contains(where: { $0.description == expectedError.description }) {
throw failure("Supposed to fail with:\n\(expectedError)\nbut got:\n\(error.errors.map { $0.description }.joined(separator: "\n"))")
}
return
} catch {
throw failure("Supposed to fail with \"\(expectedError)\"")
}
throw failure("Supposed to fail with \"\(expectedError)\"")
}
$0.describe("Validation") {
let baseSpec = ProjectSpec(basePath: "", name: "", configs: [Config(name: "invalid")])
let invalidSettings = Settings(configSettings: ["invalidConfig": [:]],
groups: ["invalidSettingGroup"])
$0.it("fails with invalid project") {
var spec = baseSpec
spec.settings = invalidSettings
spec.configFiles = ["invalidConfig": "invalidConfigFile"]
spec.fileGroups = ["invalidFileGroup"]
spec.settingGroups = ["settingGroup1": Settings(configSettings: ["invalidSettingGroupConfig": [:]], groups: ["invalidSettingGroupSettingGroup"])]
try expectValidationError(spec, .invalidConfigFileConfig("invalidConfig"))
try expectValidationError(spec, .invalidBuildSettingConfig("invalidConfig"))
try expectValidationError(spec, .invalidConfigFile(configFile: "invalidConfigFile", config: "invalidConfig"))
try expectValidationError(spec, .invalidSettingsGroup("invalidSettingGroup"))
try expectValidationError(spec, .invalidFileGroup("invalidFileGroup"))
try expectValidationError(spec, .invalidSettingsGroup("invalidSettingGroupSettingGroup"))
try expectValidationError(spec, .invalidBuildSettingConfig("invalidSettingGroupConfig"))
}
$0.it("fails with invalid target") {
var spec = baseSpec
spec.targets = [Target(name: "target1",
type: .application,
platform: .iOS,
settings: invalidSettings,
configFiles: ["invalidConfig": "invalidConfigFile"],
sources: ["invalidSource"],
dependencies: [Dependency(type: .target, reference: "invalidDependency")],
prebuildScripts: [BuildScript(script: .path("invalidPrebuildScript"), name: "prebuildScript1")],
postbuildScripts: [BuildScript(script: .path("invalidPostbuildScript"))],
scheme: TargetScheme(testTargets: ["invalidTarget"])
)]
try expectValidationError(spec, .invalidTargetDependency(target: "target1", dependency: "invalidDependency"))
try expectValidationError(spec, .invalidTargetConfigFile(target: "target1", configFile: "invalidConfigFile", config: "invalidConfig"))
try expectValidationError(spec, .invalidTargetSchemeTest(target: "target1", testTarget: "invalidTarget"))
try expectValidationError(spec, .invalidTargetSource(target: "target1", source: "invalidSource"))
try expectValidationError(spec, .invalidBuildSettingConfig("invalidConfig"))
try expectValidationError(spec, .invalidSettingsGroup("invalidSettingGroup"))
try expectValidationError(spec, .invalidBuildScriptPath(target: "target1", name: "prebuildScript1", path: "invalidPrebuildScript"))
try expectValidationError(spec, .invalidBuildScriptPath(target: "target1", name: nil, path: "invalidPostbuildScript"))
try expectValidationError(spec, .missingConfigTypeForGeneratedTargetScheme(target: "target1", configType: .debug))
try expectValidationError(spec, .missingConfigTypeForGeneratedTargetScheme(target: "target1", configType: .release))
spec.targets[0].scheme?.configVariants = ["invalidVariant"]
try expectValidationError(spec, .invalidTargetSchemeConfigVariant(target: "target1", configVariant: "invalidVariant", configType: .debug))
}
$0.it("fails with invalid scheme") {
var spec = baseSpec
spec.schemes = [Scheme(name: "scheme1",
targets: [Scheme.BuildTarget(target: "invalidTarget")],
debugConfig: "debugInvalid",
releaseConfig: "releaseInvalid")]
try expectValidationError(spec, .invalidSchemeTarget(scheme: "scheme1", target: "invalidTarget"))
try expectValidationError(spec, .invalidSchemeConfig(scheme: "scheme1", config: "debugInvalid"))
try expectValidationError(spec, .invalidSchemeConfig(scheme: "scheme1", config: "releaseInvalid"))
}
}
}
}
+23 -5
View File
@@ -15,13 +15,13 @@ func specLoadingTests() {
return try ProjectSpec(basePath: "", jsonDictionary: specDictionary)
}
func expectProjectSpecError(_ spec: [String: Any], _ expectedError: ProjectSpecError) throws {
func expectProjectSpecError(_ spec: [String: Any], _ expectedError: SpecParsingError) throws {
try expectError(expectedError) {
try getProjectSpec(spec)
}
}
func expectTargetError(_ target: [String: Any], _ expectedError: ProjectSpecError) throws {
func expectTargetError(_ target: [String: Any], _ expectedError: SpecParsingError) throws {
try expectError(expectedError) {
_ = try Target(name: "test", jsonDictionary: target)
}
@@ -33,7 +33,7 @@ func specLoadingTests() {
describe("Spec Loader") {
$0.it("merges includes") {
let path = fixturePath + "include_test.yml"
let spec = try SpecLoader.loadSpec(path: path)
let spec = try ProjectSpec(path: path)
try expect(spec.name) == "NewName"
try expect(spec.settingGroups) == [
@@ -48,7 +48,7 @@ func specLoadingTests() {
}
}
describe("Project Spec") {
describe("Project Spec Parser") {
$0.it("fails with incorrect platform") {
var target = validTarget
@@ -68,6 +68,24 @@ func specLoadingTests() {
try expectTargetError(target, .invalidDependency([invalid: "name"]))
}
$0.it("parses sources") {
var targetDictionary1 = validTarget
targetDictionary1["sources"] = [
"source1",
["path": "source2"],
["path": "sourceWithFlags", "compilerFlags": ["-Werror"]],
["path": "sourceWithFlagsStr", "compilerFlags": "-Werror -Wextra"]
]
var targetDictionary2 = validTarget
targetDictionary2["sources"] = "source3"
let target1 = try Target(name: "test", jsonDictionary: targetDictionary1)
let target2 = try Target(name: "test", jsonDictionary: targetDictionary2)
try expect(target1.sources) == [Source(path: "source1"), Source(path: "source2"), Source(path: "sourceWithFlags", compilerFlags: ["-Werror"]), Source(path: "sourceWithFlagsStr", compilerFlags: ["-Werror", "-Wextra"])]
try expect(target2.sources) == [Source(path: "source3")]
}
$0.it("parses target dependencies") {
var targetDictionary = validTarget
targetDictionary["dependencies"] = [
@@ -128,7 +146,7 @@ func specLoadingTests() {
}
$0.it("parses settings") {
let spec = try SpecLoader.loadSpec(path: fixturePath + "settings_test.yml")
let spec = try ProjectSpec(path: fixturePath + "settings_test.yml")
let buildSettings: BuildSettings = ["SETTING": "value"]
let configSettings: [String: Settings] = ["config1": Settings(buildSettings: ["SETTING1": "value"])]
let groups = ["preset1"]
+1 -1
View File
@@ -63,7 +63,7 @@ extension ArrayExpectation {
let value = try expression()
if let value = value {
if try !value.contains(where: predicate) {
throw failure("value does not contain")
throw failure("value does not contain item: \(value)")
}
}
}
+15 -2
View File
@@ -63,6 +63,7 @@ Note that target names can also be changed by adding a `name` property to a targ
### Options
- ⚪️ **carthageBuildPath**: `String` - The path to the carthage build directory. Defaults to `Carthage/Build`. This is used when specifying target carthage dependencies
- ⚪️ **createIntermediateGroups**: `String` - If this is specified and set to `true`, then intermediate groups will be created for every path component between the folder containing the source and the base path. For example, when enabled if a source path is specified as `Vendor/Foo/Hello.swift`, the group `Vendor` will created as a parent of the `Foo` group.
- ⚪️ **bundleIdPrefix**: `String` - If this is specified then any target that doesn't have an `PRODUCT_BUNDLE_IDENTIFIER` (via all levels of build settings) will get an autogenerated one by combining `bundleIdPrefix` and the target name: `bundleIdPrefix.name`. The target name will be stripped of all characters that aren't alphanumerics, hyphens, or periods. Underscores will be replace with hyphens.
- ⚪️ **settingPresets**: `String` - This controls the settings that are automatically applied to the project and its targets. These are the same build settings that Xcode would add when creating a new project. Project settings are applied by config type. Target settings are applied by the product type and platform. By default this is set to `all`
- `all`: project and target settings
@@ -195,7 +196,14 @@ targets:
The above will generate 2 targets named `MyFramework_iOS` and `MyFramework_tvOS`, with all the relevant platform build settings. They will both have a `PRODUCT_NAME` of `MyFramework`
### Sources
Specifies the source directories for a target. This can either be a single path or a list of paths. Applicable source files, resources, headers, and lproj files will be parsed appropriately
Specifies the source directories for a target. This can either be a single source or a list of sources. Applicable source files, resources, headers, and lproj files will be parsed appropriately.
A source can be provided via a string (the path) or an object of the form:
**Source Object**:
- 🔵 **path**: `String` - The path to the source file or directory.
- ⚪️ **compilerFlags**: `[String]` or `String` - A list of compilerFlags to add to files under this specific path provided as a list or a space delimitted string. Defaults to empty.
```yaml
targets:
@@ -204,7 +212,12 @@ targets:
MyOtherTarget
sources:
- MyOtherTargetSource1
- MyOtherTargetSource2
- path: MyOtherTargetSource2
compilerFlags:
- "-Werror"
- "-Wextra"
- path: MyOtherTargetSource3
compilerFlags: "-Werror -Wextra"
```
### Dependency
-2
View File
@@ -1,2 +0,0 @@
swiftformat Tests --stripunusedargs closure-only
swiftformat sources --stripunusedargs closure-only