├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── Makefile ├── README.md ├── SwiftPlate.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── SwiftPlate.xcscheme ├── Template ├── .gitignore ├── Configs │ ├── {PROJECT}.plist │ └── {PROJECT}Tests.plist ├── LICENSE ├── Package.swift ├── README.md ├── Sources │ └── {PROJECT}.swift ├── Tests │ ├── LinuxMain.swift │ └── {PROJECT}Tests │ │ └── {PROJECT}Tests.swift ├── {PROJECT}.podspec └── {PROJECT}.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ └── xcschemes │ ├── {PROJECT}-iOS.xcscheme │ ├── {PROJECT}-macOS.xcscheme │ ├── {PROJECT}-tvOS.xcscheme │ └── {PROJECT}-watchOS.xcscheme ├── main.swift ├── screenshot.png └── testStructure.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # SwiftPlate Code of Conduct 2 | 3 | Below is the Code of Conduct that all contributors and participants in the SwiftPlate community are expected to adhere to. 4 | It's adopted from the [Contributor Covenant Code of Conduct][homepage]. 5 | 6 | ## Our Pledge 7 | 8 | In the interest of fostering an open and welcoming environment, we as 9 | contributors and maintainers pledge to making participation in our project and 10 | our community a harassment-free experience for everyone, regardless of age, body 11 | size, disability, ethnicity, gender identity and expression, level of experience, 12 | nationality, personal appearance, race, religion, or sexual identity and 13 | orientation. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to creating a positive environment 18 | include: 19 | 20 | * Using welcoming and inclusive language 21 | * Being respectful of differing viewpoints and experiences 22 | * Gracefully accepting constructive criticism 23 | * Focusing on what is best for the community 24 | * Showing empathy towards other community members 25 | 26 | Examples of unacceptable behavior by participants include: 27 | 28 | * The use of sexualized language or imagery and unwelcome sexual attention or 29 | advances 30 | * Trolling, insulting/derogatory comments, and personal or political attacks 31 | * Public or private harassment 32 | * Publishing others' private information, such as a physical or electronic 33 | address, without explicit permission 34 | * Other conduct which could reasonably be considered inappropriate in a 35 | professional setting 36 | 37 | ## Our Responsibilities 38 | 39 | Project maintainers are responsible for clarifying the standards of acceptable 40 | behavior and are expected to take appropriate and fair corrective action in 41 | response to any instances of unacceptable behavior. 42 | 43 | Project maintainers have the right and responsibility to remove, edit, or 44 | reject comments, commits, code, wiki edits, issues, and other contributions 45 | that are not aligned to this Code of Conduct, or to ban temporarily or 46 | permanently any contributor for other behaviors that they deem inappropriate, 47 | threatening, offensive, or harmful. 48 | 49 | ## Scope 50 | 51 | This Code of Conduct applies both within project spaces and in public spaces 52 | when an individual is representing the project or its community. Examples of 53 | representing a project or community include using an official project e-mail 54 | address, posting via an official social media account, or acting as an appointed 55 | representative at an online or offline event. Representation of a project may be 56 | further defined and clarified by project maintainers. 57 | 58 | ## Enforcement 59 | 60 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 61 | reported by contacting the project leader at john@sundell.co. All 62 | complaints will be reviewed and investigated and will result in a response that 63 | is deemed necessary and appropriate to the circumstances. The project team is 64 | obligated to maintain confidentiality with regard to the reporter of an incident. 65 | Further details of specific enforcement policies may be posted separately. 66 | 67 | Project maintainers who do not follow or enforce the Code of Conduct in good 68 | faith may face temporary or permanent repercussions as determined by other 69 | members of the project's leadership. 70 | 71 | ## Attribution 72 | 73 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 74 | available at [http://contributor-covenant.org/version/1/4][version] 75 | 76 | [homepage]: http://contributor-covenant.org 77 | [version]: http://contributor-covenant.org/version/1/4/ 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 John Sundell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX?=/usr/local 2 | BUILD_TOOL?=xcodebuild 3 | BINARIES_FOLDER=/usr/local/bin 4 | 5 | EXECUTABLE_NAME = swiftplate 6 | XCODEFLAGS=-project 'SwiftPlate.xcodeproj' 7 | 8 | SWIFTPLATE_EXECUTABLE=./build/Release/$(EXECUTABLE_NAME) 9 | 10 | SWIFT_COMMAND=/usr/bin/swift 11 | SWIFT_BUILD_COMMAND=$(SWIFT_COMMAND) build 12 | SWIFT_TEST_COMMAND=$(SWIFT_COMMAND) test 13 | 14 | install: 15 | xcodebuild $(XCODEFLAGS) 16 | mkdir -p $(PREFIX)/bin 17 | cp -f $(SWIFTPLATE_EXECUTABLE) $(PREFIX)/bin 18 | 19 | uninstall: 20 | rm -f $(PREFIX)/bin/$(EXECUTABLE_NAME) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftPlate 2 | 3 | Easily generate cross platform Swift framework projects from the command line. 4 | 5 | SwiftPlate will generate Xcode projects for you in seconds, that support: 6 | 7 | - [x] CocoaPods 8 | - [x] Carthage 9 | - [x] Swift Package Manager 10 | - [x] iOS 11 | - [x] macOS 12 | - [x] watchOS 13 | - [x] tvOS 14 | - [x] Linux 15 | 16 | Just run `swiftplate`, and you’ll be presented with a simple step-by-step guide: 17 | 18 | Screenshot 19 | 20 | ## Usage 21 | 22 | ### Using [Homebrew](https://brew.sh) (recommended) 23 | 24 | ``` 25 | $ brew install swiftplate 26 | $ swiftplate 27 | ``` 28 | 29 | ### Using Make 30 | 31 | ``` 32 | $ git clone git@github.com:JohnSundell/SwiftPlate.git 33 | $ cd swiftplate 34 | $ make 35 | ``` 36 | 37 | ### Using [Marathon](https://github.com/johnsundell/marathon) 38 | 39 | ``` 40 | $ git clone git@github.com:JohnSundell/SwiftPlate.git 41 | $ marathon run swiftplate/main 42 | ``` 43 | 44 | ### Using the Swift interpreter directly 45 | 46 | ``` 47 | $ git clone git@github.com:JohnSundell/SwiftPlate.git 48 | $ swift swiftplate/main.swift 49 | ``` 50 | 51 | ### Using Xcode 52 | 53 | ``` 54 | $ git clone git@github.com:JohnSundell/SwiftPlate.git 55 | $ open swiftplate/SwiftPlate.xcodeproj 56 | ``` 57 | 58 | ## Command line arguments 59 | 60 | Besides using the guide to input information, SwiftPlate also supports command line arguments when launched. When a certain piece of information is supplied through an argument, SwiftPlate won't ask for that information when run. These are the arguments currently supported: 61 | 62 | 63 | | Name | Description | Long parameter | Short parameter | 64 | | ---- | ----------- | -------------- | --------------- | 65 | | Destination | Where the generated project should be saved | `--destination` | `-d` | 66 | | Project name | The name of your project | `--project` | `-p` | 67 | | Author name | Your name | `--name` | `-n` | 68 | | Author email | Your email (for Podspec) | `--email` | `-e` | 69 | | GitHub URL | Any URL you'll be hosting the project at (for Podspec) | `--url` | `-u` | 70 | | Organization name | The name of your organization | `--organization` | `-o` | 71 | | Repo | Any custom SwiftPlate repository that should be used for templates | `--repo` | `-r` | 72 | | Force | Prevent user prompt at the end (for CIs etc.) | `--force` | `-f` | 73 | 74 | ## Questions or feedback? 75 | 76 | Feel free to [open an issue](https://github.com/JohnSundell/SwiftPlate/issues/new), or find me [@johnsundell on Twitter](https://twitter.com/johnsundell). 77 | -------------------------------------------------------------------------------- /SwiftPlate.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 52CC95F51DE1DF51000B8859 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CC95F41DE1DF51000B8859 /* main.swift */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 52CC95E81DE1DF29000B8859 /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = /usr/share/man/man1/; 18 | dstSubfolderSpec = 0; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 1; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 52CC95EA1DE1DF29000B8859 /* swiftplate */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = swiftplate; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 52CC95F41DE1DF51000B8859 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; usesTabs = 0; }; 28 | /* End PBXFileReference section */ 29 | 30 | /* Begin PBXFrameworksBuildPhase section */ 31 | 52CC95E71DE1DF29000B8859 /* Frameworks */ = { 32 | isa = PBXFrameworksBuildPhase; 33 | buildActionMask = 2147483647; 34 | files = ( 35 | ); 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | /* End PBXFrameworksBuildPhase section */ 39 | 40 | /* Begin PBXGroup section */ 41 | 52CC95E11DE1DF29000B8859 = { 42 | isa = PBXGroup; 43 | children = ( 44 | 52CC95F41DE1DF51000B8859 /* main.swift */, 45 | 52CC95EB1DE1DF29000B8859 /* Products */, 46 | ); 47 | sourceTree = ""; 48 | }; 49 | 52CC95EB1DE1DF29000B8859 /* Products */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | 52CC95EA1DE1DF29000B8859 /* swiftplate */, 53 | ); 54 | name = Products; 55 | sourceTree = ""; 56 | }; 57 | /* End PBXGroup section */ 58 | 59 | /* Begin PBXNativeTarget section */ 60 | 52CC95E91DE1DF29000B8859 /* SwiftPlate */ = { 61 | isa = PBXNativeTarget; 62 | buildConfigurationList = 52CC95F11DE1DF29000B8859 /* Build configuration list for PBXNativeTarget "SwiftPlate" */; 63 | buildPhases = ( 64 | 52CC95E61DE1DF29000B8859 /* Sources */, 65 | 52CC95E71DE1DF29000B8859 /* Frameworks */, 66 | 52CC95E81DE1DF29000B8859 /* CopyFiles */, 67 | ); 68 | buildRules = ( 69 | ); 70 | dependencies = ( 71 | ); 72 | name = SwiftPlate; 73 | productName = SwiftPlate; 74 | productReference = 52CC95EA1DE1DF29000B8859 /* swiftplate */; 75 | productType = "com.apple.product-type.tool"; 76 | }; 77 | /* End PBXNativeTarget section */ 78 | 79 | /* Begin PBXProject section */ 80 | 52CC95E21DE1DF29000B8859 /* Project object */ = { 81 | isa = PBXProject; 82 | attributes = { 83 | LastSwiftUpdateCheck = 0810; 84 | LastUpgradeCheck = 1020; 85 | ORGANIZATIONNAME = "John Sundell"; 86 | TargetAttributes = { 87 | 52CC95E91DE1DF29000B8859 = { 88 | CreatedOnToolsVersion = 8.1; 89 | LastSwiftMigration = 0810; 90 | ProvisioningStyle = Automatic; 91 | }; 92 | }; 93 | }; 94 | buildConfigurationList = 52CC95E51DE1DF29000B8859 /* Build configuration list for PBXProject "SwiftPlate" */; 95 | compatibilityVersion = "Xcode 3.2"; 96 | developmentRegion = en; 97 | hasScannedForEncodings = 0; 98 | knownRegions = ( 99 | en, 100 | Base, 101 | ); 102 | mainGroup = 52CC95E11DE1DF29000B8859; 103 | productRefGroup = 52CC95EB1DE1DF29000B8859 /* Products */; 104 | projectDirPath = ""; 105 | projectRoot = ""; 106 | targets = ( 107 | 52CC95E91DE1DF29000B8859 /* SwiftPlate */, 108 | ); 109 | }; 110 | /* End PBXProject section */ 111 | 112 | /* Begin PBXSourcesBuildPhase section */ 113 | 52CC95E61DE1DF29000B8859 /* Sources */ = { 114 | isa = PBXSourcesBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | 52CC95F51DE1DF51000B8859 /* main.swift in Sources */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | /* End PBXSourcesBuildPhase section */ 122 | 123 | /* Begin XCBuildConfiguration section */ 124 | 52CC95EF1DE1DF29000B8859 /* Debug */ = { 125 | isa = XCBuildConfiguration; 126 | buildSettings = { 127 | ALWAYS_SEARCH_USER_PATHS = NO; 128 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 129 | CLANG_ANALYZER_NONNULL = YES; 130 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 131 | CLANG_CXX_LIBRARY = "libc++"; 132 | CLANG_ENABLE_MODULES = YES; 133 | CLANG_ENABLE_OBJC_ARC = YES; 134 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 135 | CLANG_WARN_BOOL_CONVERSION = YES; 136 | CLANG_WARN_COMMA = YES; 137 | CLANG_WARN_CONSTANT_CONVERSION = YES; 138 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 139 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 140 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 141 | CLANG_WARN_EMPTY_BODY = YES; 142 | CLANG_WARN_ENUM_CONVERSION = YES; 143 | CLANG_WARN_INFINITE_RECURSION = YES; 144 | CLANG_WARN_INT_CONVERSION = YES; 145 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 146 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 147 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 148 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 149 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 150 | CLANG_WARN_STRICT_PROTOTYPES = YES; 151 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 152 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 153 | CLANG_WARN_UNREACHABLE_CODE = YES; 154 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 155 | CODE_SIGN_IDENTITY = "-"; 156 | COPY_PHASE_STRIP = NO; 157 | DEBUG_INFORMATION_FORMAT = dwarf; 158 | ENABLE_STRICT_OBJC_MSGSEND = YES; 159 | ENABLE_TESTABILITY = YES; 160 | GCC_C_LANGUAGE_STANDARD = gnu99; 161 | GCC_DYNAMIC_NO_PIC = NO; 162 | GCC_NO_COMMON_BLOCKS = YES; 163 | GCC_OPTIMIZATION_LEVEL = 0; 164 | GCC_PREPROCESSOR_DEFINITIONS = ( 165 | "DEBUG=1", 166 | "$(inherited)", 167 | ); 168 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 169 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 170 | GCC_WARN_UNDECLARED_SELECTOR = YES; 171 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 172 | GCC_WARN_UNUSED_FUNCTION = YES; 173 | GCC_WARN_UNUSED_VARIABLE = YES; 174 | MACOSX_DEPLOYMENT_TARGET = 10.11; 175 | MTL_ENABLE_DEBUG_INFO = YES; 176 | ONLY_ACTIVE_ARCH = YES; 177 | SDKROOT = macosx; 178 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 179 | }; 180 | name = Debug; 181 | }; 182 | 52CC95F01DE1DF29000B8859 /* Release */ = { 183 | isa = XCBuildConfiguration; 184 | buildSettings = { 185 | ALWAYS_SEARCH_USER_PATHS = NO; 186 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 187 | CLANG_ANALYZER_NONNULL = YES; 188 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 189 | CLANG_CXX_LIBRARY = "libc++"; 190 | CLANG_ENABLE_MODULES = YES; 191 | CLANG_ENABLE_OBJC_ARC = YES; 192 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 193 | CLANG_WARN_BOOL_CONVERSION = YES; 194 | CLANG_WARN_COMMA = YES; 195 | CLANG_WARN_CONSTANT_CONVERSION = YES; 196 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 197 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 198 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 199 | CLANG_WARN_EMPTY_BODY = YES; 200 | CLANG_WARN_ENUM_CONVERSION = YES; 201 | CLANG_WARN_INFINITE_RECURSION = YES; 202 | CLANG_WARN_INT_CONVERSION = YES; 203 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 204 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 205 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 206 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 207 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 208 | CLANG_WARN_STRICT_PROTOTYPES = YES; 209 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 210 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 211 | CLANG_WARN_UNREACHABLE_CODE = YES; 212 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 213 | CODE_SIGN_IDENTITY = "-"; 214 | COPY_PHASE_STRIP = NO; 215 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 216 | ENABLE_NS_ASSERTIONS = NO; 217 | ENABLE_STRICT_OBJC_MSGSEND = YES; 218 | GCC_C_LANGUAGE_STANDARD = gnu99; 219 | GCC_NO_COMMON_BLOCKS = YES; 220 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 221 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 222 | GCC_WARN_UNDECLARED_SELECTOR = YES; 223 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 224 | GCC_WARN_UNUSED_FUNCTION = YES; 225 | GCC_WARN_UNUSED_VARIABLE = YES; 226 | MACOSX_DEPLOYMENT_TARGET = 10.11; 227 | MTL_ENABLE_DEBUG_INFO = NO; 228 | SDKROOT = macosx; 229 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 230 | }; 231 | name = Release; 232 | }; 233 | 52CC95F21DE1DF29000B8859 /* Debug */ = { 234 | isa = XCBuildConfiguration; 235 | buildSettings = { 236 | CLANG_ENABLE_MODULES = YES; 237 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 238 | PRODUCT_NAME = swiftplate; 239 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 240 | SWIFT_VERSION = 5.0; 241 | }; 242 | name = Debug; 243 | }; 244 | 52CC95F31DE1DF29000B8859 /* Release */ = { 245 | isa = XCBuildConfiguration; 246 | buildSettings = { 247 | CLANG_ENABLE_MODULES = YES; 248 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 249 | PRODUCT_NAME = swiftplate; 250 | SWIFT_VERSION = 5.0; 251 | }; 252 | name = Release; 253 | }; 254 | /* End XCBuildConfiguration section */ 255 | 256 | /* Begin XCConfigurationList section */ 257 | 52CC95E51DE1DF29000B8859 /* Build configuration list for PBXProject "SwiftPlate" */ = { 258 | isa = XCConfigurationList; 259 | buildConfigurations = ( 260 | 52CC95EF1DE1DF29000B8859 /* Debug */, 261 | 52CC95F01DE1DF29000B8859 /* Release */, 262 | ); 263 | defaultConfigurationIsVisible = 0; 264 | defaultConfigurationName = Release; 265 | }; 266 | 52CC95F11DE1DF29000B8859 /* Build configuration list for PBXNativeTarget "SwiftPlate" */ = { 267 | isa = XCConfigurationList; 268 | buildConfigurations = ( 269 | 52CC95F21DE1DF29000B8859 /* Debug */, 270 | 52CC95F31DE1DF29000B8859 /* Release */, 271 | ); 272 | defaultConfigurationIsVisible = 0; 273 | defaultConfigurationName = Release; 274 | }; 275 | /* End XCConfigurationList section */ 276 | }; 277 | rootObject = 52CC95E21DE1DF29000B8859 /* Project object */; 278 | } 279 | -------------------------------------------------------------------------------- /SwiftPlate.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftPlate.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftPlate.xcodeproj/xcshareddata/xcschemes/SwiftPlate.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Template/.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | # Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | # Carthage/Checkouts 54 | 55 | Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots 67 | fastlane/test_output 68 | -------------------------------------------------------------------------------- /Template/Configs/{PROJECT}.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © {YEAR} {AUTHOR}. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Template/Configs/{PROJECT}Tests.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Template/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) {YEAR} {AUTHOR} 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Template/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "{PROJECT}", 8 | products: [ 9 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 10 | .library( 11 | name: "{PROJECT}", 12 | targets: ["{PROJECT}"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 21 | .target( 22 | name: "{PROJECT}", 23 | dependencies: []), 24 | .testTarget( 25 | name: "{PROJECT}Tests", 26 | dependencies: ["{PROJECT}"]), 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Template/README.md: -------------------------------------------------------------------------------- 1 | # {PROJECT} -------------------------------------------------------------------------------- /Template/Sources/{PROJECT}.swift: -------------------------------------------------------------------------------- 1 | // 2 | // {PROJECT}.swift 3 | // {ORGANIZATION} 4 | // 5 | // Created by {AUTHOR} on {TODAY}. 6 | // Copyright © {YEAR} {ORGANIZATION}. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /Template/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import {PROJECT}Tests 3 | 4 | XCTMain([ 5 | testCase({PROJECT}Tests.allTests), 6 | ]) 7 | -------------------------------------------------------------------------------- /Template/Tests/{PROJECT}Tests/{PROJECT}Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // {PROJECT}Tests.swift 3 | // {ORGANIZATION} 4 | // 5 | // Created by {AUTHOR} on {TODAY}. 6 | // Copyright © {YEAR} {ORGANIZATION}. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import {PROJECT} 12 | 13 | class {PROJECT}Tests: XCTestCase { 14 | func testExample() { 15 | // This is an example of a functional test case. 16 | // Use XCTAssert and related functions to verify your tests produce the correct results. 17 | //// XCTAssertEqual({PROJECT}().text, "Hello, World!") 18 | } 19 | 20 | static var allTests = [ 21 | ("testExample", testExample), 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /Template/{PROJECT}.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "{PROJECT}" 3 | s.version = "0.1" 4 | s.summary = "" 5 | s.description = <<-DESC 6 | Your description here. 7 | DESC 8 | s.homepage = "{URL}" 9 | s.license = { :type => "MIT", :file => "LICENSE" } 10 | s.author = { "{AUTHOR}" => "{EMAIL}" } 11 | s.social_media_url = "" 12 | s.ios.deployment_target = "8.0" 13 | s.osx.deployment_target = "10.9" 14 | s.watchos.deployment_target = "2.0" 15 | s.tvos.deployment_target = "9.0" 16 | s.source = { :git => "{URL}.git", :tag => s.version.to_s } 17 | s.source_files = "Sources/**/*" 18 | s.frameworks = "Foundation" 19 | end 20 | -------------------------------------------------------------------------------- /Template/{PROJECT}.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 47; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 52D6D9871BEFF229002C0205 /* {PROJECT}.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* {PROJECT}.framework */; }; 11 | 8933C7851EB5B820000D00A4 /* {PROJECT}.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* {PROJECT}.swift */; }; 12 | 8933C7861EB5B820000D00A4 /* {PROJECT}.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* {PROJECT}.swift */; }; 13 | 8933C7871EB5B820000D00A4 /* {PROJECT}.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* {PROJECT}.swift */; }; 14 | 8933C7881EB5B820000D00A4 /* {PROJECT}.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* {PROJECT}.swift */; }; 15 | 8933C78E1EB5B82C000D00A4 /* {PROJECT}Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7891EB5B82A000D00A4 /* {PROJECT}Tests.swift */; }; 16 | 8933C78F1EB5B82C000D00A4 /* {PROJECT}Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7891EB5B82A000D00A4 /* {PROJECT}Tests.swift */; }; 17 | 8933C7901EB5B82D000D00A4 /* {PROJECT}Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7891EB5B82A000D00A4 /* {PROJECT}Tests.swift */; }; 18 | DD7502881C68FEDE006590AF /* {PROJECT}.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6DA0F1BF000BD002C0205 /* {PROJECT}.framework */; }; 19 | DD7502921C690C7A006590AF /* {PROJECT}.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D9F01BEFFFBE002C0205 /* {PROJECT}.framework */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 52D6D9881BEFF229002C0205 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 52D6D97B1BEFF229002C0205; 28 | remoteInfo = {PROJECT}; 29 | }; 30 | DD7502801C68FCFC006590AF /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 52D6DA0E1BF000BD002C0205; 35 | remoteInfo = "{PROJECT}-macOS"; 36 | }; 37 | DD7502931C690C7A006590AF /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 52D6D9EF1BEFFFBE002C0205; 42 | remoteInfo = "{PROJECT}-tvOS"; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 52D6D97C1BEFF229002C0205 /* {PROJECT}.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = {PROJECT}.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 52D6D9861BEFF229002C0205 /* {PROJECT}-iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "{PROJECT}-iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 52D6D9E21BEFFF6E002C0205 /* {PROJECT}.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = {PROJECT}.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 52D6D9F01BEFFFBE002C0205 /* {PROJECT}.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = {PROJECT}.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 52D6DA0F1BF000BD002C0205 /* {PROJECT}.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = {PROJECT}.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 8933C7841EB5B820000D00A4 /* {PROJECT}.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = {PROJECT}.swift; sourceTree = ""; }; 53 | 8933C7891EB5B82A000D00A4 /* {PROJECT}Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = {PROJECT}Tests.swift; sourceTree = ""; }; 54 | AD2FAA261CD0B6D800659CF4 /* {PROJECT}.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = {PROJECT}.plist; sourceTree = ""; }; 55 | AD2FAA281CD0B6E100659CF4 /* {PROJECT}Tests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = {PROJECT}Tests.plist; sourceTree = ""; }; 56 | DD75027A1C68FCFC006590AF /* {PROJECT}-macOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "{PROJECT}-macOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | DD75028D1C690C7A006590AF /* {PROJECT}-tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "{PROJECT}-tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 52D6D9781BEFF229002C0205 /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | 52D6D9831BEFF229002C0205 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | 52D6D9871BEFF229002C0205 /* {PROJECT}.framework in Frameworks */, 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | 52D6D9DE1BEFFF6E002C0205 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | 52D6D9EC1BEFFFBE002C0205 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | 52D6DA0B1BF000BD002C0205 /* Frameworks */ = { 91 | isa = PBXFrameworksBuildPhase; 92 | buildActionMask = 2147483647; 93 | files = ( 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | DD7502771C68FCFC006590AF /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | DD7502881C68FEDE006590AF /* {PROJECT}.framework in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | DD75028A1C690C7A006590AF /* Frameworks */ = { 106 | isa = PBXFrameworksBuildPhase; 107 | buildActionMask = 2147483647; 108 | files = ( 109 | DD7502921C690C7A006590AF /* {PROJECT}.framework in Frameworks */, 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | /* End PBXFrameworksBuildPhase section */ 114 | 115 | /* Begin PBXGroup section */ 116 | 52D6D9721BEFF229002C0205 = { 117 | isa = PBXGroup; 118 | children = ( 119 | 8933C7811EB5B7E0000D00A4 /* Sources */, 120 | 8933C7831EB5B7EB000D00A4 /* Tests */, 121 | 52D6D99C1BEFF38C002C0205 /* Configs */, 122 | 52D6D97D1BEFF229002C0205 /* Products */, 123 | ); 124 | sourceTree = ""; 125 | }; 126 | 52D6D97D1BEFF229002C0205 /* Products */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 52D6D97C1BEFF229002C0205 /* {PROJECT}.framework */, 130 | 52D6D9861BEFF229002C0205 /* {PROJECT}-iOS Tests.xctest */, 131 | 52D6D9E21BEFFF6E002C0205 /* {PROJECT}.framework */, 132 | 52D6D9F01BEFFFBE002C0205 /* {PROJECT}.framework */, 133 | 52D6DA0F1BF000BD002C0205 /* {PROJECT}.framework */, 134 | DD75027A1C68FCFC006590AF /* {PROJECT}-macOS Tests.xctest */, 135 | DD75028D1C690C7A006590AF /* {PROJECT}-tvOS Tests.xctest */, 136 | ); 137 | name = Products; 138 | sourceTree = ""; 139 | }; 140 | 52D6D99C1BEFF38C002C0205 /* Configs */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | DD7502721C68FC1B006590AF /* Frameworks */, 144 | DD7502731C68FC20006590AF /* Tests */, 145 | ); 146 | path = Configs; 147 | sourceTree = ""; 148 | }; 149 | 8933C7811EB5B7E0000D00A4 /* Sources */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 8933C7841EB5B820000D00A4 /* {PROJECT}.swift */, 153 | ); 154 | path = Sources; 155 | sourceTree = ""; 156 | }; 157 | 8933C7831EB5B7EB000D00A4 /* Tests */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 8933C7891EB5B82A000D00A4 /* {PROJECT}Tests.swift */, 161 | ); 162 | name = Tests; 163 | path = Tests/{PROJECT}Tests; 164 | sourceTree = ""; 165 | }; 166 | DD7502721C68FC1B006590AF /* Frameworks */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | AD2FAA261CD0B6D800659CF4 /* {PROJECT}.plist */, 170 | ); 171 | name = Frameworks; 172 | sourceTree = ""; 173 | }; 174 | DD7502731C68FC20006590AF /* Tests */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | AD2FAA281CD0B6E100659CF4 /* {PROJECT}Tests.plist */, 178 | ); 179 | name = Tests; 180 | sourceTree = ""; 181 | }; 182 | /* End PBXGroup section */ 183 | 184 | /* Begin PBXHeadersBuildPhase section */ 185 | 52D6D9791BEFF229002C0205 /* Headers */ = { 186 | isa = PBXHeadersBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | 52D6D9DF1BEFFF6E002C0205 /* Headers */ = { 193 | isa = PBXHeadersBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | }; 199 | 52D6D9ED1BEFFFBE002C0205 /* Headers */ = { 200 | isa = PBXHeadersBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | }; 206 | 52D6DA0C1BF000BD002C0205 /* Headers */ = { 207 | isa = PBXHeadersBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | /* End PBXHeadersBuildPhase section */ 214 | 215 | /* Begin PBXNativeTarget section */ 216 | 52D6D97B1BEFF229002C0205 /* {PROJECT}-iOS */ = { 217 | isa = PBXNativeTarget; 218 | buildConfigurationList = 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-iOS" */; 219 | buildPhases = ( 220 | 52D6D9771BEFF229002C0205 /* Sources */, 221 | 52D6D9781BEFF229002C0205 /* Frameworks */, 222 | 52D6D9791BEFF229002C0205 /* Headers */, 223 | 52D6D97A1BEFF229002C0205 /* Resources */, 224 | ); 225 | buildRules = ( 226 | ); 227 | dependencies = ( 228 | ); 229 | name = "{PROJECT}-iOS"; 230 | productName = {PROJECT}; 231 | productReference = 52D6D97C1BEFF229002C0205 /* {PROJECT}.framework */; 232 | productType = "com.apple.product-type.framework"; 233 | }; 234 | 52D6D9851BEFF229002C0205 /* {PROJECT}-iOS Tests */ = { 235 | isa = PBXNativeTarget; 236 | buildConfigurationList = 52D6D9931BEFF229002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-iOS Tests" */; 237 | buildPhases = ( 238 | 52D6D9821BEFF229002C0205 /* Sources */, 239 | 52D6D9831BEFF229002C0205 /* Frameworks */, 240 | 52D6D9841BEFF229002C0205 /* Resources */, 241 | ); 242 | buildRules = ( 243 | ); 244 | dependencies = ( 245 | 52D6D9891BEFF229002C0205 /* PBXTargetDependency */, 246 | ); 247 | name = "{PROJECT}-iOS Tests"; 248 | productName = {PROJECT}Tests; 249 | productReference = 52D6D9861BEFF229002C0205 /* {PROJECT}-iOS Tests.xctest */; 250 | productType = "com.apple.product-type.bundle.unit-test"; 251 | }; 252 | 52D6D9E11BEFFF6E002C0205 /* {PROJECT}-watchOS */ = { 253 | isa = PBXNativeTarget; 254 | buildConfigurationList = 52D6D9E71BEFFF6E002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-watchOS" */; 255 | buildPhases = ( 256 | 52D6D9DD1BEFFF6E002C0205 /* Sources */, 257 | 52D6D9DE1BEFFF6E002C0205 /* Frameworks */, 258 | 52D6D9DF1BEFFF6E002C0205 /* Headers */, 259 | 52D6D9E01BEFFF6E002C0205 /* Resources */, 260 | ); 261 | buildRules = ( 262 | ); 263 | dependencies = ( 264 | ); 265 | name = "{PROJECT}-watchOS"; 266 | productName = "{PROJECT}-watchOS"; 267 | productReference = 52D6D9E21BEFFF6E002C0205 /* {PROJECT}.framework */; 268 | productType = "com.apple.product-type.framework"; 269 | }; 270 | 52D6D9EF1BEFFFBE002C0205 /* {PROJECT}-tvOS */ = { 271 | isa = PBXNativeTarget; 272 | buildConfigurationList = 52D6DA011BEFFFBE002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-tvOS" */; 273 | buildPhases = ( 274 | 52D6D9EB1BEFFFBE002C0205 /* Sources */, 275 | 52D6D9EC1BEFFFBE002C0205 /* Frameworks */, 276 | 52D6D9ED1BEFFFBE002C0205 /* Headers */, 277 | 52D6D9EE1BEFFFBE002C0205 /* Resources */, 278 | ); 279 | buildRules = ( 280 | ); 281 | dependencies = ( 282 | ); 283 | name = "{PROJECT}-tvOS"; 284 | productName = "{PROJECT}-tvOS"; 285 | productReference = 52D6D9F01BEFFFBE002C0205 /* {PROJECT}.framework */; 286 | productType = "com.apple.product-type.framework"; 287 | }; 288 | 52D6DA0E1BF000BD002C0205 /* {PROJECT}-macOS */ = { 289 | isa = PBXNativeTarget; 290 | buildConfigurationList = 52D6DA201BF000BD002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-macOS" */; 291 | buildPhases = ( 292 | 52D6DA0A1BF000BD002C0205 /* Sources */, 293 | 52D6DA0B1BF000BD002C0205 /* Frameworks */, 294 | 52D6DA0C1BF000BD002C0205 /* Headers */, 295 | 52D6DA0D1BF000BD002C0205 /* Resources */, 296 | ); 297 | buildRules = ( 298 | ); 299 | dependencies = ( 300 | ); 301 | name = "{PROJECT}-macOS"; 302 | productName = "{PROJECT}-macOS"; 303 | productReference = 52D6DA0F1BF000BD002C0205 /* {PROJECT}.framework */; 304 | productType = "com.apple.product-type.framework"; 305 | }; 306 | DD7502791C68FCFC006590AF /* {PROJECT}-macOS Tests */ = { 307 | isa = PBXNativeTarget; 308 | buildConfigurationList = DD7502821C68FCFC006590AF /* Build configuration list for PBXNativeTarget "{PROJECT}-macOS Tests" */; 309 | buildPhases = ( 310 | DD7502761C68FCFC006590AF /* Sources */, 311 | DD7502771C68FCFC006590AF /* Frameworks */, 312 | DD7502781C68FCFC006590AF /* Resources */, 313 | ); 314 | buildRules = ( 315 | ); 316 | dependencies = ( 317 | DD7502811C68FCFC006590AF /* PBXTargetDependency */, 318 | ); 319 | name = "{PROJECT}-macOS Tests"; 320 | productName = "{PROJECT}-OS Tests"; 321 | productReference = DD75027A1C68FCFC006590AF /* {PROJECT}-macOS Tests.xctest */; 322 | productType = "com.apple.product-type.bundle.unit-test"; 323 | }; 324 | DD75028C1C690C7A006590AF /* {PROJECT}-tvOS Tests */ = { 325 | isa = PBXNativeTarget; 326 | buildConfigurationList = DD7502951C690C7A006590AF /* Build configuration list for PBXNativeTarget "{PROJECT}-tvOS Tests" */; 327 | buildPhases = ( 328 | DD7502891C690C7A006590AF /* Sources */, 329 | DD75028A1C690C7A006590AF /* Frameworks */, 330 | DD75028B1C690C7A006590AF /* Resources */, 331 | ); 332 | buildRules = ( 333 | ); 334 | dependencies = ( 335 | DD7502941C690C7A006590AF /* PBXTargetDependency */, 336 | ); 337 | name = "{PROJECT}-tvOS Tests"; 338 | productName = "{PROJECT}-tvOS Tests"; 339 | productReference = DD75028D1C690C7A006590AF /* {PROJECT}-tvOS Tests.xctest */; 340 | productType = "com.apple.product-type.bundle.unit-test"; 341 | }; 342 | /* End PBXNativeTarget section */ 343 | 344 | /* Begin PBXProject section */ 345 | 52D6D9731BEFF229002C0205 /* Project object */ = { 346 | isa = PBXProject; 347 | attributes = { 348 | LastSwiftUpdateCheck = 0720; 349 | LastUpgradeCheck = 1020; 350 | ORGANIZATIONNAME = {ORGANIZATION}; 351 | TargetAttributes = { 352 | 52D6D97B1BEFF229002C0205 = { 353 | CreatedOnToolsVersion = 7.1; 354 | LastSwiftMigration = 1020; 355 | }; 356 | 52D6D9851BEFF229002C0205 = { 357 | CreatedOnToolsVersion = 7.1; 358 | LastSwiftMigration = 1020; 359 | }; 360 | 52D6D9E11BEFFF6E002C0205 = { 361 | CreatedOnToolsVersion = 7.1; 362 | LastSwiftMigration = 1020; 363 | }; 364 | 52D6D9EF1BEFFFBE002C0205 = { 365 | CreatedOnToolsVersion = 7.1; 366 | LastSwiftMigration = 1020; 367 | }; 368 | 52D6DA0E1BF000BD002C0205 = { 369 | CreatedOnToolsVersion = 7.1; 370 | LastSwiftMigration = 1020; 371 | }; 372 | DD7502791C68FCFC006590AF = { 373 | CreatedOnToolsVersion = 7.2.1; 374 | LastSwiftMigration = 1020; 375 | }; 376 | DD75028C1C690C7A006590AF = { 377 | CreatedOnToolsVersion = 7.2.1; 378 | LastSwiftMigration = 1020; 379 | }; 380 | }; 381 | }; 382 | buildConfigurationList = 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "{PROJECT}" */; 383 | compatibilityVersion = "Xcode 6.3"; 384 | developmentRegion = en; 385 | hasScannedForEncodings = 0; 386 | knownRegions = ( 387 | en, 388 | Base, 389 | ); 390 | mainGroup = 52D6D9721BEFF229002C0205; 391 | productRefGroup = 52D6D97D1BEFF229002C0205 /* Products */; 392 | projectDirPath = ""; 393 | projectRoot = ""; 394 | targets = ( 395 | 52D6D97B1BEFF229002C0205 /* {PROJECT}-iOS */, 396 | 52D6DA0E1BF000BD002C0205 /* {PROJECT}-macOS */, 397 | 52D6D9E11BEFFF6E002C0205 /* {PROJECT}-watchOS */, 398 | 52D6D9EF1BEFFFBE002C0205 /* {PROJECT}-tvOS */, 399 | 52D6D9851BEFF229002C0205 /* {PROJECT}-iOS Tests */, 400 | DD7502791C68FCFC006590AF /* {PROJECT}-macOS Tests */, 401 | DD75028C1C690C7A006590AF /* {PROJECT}-tvOS Tests */, 402 | ); 403 | }; 404 | /* End PBXProject section */ 405 | 406 | /* Begin PBXResourcesBuildPhase section */ 407 | 52D6D97A1BEFF229002C0205 /* Resources */ = { 408 | isa = PBXResourcesBuildPhase; 409 | buildActionMask = 2147483647; 410 | files = ( 411 | ); 412 | runOnlyForDeploymentPostprocessing = 0; 413 | }; 414 | 52D6D9841BEFF229002C0205 /* Resources */ = { 415 | isa = PBXResourcesBuildPhase; 416 | buildActionMask = 2147483647; 417 | files = ( 418 | ); 419 | runOnlyForDeploymentPostprocessing = 0; 420 | }; 421 | 52D6D9E01BEFFF6E002C0205 /* Resources */ = { 422 | isa = PBXResourcesBuildPhase; 423 | buildActionMask = 2147483647; 424 | files = ( 425 | ); 426 | runOnlyForDeploymentPostprocessing = 0; 427 | }; 428 | 52D6D9EE1BEFFFBE002C0205 /* Resources */ = { 429 | isa = PBXResourcesBuildPhase; 430 | buildActionMask = 2147483647; 431 | files = ( 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | }; 435 | 52D6DA0D1BF000BD002C0205 /* Resources */ = { 436 | isa = PBXResourcesBuildPhase; 437 | buildActionMask = 2147483647; 438 | files = ( 439 | ); 440 | runOnlyForDeploymentPostprocessing = 0; 441 | }; 442 | DD7502781C68FCFC006590AF /* Resources */ = { 443 | isa = PBXResourcesBuildPhase; 444 | buildActionMask = 2147483647; 445 | files = ( 446 | ); 447 | runOnlyForDeploymentPostprocessing = 0; 448 | }; 449 | DD75028B1C690C7A006590AF /* Resources */ = { 450 | isa = PBXResourcesBuildPhase; 451 | buildActionMask = 2147483647; 452 | files = ( 453 | ); 454 | runOnlyForDeploymentPostprocessing = 0; 455 | }; 456 | /* End PBXResourcesBuildPhase section */ 457 | 458 | /* Begin PBXSourcesBuildPhase section */ 459 | 52D6D9771BEFF229002C0205 /* Sources */ = { 460 | isa = PBXSourcesBuildPhase; 461 | buildActionMask = 2147483647; 462 | files = ( 463 | 8933C7851EB5B820000D00A4 /* {PROJECT}.swift in Sources */, 464 | ); 465 | runOnlyForDeploymentPostprocessing = 0; 466 | }; 467 | 52D6D9821BEFF229002C0205 /* Sources */ = { 468 | isa = PBXSourcesBuildPhase; 469 | buildActionMask = 2147483647; 470 | files = ( 471 | 8933C7901EB5B82D000D00A4 /* {PROJECT}Tests.swift in Sources */, 472 | ); 473 | runOnlyForDeploymentPostprocessing = 0; 474 | }; 475 | 52D6D9DD1BEFFF6E002C0205 /* Sources */ = { 476 | isa = PBXSourcesBuildPhase; 477 | buildActionMask = 2147483647; 478 | files = ( 479 | 8933C7871EB5B820000D00A4 /* {PROJECT}.swift in Sources */, 480 | ); 481 | runOnlyForDeploymentPostprocessing = 0; 482 | }; 483 | 52D6D9EB1BEFFFBE002C0205 /* Sources */ = { 484 | isa = PBXSourcesBuildPhase; 485 | buildActionMask = 2147483647; 486 | files = ( 487 | 8933C7881EB5B820000D00A4 /* {PROJECT}.swift in Sources */, 488 | ); 489 | runOnlyForDeploymentPostprocessing = 0; 490 | }; 491 | 52D6DA0A1BF000BD002C0205 /* Sources */ = { 492 | isa = PBXSourcesBuildPhase; 493 | buildActionMask = 2147483647; 494 | files = ( 495 | 8933C7861EB5B820000D00A4 /* {PROJECT}.swift in Sources */, 496 | ); 497 | runOnlyForDeploymentPostprocessing = 0; 498 | }; 499 | DD7502761C68FCFC006590AF /* Sources */ = { 500 | isa = PBXSourcesBuildPhase; 501 | buildActionMask = 2147483647; 502 | files = ( 503 | 8933C78F1EB5B82C000D00A4 /* {PROJECT}Tests.swift in Sources */, 504 | ); 505 | runOnlyForDeploymentPostprocessing = 0; 506 | }; 507 | DD7502891C690C7A006590AF /* Sources */ = { 508 | isa = PBXSourcesBuildPhase; 509 | buildActionMask = 2147483647; 510 | files = ( 511 | 8933C78E1EB5B82C000D00A4 /* {PROJECT}Tests.swift in Sources */, 512 | ); 513 | runOnlyForDeploymentPostprocessing = 0; 514 | }; 515 | /* End PBXSourcesBuildPhase section */ 516 | 517 | /* Begin PBXTargetDependency section */ 518 | 52D6D9891BEFF229002C0205 /* PBXTargetDependency */ = { 519 | isa = PBXTargetDependency; 520 | target = 52D6D97B1BEFF229002C0205 /* {PROJECT}-iOS */; 521 | targetProxy = 52D6D9881BEFF229002C0205 /* PBXContainerItemProxy */; 522 | }; 523 | DD7502811C68FCFC006590AF /* PBXTargetDependency */ = { 524 | isa = PBXTargetDependency; 525 | target = 52D6DA0E1BF000BD002C0205 /* {PROJECT}-macOS */; 526 | targetProxy = DD7502801C68FCFC006590AF /* PBXContainerItemProxy */; 527 | }; 528 | DD7502941C690C7A006590AF /* PBXTargetDependency */ = { 529 | isa = PBXTargetDependency; 530 | target = 52D6D9EF1BEFFFBE002C0205 /* {PROJECT}-tvOS */; 531 | targetProxy = DD7502931C690C7A006590AF /* PBXContainerItemProxy */; 532 | }; 533 | /* End PBXTargetDependency section */ 534 | 535 | /* Begin XCBuildConfiguration section */ 536 | 52D6D98E1BEFF229002C0205 /* Debug */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | ALWAYS_SEARCH_USER_PATHS = NO; 540 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 541 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 542 | CLANG_CXX_LIBRARY = "libc++"; 543 | CLANG_ENABLE_MODULES = YES; 544 | CLANG_ENABLE_OBJC_ARC = YES; 545 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 546 | CLANG_WARN_BOOL_CONVERSION = YES; 547 | CLANG_WARN_COMMA = YES; 548 | CLANG_WARN_CONSTANT_CONVERSION = YES; 549 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 551 | CLANG_WARN_EMPTY_BODY = YES; 552 | CLANG_WARN_ENUM_CONVERSION = YES; 553 | CLANG_WARN_INFINITE_RECURSION = YES; 554 | CLANG_WARN_INT_CONVERSION = YES; 555 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 556 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 557 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 558 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 559 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 560 | CLANG_WARN_STRICT_PROTOTYPES = YES; 561 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 562 | CLANG_WARN_UNREACHABLE_CODE = YES; 563 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 564 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 565 | COPY_PHASE_STRIP = NO; 566 | CURRENT_PROJECT_VERSION = 1; 567 | DEBUG_INFORMATION_FORMAT = dwarf; 568 | ENABLE_STRICT_OBJC_MSGSEND = YES; 569 | ENABLE_TESTABILITY = YES; 570 | GCC_C_LANGUAGE_STANDARD = gnu99; 571 | GCC_DYNAMIC_NO_PIC = NO; 572 | GCC_NO_COMMON_BLOCKS = YES; 573 | GCC_OPTIMIZATION_LEVEL = 0; 574 | GCC_PREPROCESSOR_DEFINITIONS = ( 575 | "DEBUG=1", 576 | "$(inherited)", 577 | ); 578 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 579 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 580 | GCC_WARN_UNDECLARED_SELECTOR = YES; 581 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 582 | GCC_WARN_UNUSED_FUNCTION = YES; 583 | GCC_WARN_UNUSED_VARIABLE = YES; 584 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 585 | MTL_ENABLE_DEBUG_INFO = YES; 586 | ONLY_ACTIVE_ARCH = YES; 587 | SDKROOT = iphoneos; 588 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 589 | SWIFT_VERSION = 5.0; 590 | TARGETED_DEVICE_FAMILY = "1,2"; 591 | VERSIONING_SYSTEM = "apple-generic"; 592 | VERSION_INFO_PREFIX = ""; 593 | }; 594 | name = Debug; 595 | }; 596 | 52D6D98F1BEFF229002C0205 /* Release */ = { 597 | isa = XCBuildConfiguration; 598 | buildSettings = { 599 | ALWAYS_SEARCH_USER_PATHS = NO; 600 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 601 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 602 | CLANG_CXX_LIBRARY = "libc++"; 603 | CLANG_ENABLE_MODULES = YES; 604 | CLANG_ENABLE_OBJC_ARC = YES; 605 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 606 | CLANG_WARN_BOOL_CONVERSION = YES; 607 | CLANG_WARN_COMMA = YES; 608 | CLANG_WARN_CONSTANT_CONVERSION = YES; 609 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 610 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 611 | CLANG_WARN_EMPTY_BODY = YES; 612 | CLANG_WARN_ENUM_CONVERSION = YES; 613 | CLANG_WARN_INFINITE_RECURSION = YES; 614 | CLANG_WARN_INT_CONVERSION = YES; 615 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 616 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 617 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 618 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 619 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 620 | CLANG_WARN_STRICT_PROTOTYPES = YES; 621 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 622 | CLANG_WARN_UNREACHABLE_CODE = YES; 623 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 624 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 625 | COPY_PHASE_STRIP = NO; 626 | CURRENT_PROJECT_VERSION = 1; 627 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 628 | ENABLE_NS_ASSERTIONS = NO; 629 | ENABLE_STRICT_OBJC_MSGSEND = YES; 630 | GCC_C_LANGUAGE_STANDARD = gnu99; 631 | GCC_NO_COMMON_BLOCKS = YES; 632 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 633 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 634 | GCC_WARN_UNDECLARED_SELECTOR = YES; 635 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 636 | GCC_WARN_UNUSED_FUNCTION = YES; 637 | GCC_WARN_UNUSED_VARIABLE = YES; 638 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 639 | MTL_ENABLE_DEBUG_INFO = NO; 640 | SDKROOT = iphoneos; 641 | SWIFT_VERSION = 5.0; 642 | TARGETED_DEVICE_FAMILY = "1,2"; 643 | VALIDATE_PRODUCT = YES; 644 | VERSIONING_SYSTEM = "apple-generic"; 645 | VERSION_INFO_PREFIX = ""; 646 | }; 647 | name = Release; 648 | }; 649 | 52D6D9911BEFF229002C0205 /* Debug */ = { 650 | isa = XCBuildConfiguration; 651 | buildSettings = { 652 | APPLICATION_EXTENSION_API_ONLY = YES; 653 | CLANG_ENABLE_MODULES = YES; 654 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 655 | DEFINES_MODULE = YES; 656 | DYLIB_COMPATIBILITY_VERSION = 1; 657 | DYLIB_CURRENT_VERSION = 1; 658 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 659 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 660 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 661 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 662 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 663 | ONLY_ACTIVE_ARCH = NO; 664 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-iOS"; 665 | PRODUCT_NAME = {PROJECT}; 666 | SKIP_INSTALL = YES; 667 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 668 | SWIFT_VERSION = 5.0; 669 | }; 670 | name = Debug; 671 | }; 672 | 52D6D9921BEFF229002C0205 /* Release */ = { 673 | isa = XCBuildConfiguration; 674 | buildSettings = { 675 | APPLICATION_EXTENSION_API_ONLY = YES; 676 | CLANG_ENABLE_MODULES = YES; 677 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 678 | DEFINES_MODULE = YES; 679 | DYLIB_COMPATIBILITY_VERSION = 1; 680 | DYLIB_CURRENT_VERSION = 1; 681 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 682 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 683 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 684 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 685 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 686 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-iOS"; 687 | PRODUCT_NAME = {PROJECT}; 688 | SKIP_INSTALL = YES; 689 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 690 | SWIFT_VERSION = 5.0; 691 | }; 692 | name = Release; 693 | }; 694 | 52D6D9941BEFF229002C0205 /* Debug */ = { 695 | isa = XCBuildConfiguration; 696 | buildSettings = { 697 | CLANG_ENABLE_MODULES = YES; 698 | INFOPLIST_FILE = Configs/{PROJECT}Tests.plist; 699 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 700 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-iOS-Tests"; 701 | PRODUCT_NAME = "$(TARGET_NAME)"; 702 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 703 | SWIFT_VERSION = 5.0; 704 | }; 705 | name = Debug; 706 | }; 707 | 52D6D9951BEFF229002C0205 /* Release */ = { 708 | isa = XCBuildConfiguration; 709 | buildSettings = { 710 | CLANG_ENABLE_MODULES = YES; 711 | INFOPLIST_FILE = Configs/{PROJECT}Tests.plist; 712 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 713 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-iOS-Tests"; 714 | PRODUCT_NAME = "$(TARGET_NAME)"; 715 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 716 | SWIFT_VERSION = 5.0; 717 | }; 718 | name = Release; 719 | }; 720 | 52D6D9E81BEFFF6E002C0205 /* Debug */ = { 721 | isa = XCBuildConfiguration; 722 | buildSettings = { 723 | APPLICATION_EXTENSION_API_ONLY = YES; 724 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 725 | DEFINES_MODULE = YES; 726 | DYLIB_COMPATIBILITY_VERSION = 1; 727 | DYLIB_CURRENT_VERSION = 1; 728 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 729 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 730 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 731 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 732 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-watchOS"; 733 | PRODUCT_NAME = {PROJECT}; 734 | SDKROOT = watchos; 735 | SKIP_INSTALL = YES; 736 | SWIFT_VERSION = 5.0; 737 | TARGETED_DEVICE_FAMILY = 4; 738 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 739 | }; 740 | name = Debug; 741 | }; 742 | 52D6D9E91BEFFF6E002C0205 /* Release */ = { 743 | isa = XCBuildConfiguration; 744 | buildSettings = { 745 | APPLICATION_EXTENSION_API_ONLY = YES; 746 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 747 | DEFINES_MODULE = YES; 748 | DYLIB_COMPATIBILITY_VERSION = 1; 749 | DYLIB_CURRENT_VERSION = 1; 750 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 751 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 752 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 753 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 754 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-watchOS"; 755 | PRODUCT_NAME = {PROJECT}; 756 | SDKROOT = watchos; 757 | SKIP_INSTALL = YES; 758 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 759 | SWIFT_VERSION = 5.0; 760 | TARGETED_DEVICE_FAMILY = 4; 761 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 762 | }; 763 | name = Release; 764 | }; 765 | 52D6DA021BEFFFBE002C0205 /* Debug */ = { 766 | isa = XCBuildConfiguration; 767 | buildSettings = { 768 | APPLICATION_EXTENSION_API_ONLY = YES; 769 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 770 | DEFINES_MODULE = YES; 771 | DYLIB_COMPATIBILITY_VERSION = 1; 772 | DYLIB_CURRENT_VERSION = 1; 773 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 774 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 775 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 776 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 777 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-tvOS"; 778 | PRODUCT_NAME = {PROJECT}; 779 | SDKROOT = appletvos; 780 | SKIP_INSTALL = YES; 781 | SWIFT_VERSION = 5.0; 782 | TARGETED_DEVICE_FAMILY = 3; 783 | TVOS_DEPLOYMENT_TARGET = 9.0; 784 | }; 785 | name = Debug; 786 | }; 787 | 52D6DA031BEFFFBE002C0205 /* Release */ = { 788 | isa = XCBuildConfiguration; 789 | buildSettings = { 790 | APPLICATION_EXTENSION_API_ONLY = YES; 791 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 792 | DEFINES_MODULE = YES; 793 | DYLIB_COMPATIBILITY_VERSION = 1; 794 | DYLIB_CURRENT_VERSION = 1; 795 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 796 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 797 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 798 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 799 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-tvOS"; 800 | PRODUCT_NAME = {PROJECT}; 801 | SDKROOT = appletvos; 802 | SKIP_INSTALL = YES; 803 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 804 | SWIFT_VERSION = 5.0; 805 | TARGETED_DEVICE_FAMILY = 3; 806 | TVOS_DEPLOYMENT_TARGET = 9.0; 807 | }; 808 | name = Release; 809 | }; 810 | 52D6DA211BF000BD002C0205 /* Debug */ = { 811 | isa = XCBuildConfiguration; 812 | buildSettings = { 813 | APPLICATION_EXTENSION_API_ONLY = YES; 814 | CODE_SIGN_IDENTITY = "-"; 815 | COMBINE_HIDPI_IMAGES = YES; 816 | DEFINES_MODULE = YES; 817 | DYLIB_COMPATIBILITY_VERSION = 1; 818 | DYLIB_CURRENT_VERSION = 1; 819 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 820 | FRAMEWORK_VERSION = A; 821 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 822 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 823 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 824 | MACOSX_DEPLOYMENT_TARGET = 10.10; 825 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-macOS"; 826 | PRODUCT_NAME = {PROJECT}; 827 | SDKROOT = macosx; 828 | SKIP_INSTALL = YES; 829 | SWIFT_VERSION = 5.0; 830 | }; 831 | name = Debug; 832 | }; 833 | 52D6DA221BF000BD002C0205 /* Release */ = { 834 | isa = XCBuildConfiguration; 835 | buildSettings = { 836 | APPLICATION_EXTENSION_API_ONLY = YES; 837 | CODE_SIGN_IDENTITY = "-"; 838 | COMBINE_HIDPI_IMAGES = YES; 839 | DEFINES_MODULE = YES; 840 | DYLIB_COMPATIBILITY_VERSION = 1; 841 | DYLIB_CURRENT_VERSION = 1; 842 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 843 | FRAMEWORK_VERSION = A; 844 | INFOPLIST_FILE = Configs/{PROJECT}.plist; 845 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 846 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 847 | MACOSX_DEPLOYMENT_TARGET = 10.10; 848 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-macOS"; 849 | PRODUCT_NAME = {PROJECT}; 850 | SDKROOT = macosx; 851 | SKIP_INSTALL = YES; 852 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 853 | SWIFT_VERSION = 5.0; 854 | }; 855 | name = Release; 856 | }; 857 | DD7502831C68FCFC006590AF /* Debug */ = { 858 | isa = XCBuildConfiguration; 859 | buildSettings = { 860 | CODE_SIGN_IDENTITY = "-"; 861 | COMBINE_HIDPI_IMAGES = YES; 862 | INFOPLIST_FILE = Configs/{PROJECT}Tests.plist; 863 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 864 | MACOSX_DEPLOYMENT_TARGET = 10.11; 865 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-macOS-Tests"; 866 | PRODUCT_NAME = "$(TARGET_NAME)"; 867 | SDKROOT = macosx; 868 | SWIFT_VERSION = 5.0; 869 | }; 870 | name = Debug; 871 | }; 872 | DD7502841C68FCFC006590AF /* Release */ = { 873 | isa = XCBuildConfiguration; 874 | buildSettings = { 875 | CODE_SIGN_IDENTITY = "-"; 876 | COMBINE_HIDPI_IMAGES = YES; 877 | INFOPLIST_FILE = Configs/{PROJECT}Tests.plist; 878 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 879 | MACOSX_DEPLOYMENT_TARGET = 10.11; 880 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-macOS-Tests"; 881 | PRODUCT_NAME = "$(TARGET_NAME)"; 882 | SDKROOT = macosx; 883 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 884 | SWIFT_VERSION = 5.0; 885 | }; 886 | name = Release; 887 | }; 888 | DD7502961C690C7A006590AF /* Debug */ = { 889 | isa = XCBuildConfiguration; 890 | buildSettings = { 891 | INFOPLIST_FILE = Configs/{PROJECT}Tests.plist; 892 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 893 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-tvOS-Tests"; 894 | PRODUCT_NAME = "$(TARGET_NAME)"; 895 | SDKROOT = appletvos; 896 | SWIFT_VERSION = 5.0; 897 | TVOS_DEPLOYMENT_TARGET = 9.1; 898 | }; 899 | name = Debug; 900 | }; 901 | DD7502971C690C7A006590AF /* Release */ = { 902 | isa = XCBuildConfiguration; 903 | buildSettings = { 904 | INFOPLIST_FILE = Configs/{PROJECT}Tests.plist; 905 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 906 | PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-tvOS-Tests"; 907 | PRODUCT_NAME = "$(TARGET_NAME)"; 908 | SDKROOT = appletvos; 909 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 910 | SWIFT_VERSION = 5.0; 911 | TVOS_DEPLOYMENT_TARGET = 9.1; 912 | }; 913 | name = Release; 914 | }; 915 | /* End XCBuildConfiguration section */ 916 | 917 | /* Begin XCConfigurationList section */ 918 | 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "{PROJECT}" */ = { 919 | isa = XCConfigurationList; 920 | buildConfigurations = ( 921 | 52D6D98E1BEFF229002C0205 /* Debug */, 922 | 52D6D98F1BEFF229002C0205 /* Release */, 923 | ); 924 | defaultConfigurationIsVisible = 0; 925 | defaultConfigurationName = Release; 926 | }; 927 | 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-iOS" */ = { 928 | isa = XCConfigurationList; 929 | buildConfigurations = ( 930 | 52D6D9911BEFF229002C0205 /* Debug */, 931 | 52D6D9921BEFF229002C0205 /* Release */, 932 | ); 933 | defaultConfigurationIsVisible = 0; 934 | defaultConfigurationName = Release; 935 | }; 936 | 52D6D9931BEFF229002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-iOS Tests" */ = { 937 | isa = XCConfigurationList; 938 | buildConfigurations = ( 939 | 52D6D9941BEFF229002C0205 /* Debug */, 940 | 52D6D9951BEFF229002C0205 /* Release */, 941 | ); 942 | defaultConfigurationIsVisible = 0; 943 | defaultConfigurationName = Release; 944 | }; 945 | 52D6D9E71BEFFF6E002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-watchOS" */ = { 946 | isa = XCConfigurationList; 947 | buildConfigurations = ( 948 | 52D6D9E81BEFFF6E002C0205 /* Debug */, 949 | 52D6D9E91BEFFF6E002C0205 /* Release */, 950 | ); 951 | defaultConfigurationIsVisible = 0; 952 | defaultConfigurationName = Release; 953 | }; 954 | 52D6DA011BEFFFBE002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-tvOS" */ = { 955 | isa = XCConfigurationList; 956 | buildConfigurations = ( 957 | 52D6DA021BEFFFBE002C0205 /* Debug */, 958 | 52D6DA031BEFFFBE002C0205 /* Release */, 959 | ); 960 | defaultConfigurationIsVisible = 0; 961 | defaultConfigurationName = Release; 962 | }; 963 | 52D6DA201BF000BD002C0205 /* Build configuration list for PBXNativeTarget "{PROJECT}-macOS" */ = { 964 | isa = XCConfigurationList; 965 | buildConfigurations = ( 966 | 52D6DA211BF000BD002C0205 /* Debug */, 967 | 52D6DA221BF000BD002C0205 /* Release */, 968 | ); 969 | defaultConfigurationIsVisible = 0; 970 | defaultConfigurationName = Release; 971 | }; 972 | DD7502821C68FCFC006590AF /* Build configuration list for PBXNativeTarget "{PROJECT}-macOS Tests" */ = { 973 | isa = XCConfigurationList; 974 | buildConfigurations = ( 975 | DD7502831C68FCFC006590AF /* Debug */, 976 | DD7502841C68FCFC006590AF /* Release */, 977 | ); 978 | defaultConfigurationIsVisible = 0; 979 | defaultConfigurationName = Release; 980 | }; 981 | DD7502951C690C7A006590AF /* Build configuration list for PBXNativeTarget "{PROJECT}-tvOS Tests" */ = { 982 | isa = XCConfigurationList; 983 | buildConfigurations = ( 984 | DD7502961C690C7A006590AF /* Debug */, 985 | DD7502971C690C7A006590AF /* Release */, 986 | ); 987 | defaultConfigurationIsVisible = 0; 988 | defaultConfigurationName = Release; 989 | }; 990 | /* End XCConfigurationList section */ 991 | }; 992 | rootObject = 52D6D9731BEFF229002C0205 /* Project object */; 993 | } 994 | -------------------------------------------------------------------------------- /Template/{PROJECT}.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Template/{PROJECT}.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Template/{PROJECT}.xcodeproj/xcshareddata/xcschemes/{PROJECT}-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Template/{PROJECT}.xcodeproj/xcshareddata/xcschemes/{PROJECT}-macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Template/{PROJECT}.xcodeproj/xcshareddata/xcschemes/{PROJECT}-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Template/{PROJECT}.xcodeproj/xcshareddata/xcschemes/{PROJECT}-watchOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 46 | 47 | 53 | 54 | 55 | 56 | 57 | 58 | 64 | 65 | 71 | 72 | 73 | 74 | 76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /main.swift: -------------------------------------------------------------------------------- 1 | #!/usr/bin/swift 2 | 3 | /** 4 | * SwiftPlate 5 | * 6 | * Copyright (c) 2016 John Sundell. Licensed under the MIT license, as follows: 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in all 16 | * copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | * SOFTWARE. 25 | */ 26 | 27 | import Foundation 28 | 29 | // MARK: - Extensions 30 | 31 | extension Process { 32 | @discardableResult func launchBash(withCommand command: String) -> String? { 33 | launchPath = "/bin/bash" 34 | arguments = ["-c", command] 35 | 36 | let pipe = Pipe() 37 | standardOutput = pipe 38 | 39 | // Silent errors by assigning a dummy pipe to the error output 40 | standardError = Pipe() 41 | 42 | launch() 43 | waitUntilExit() 44 | 45 | let outputData = pipe.fileHandleForReading.readDataToEndOfFile() 46 | return String(data: outputData, encoding: .utf8)?.nonEmpty 47 | } 48 | 49 | func gitConfigValue(forKey key: String) -> String? { 50 | return launchBash(withCommand: "git config --global --get \(key)")?.trimmingCharacters(in: .whitespacesAndNewlines) 51 | } 52 | } 53 | 54 | extension String { 55 | var nonEmpty: String? { 56 | guard count > 0 else { 57 | return nil 58 | } 59 | 60 | return self 61 | } 62 | 63 | func withoutSuffix(_ suffix: String) -> String { 64 | guard hasSuffix(suffix) else { 65 | return self 66 | } 67 | 68 | let startIndex = index(endIndex, offsetBy: -suffix.count) 69 | return replacingCharacters(in: startIndex.. Bool { 75 | var objCBool: ObjCBool = false 76 | 77 | guard fileExists(atPath: path, isDirectory: &objCBool) else { 78 | return false 79 | } 80 | 81 | return objCBool.boolValue 82 | } 83 | } 84 | 85 | extension Array { 86 | func element(after index: Int) -> Element? { 87 | guard index >= 0 && index < count else { 88 | return nil 89 | } 90 | 91 | return self[index + 1] 92 | } 93 | } 94 | 95 | // MARK: - Types 96 | 97 | struct Arguments { 98 | var destination: String? 99 | var projectName: String? 100 | var authorName: String? 101 | var authorEmail: String? 102 | var githubURL: String? 103 | var organizationName: String? 104 | var repositoryURL: URL? 105 | var forceEnabled: Bool = false 106 | 107 | init(commandLineArguments arguments: [String]) { 108 | for (index, argument) in arguments.enumerated() { 109 | switch argument.lowercased() { 110 | case "--destination", "-d": 111 | destination = arguments.element(after: index) 112 | case "--project", "-p": 113 | projectName = arguments.element(after: index) 114 | case "--name", "-n": 115 | authorName = arguments.element(after: index) 116 | case "--email", "-e": 117 | authorEmail = arguments.element(after: index) 118 | case "--url", "-u": 119 | githubURL = arguments.element(after: index) 120 | case "--organization", "-o": 121 | organizationName = arguments.element(after: index) 122 | case "--repo", "-r": 123 | if let urlString = arguments.element(after: index) { 124 | repositoryURL = URL(string: urlString) 125 | } 126 | case "--force", "-f": 127 | forceEnabled = true 128 | default: 129 | break 130 | } 131 | } 132 | } 133 | } 134 | 135 | class StringReplacer { 136 | private let projectName: String 137 | private let authorName: String 138 | private let authorEmail: String 139 | private let gitHubURL: String 140 | private let year: String 141 | private let today: String 142 | private let organizationName: String 143 | 144 | init(projectName: String, authorName: String, authorEmail: String?, gitHubURL: String?, organizationName: String?) { 145 | self.projectName = projectName 146 | self.authorName = authorName 147 | self.authorEmail = authorEmail ?? "" 148 | self.gitHubURL = gitHubURL ?? "" 149 | self.organizationName = organizationName ?? projectName 150 | 151 | 152 | let yearFormatter = DateFormatter() 153 | yearFormatter.dateFormat = "yyyy" 154 | self.year = yearFormatter.string(from: Date()) 155 | 156 | let dateFormatter = DateFormatter() 157 | dateFormatter.dateStyle = .short 158 | self.today = dateFormatter.string(from: Date()) 159 | } 160 | 161 | private var dateString: String { 162 | return DateFormatter.localizedString( 163 | from: Date(), 164 | dateStyle: DateFormatter.Style.medium, 165 | timeStyle: DateFormatter.Style.none 166 | ) 167 | } 168 | 169 | func process(string: String) -> String { 170 | return string.replacingOccurrences(of: "{PROJECT}", with: projectName) 171 | .replacingOccurrences(of: "{AUTHOR}", with: authorName) 172 | .replacingOccurrences(of: "{EMAIL}", with: authorEmail) 173 | .replacingOccurrences(of: "{URL}", with: gitHubURL) 174 | .replacingOccurrences(of: "{YEAR}", with: year) 175 | .replacingOccurrences(of: "{TODAY}", with: today) 176 | .replacingOccurrences(of: "{DATE}", with: dateString) 177 | .replacingOccurrences(of: "{ORGANIZATION}", with: organizationName) 178 | } 179 | 180 | func process(filesInFolderWithPath folderPath: String) throws { 181 | let fileManager = FileManager.default 182 | let currentFileName = URL.init(fileURLWithPath: #file).lastPathComponent 183 | 184 | for itemName in try fileManager.contentsOfDirectory(atPath: folderPath) { 185 | if itemName.hasPrefix(".") || itemName == currentFileName { 186 | continue 187 | } 188 | 189 | let itemPath = folderPath + "/" + itemName 190 | let newItemPath = folderPath + "/" + process(string: itemName) 191 | 192 | if fileManager.isFolder(atPath: itemPath) { 193 | try process(filesInFolderWithPath: itemPath) 194 | try fileManager.moveItem(atPath: itemPath, toPath: newItemPath) 195 | continue 196 | } 197 | 198 | let fileContents = try String(contentsOfFile: itemPath) 199 | try process(string: fileContents).write(toFile: newItemPath, atomically: false, encoding: .utf8) 200 | 201 | if newItemPath != itemPath { 202 | try fileManager.removeItem(atPath: itemPath) 203 | } 204 | } 205 | } 206 | } 207 | 208 | // MARK: - Functions 209 | 210 | func printError(_ message: String) { 211 | print("👮 \(message)") 212 | } 213 | 214 | func askForRequiredInfo(question: String, errorMessage errorMessageClosure: @autoclosure () -> String) -> String { 215 | print(question) 216 | 217 | guard let info = readLine()?.nonEmpty else { 218 | printError("\(errorMessageClosure()). Try again.") 219 | return askForRequiredInfo(question: question, errorMessage: errorMessageClosure()) 220 | } 221 | 222 | return info 223 | } 224 | 225 | func askForOptionalInfo(question: String, questionSuffix: String = "You may leave this empty.") -> String? { 226 | print("\(question) \(questionSuffix)") 227 | return readLine()?.nonEmpty 228 | } 229 | 230 | func askForBooleanInfo(question: String) -> Bool { 231 | let errorMessage = "Please enter Y/y (yes) or N/n (no)" 232 | let answerString = askForRequiredInfo(question: "\(question) (Y/N)", errorMessage: errorMessage) 233 | 234 | switch answerString.lowercased() { 235 | case "y": 236 | return true 237 | case "n": 238 | return false 239 | default: 240 | printError("\(errorMessage). Try again.") 241 | return askForBooleanInfo(question: question) 242 | } 243 | } 244 | 245 | func askForDestination() -> String { 246 | let destination = askForOptionalInfo( 247 | question: "📦 Where would you like to generate a project?", 248 | questionSuffix: "(Leave empty to use current directory)" 249 | ) 250 | 251 | let fileManager = FileManager.default 252 | 253 | if let destination = destination { 254 | guard fileManager.fileExists(atPath: destination) else { 255 | printError("That path doesn't exist. Try again.") 256 | return askForDestination() 257 | } 258 | 259 | return destination 260 | } 261 | 262 | return fileManager.currentDirectoryPath 263 | } 264 | 265 | func askForProjectName(destination: String) -> String { 266 | let projectFolderName = destination.withoutSuffix("/").components(separatedBy: "/").last! 267 | 268 | let projectName = askForOptionalInfo( 269 | question: "📛 What's the name of your project?", 270 | questionSuffix: "(Leave empty to use the name of the project folder: \(projectFolderName))" 271 | ) 272 | 273 | return projectName ?? projectFolderName 274 | } 275 | 276 | func askForAuthorName() -> String { 277 | let gitName = Process().gitConfigValue(forKey: "user.name") 278 | let question = "👶 What's your name?" 279 | 280 | if let gitName = gitName { 281 | let authorName = askForOptionalInfo(question: question, questionSuffix: "(Leave empty to use your git config name: \(gitName))") 282 | return authorName ?? gitName 283 | } 284 | 285 | return askForRequiredInfo(question: question, errorMessage: "Your name cannot be empty") 286 | } 287 | 288 | func askForAuthorEmail() -> String? { 289 | let gitEmail = Process().gitConfigValue(forKey: "user.email") 290 | let question = "📫 What's your email address (for Podspec)?" 291 | 292 | if let gitEmail = gitEmail { 293 | let authorEmail = askForOptionalInfo(question: question, questionSuffix: "(Leave empty to use your git config email: \(gitEmail))") 294 | return authorEmail ?? gitEmail 295 | } 296 | 297 | return askForOptionalInfo(question: question) 298 | } 299 | 300 | func askForGitHubURL(destination: String) -> String? { 301 | let gitURL = Process().launchBash(withCommand: "cd \(destination) && git remote get-url origin")? 302 | .trimmingCharacters(in: .whitespacesAndNewlines) 303 | .withoutSuffix(".git") 304 | 305 | let question = "🌍 Any GitHub URL that you'll be hosting this project at (for Podspec)?" 306 | 307 | if let gitURL = gitURL { 308 | let gitHubURL = askForOptionalInfo(question: question, questionSuffix: "(Leave empty to use the remote URL of your repo: \(gitURL))") 309 | return gitHubURL ?? gitURL 310 | } 311 | 312 | return askForOptionalInfo(question: question) 313 | } 314 | 315 | func performCommand(description: String, command: () throws -> Void) rethrows { 316 | print("👉 \(description)...") 317 | try command() 318 | print("✅ Done") 319 | } 320 | 321 | // MARK: - Program 322 | 323 | print("Welcome to the SwiftPlate project generator 🐣") 324 | 325 | let arguments = Arguments(commandLineArguments: CommandLine.arguments) 326 | let destination = arguments.destination ?? askForDestination() 327 | let projectName = arguments.projectName ?? askForProjectName(destination: destination) 328 | let authorName = arguments.authorName ?? askForAuthorName() 329 | let authorEmail = arguments.authorEmail ?? askForAuthorEmail() 330 | let gitHubURL = arguments.githubURL ?? askForGitHubURL(destination: destination) 331 | let organizationName = arguments.organizationName ?? askForOptionalInfo(question: "🏢 What's your organization name?") 332 | 333 | print("---------------------------------------------------------------------") 334 | print("SwiftPlate will now generate a project with the following parameters:") 335 | print("📦 Destination: \(destination)") 336 | print("📛 Name: \(projectName)") 337 | print("👶 Author: \(authorName)") 338 | 339 | if let authorEmail = authorEmail { 340 | print("📫 Author email: \(authorEmail)") 341 | } 342 | 343 | if let gitHubURL = gitHubURL { 344 | print("🌍 GitHub URL: \(gitHubURL)") 345 | } 346 | 347 | if let organizationName = organizationName { 348 | print("🏢 Organization Name: \(organizationName)") 349 | } 350 | 351 | print("---------------------------------------------------------------------") 352 | 353 | if !arguments.forceEnabled { 354 | if !askForBooleanInfo(question: "Proceed? ✅") { 355 | exit(0) 356 | } 357 | } 358 | 359 | print("🚀 Starting to generate project \(projectName)...") 360 | 361 | do { 362 | let fileManager = FileManager.default 363 | let temporaryDirectoryPath = destination + "/swiftplate_temp" 364 | let gitClonePath = "\(temporaryDirectoryPath)/SwiftPlate" 365 | let templatePath = "\(gitClonePath)/Template" 366 | 367 | performCommand(description: "Removing any previous temporary folder") { 368 | try? fileManager.removeItem(atPath: temporaryDirectoryPath) 369 | } 370 | 371 | try performCommand(description: "Making temporary folder (\(temporaryDirectoryPath))") { 372 | try fileManager.createDirectory(atPath: temporaryDirectoryPath, withIntermediateDirectories: false, attributes: nil) 373 | } 374 | 375 | performCommand(description: "Making a local clone of the SwiftPlate repo") { 376 | let repositoryURL = arguments.repositoryURL ?? URL(string: "https://github.com/JohnSundell/SwiftPlate.git")! 377 | Process().launchBash(withCommand: "git clone \(repositoryURL.absoluteString) '\(gitClonePath)' -q") 378 | } 379 | 380 | try performCommand(description: "Copying template folder") { 381 | let ignorableItems: Set = ["readme.md", "license"] 382 | let ignoredItems = try fileManager.contentsOfDirectory(atPath: destination).map { 383 | $0.lowercased() 384 | }.filter { 385 | ignorableItems.contains($0) 386 | } 387 | 388 | for itemName in try fileManager.contentsOfDirectory(atPath: templatePath) { 389 | let originPath = templatePath + "/" + itemName 390 | let destinationPath = destination + "/" + itemName 391 | 392 | let lowercasedItemName = itemName.lowercased() 393 | guard ignoredItems.contains(lowercasedItemName) == false else { 394 | continue 395 | } 396 | 397 | try fileManager.copyItem(atPath: originPath, toPath: destinationPath) 398 | } 399 | } 400 | 401 | try performCommand(description: "Removing temporary folder") { 402 | try fileManager.removeItem(atPath: temporaryDirectoryPath) 403 | } 404 | 405 | try performCommand(description: "Filling in template") { 406 | let replacer = StringReplacer( 407 | projectName: projectName, 408 | authorName: authorName, 409 | authorEmail: authorEmail, 410 | gitHubURL: gitHubURL, 411 | organizationName: organizationName 412 | ) 413 | 414 | try replacer.process(filesInFolderWithPath: destination) 415 | } 416 | 417 | print("All done! 🎉 Good luck with your project! 🚀") 418 | } catch { 419 | print("An error was encountered 🙁") 420 | print("Error: \(error)") 421 | } 422 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnSundell/SwiftPlate/f7da14dae7f37bb786b4fcbacf72d5226b0614cb/screenshot.png -------------------------------------------------------------------------------- /testStructure.py: -------------------------------------------------------------------------------- 1 | 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | import os 6 | from os.path import join, getsize 7 | 8 | rootFiles = set(['LICENSE', 'Package.swift', 'README.md', sys.argv[1] + '.podspec']) 9 | configFiles = set([sys.argv[1] + '.plist', sys.argv[1] + 'Tests.plist']) 10 | sourceFiles = set([sys.argv[1]+ '.swift']) 11 | testDirs = set([sys.argv[1] + 'Tests']) 12 | 13 | for root, dirs, files in os.walk('.'): 14 | if root == '.': 15 | if sys.argv[1] + '.xcodeproj' not in dirs: 16 | print("xcode project not found") 17 | exit(1) 18 | if not rootFiles.issubset(files): 19 | print("root level files not found") 20 | exit(1) 21 | if root == './Configs': 22 | if not configFiles.issubset(files): 23 | print("Config files not found") 24 | exit(1) 25 | if root == './Sources': 26 | if not sourceFiles.issubset(files): 27 | print("Source files not found") 28 | exit(1) 29 | if root == './Tests': 30 | if not testDirs.issubset(dirs): 31 | print("Test Directories not found") 32 | exit(1) 33 | print("All tests run successfully ⭐⭐⭐⭐⭐") 34 | exit(0) 35 | --------------------------------------------------------------------------------