mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
Merge remote-tracking branch 'upstream/master' into ts-no-overwriting-xcconfig-value
This commit is contained in:
+33
-32
@@ -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)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Carthage
|
||||
+4
-2
@@ -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>
|
||||
@@ -0,0 +1 @@
|
||||
github "Alamofire/Alamofire"
|
||||
@@ -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 */;
|
||||
}
|
||||
-35
@@ -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 */;
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:TestProject.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public enum Platform: String {
|
||||
case .macOS:
|
||||
return "Mac"
|
||||
default:
|
||||
return self.rawValue
|
||||
return rawValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
+1
-1
@@ -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])
|
||||
+16
-70
@@ -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- ")
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-24
@@ -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 [:]
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -15,7 +15,7 @@ import ProjectSpec
|
||||
|
||||
public class ProjectGenerator {
|
||||
|
||||
var spec: ProjectSpec
|
||||
let spec: ProjectSpec
|
||||
let currentXcodeVersion = "0900"
|
||||
|
||||
public init(spec: ProjectSpec) {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
swiftformat Tests --stripunusedargs closure-only
|
||||
swiftformat sources --stripunusedargs closure-only
|
||||
Reference in New Issue
Block a user