diff --git a/README.md b/README.md index 28cfb68..6127028 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ SwiftPlate will generate Xcode projects for you in seconds, that support: - [x] watchOS - [x] tvOS - [x] Linux +- [x] Quick + Nimble testing +- [x] Travis CI (via Fastlane - Mac environment only) Just run `swiftplate`, and you’ll be presented with a simple step-by-step guide: diff --git a/Template/.gitignore b/Template/.gitignore index d534044..0a04d73 100644 --- a/Template/.gitignore +++ b/Template/.gitignore @@ -65,3 +65,4 @@ fastlane/report.xml fastlane/Preview.html fastlane/screenshots fastlane/test_output +fastlane/README.md \ No newline at end of file diff --git a/Template/.travis.yml b/Template/.travis.yml new file mode 100644 index 0000000..cdcfde5 --- /dev/null +++ b/Template/.travis.yml @@ -0,0 +1,6 @@ +language: objective-c +osx_image: xcode8.3 +before_install: +- gem update fastlane +script: +- fastlane test \ No newline at end of file diff --git a/Template/fastlane/Fastfile b/Template/fastlane/Fastfile new file mode 100644 index 0000000..64d1c4a --- /dev/null +++ b/Template/fastlane/Fastfile @@ -0,0 +1,69 @@ +# Customise this file, documentation can be found here: +# https://github.com/fastlane/fastlane/tree/master/fastlane/docs +# All available actions: https://docs.fastlane.tools/actions +# can also be listed using the `fastlane actions` command + +# Change the syntax highlighting to Ruby +# All lines starting with a # are ignored when running `fastlane` + +# If you want to automatically update fastlane if a new version is available: +# update_fastlane + +# This is the minimum version number required. +# Update this, if you use features of a newer version +fastlane_version "2.16.0" + +default_platform :ios + +platform :ios do + + desc "Builds the framework and runs all the tests" + lane :test do + + # Prevent timeout issues + ENV["FASTLANE_XCODE_LIST_TIMEOUT"] = "120" + + # Just build the watchOS target (no tests) + xcodebuild( + project: "{PROJECT}.xcodeproj", + scheme: "{PROJECT}-watchOS", + clean: true, + build: true + ) + + # Build and test the macOS target + scan( + project: "{PROJECT}.xcodeproj", + scheme: "{PROJECT}-macOS", + devices: [ + # (deliberately empty, will use the mac this is running on) + ], + clean: true, + skip_slack: true + ) + + # Build and test the iOS target + scan( + project: "{PROJECT}.xcodeproj", + scheme: "{PROJECT}-iOS", + devices: [ + "iPhone SE", + # "iPhone 6", + # "iPhone 7 Plus", + ], + clean: true, + skip_slack: true + ) + + # Build and test the tvOS target + scan( + project: "{PROJECT}.xcodeproj", + scheme: "{PROJECT}-tvOS", + devices: [ + "Apple TV 1080p", + ], + clean: true, + skip_slack: true + ) + end +end diff --git a/Template/optional/ExampleTests-quick+nimble.swift b/Template/optional/ExampleTests-quick+nimble.swift new file mode 100644 index 0000000..c922bbd --- /dev/null +++ b/Template/optional/ExampleTests-quick+nimble.swift @@ -0,0 +1,40 @@ +// +// {PROJECT}Tests.swift +// {ORGANIZATION} +// +// Created by {AUTHOR} on {TODAY}. +// Copyright © {YEAR} {ORGANIZATION}. All rights reserved. +// + +import Quick +import Nimble +import {PROJECT} + +class {PROJECT}Spec: QuickSpec { + + override func spec() { + + // For more information about Quick and Nimble: + // https://github.com/Quick/Quick + // https://github.com/Quick/Nimble + + // EXAMPLES: + + describe("A bunch of numbers") { + it("should add up") { + expect(1 + 1).to(equal(2)) + } + it("should behave logically") { + expect(1.2).to(beCloseTo(1.1, within: 0.1)) + expect(3) > 2 + } + } + + describe("Some other stuff") { + it("should make sense") { + expect("seahorse").to(contain("sea")) + expect(["Atlantic", "Pacific"]).toNot(contain("Mississippi")) + } + } + } +} diff --git a/Template/optional/LinuxMain-quick+nimble.swift b/Template/optional/LinuxMain-quick+nimble.swift new file mode 100644 index 0000000..14e4388 --- /dev/null +++ b/Template/optional/LinuxMain-quick+nimble.swift @@ -0,0 +1,7 @@ +import XCTest +import Quick +@testable import {PROJECT}Tests + +Quick.QCKMain([ + {PROJECT}Tests.self, +]) diff --git a/Template/optional/Package-quick+nimble.swift b/Template/optional/Package-quick+nimble.swift new file mode 100644 index 0000000..b8c370a --- /dev/null +++ b/Template/optional/Package-quick+nimble.swift @@ -0,0 +1,9 @@ +import PackageDescription + +let package = Package( + name: "{PROJECT}", + dependencies: [ + .Package(url: "https://github.com/Quick/Quick.git", majorVersion: 1), + .Package(url: "https://github.com/Quick/Nimble.git", majorVersion: 6) + ] +) \ No newline at end of file diff --git a/Template/optional/Podfile-blank b/Template/optional/Podfile-blank new file mode 100644 index 0000000..c1c52c4 --- /dev/null +++ b/Template/optional/Podfile-blank @@ -0,0 +1,52 @@ +workspace '{PROJECT}' +inhibit_all_warnings! +use_frameworks! + + +# Shared declarations + +def dependency_pods + # Fill in as needed +end + +def testing_pods + # Fill in as needed +end + + +# Framework targets + +target '{PROJECT}-iOS' do + platform :ios, '8.0' + dependency_pods +end + +target '{PROJECT}-macOS' do + platform :osx, '10.9' + dependency_pods +end + +target '{PROJECT}-tvOS' do + platform :tvos, '9.0' + dependency_pods +end + +target '{PROJECT}-watchOS' do + platform :watchos, '2.0' + dependency_pods +end + + +# Test targets + +target '{PROJECT}-iOS Tests' do + testing_pods +end + +target '{PROJECT}-macOS Tests' do + testing_pods +end + +target '{PROJECT}-tvOS Tests' do + testing_pods +end diff --git a/Template/optional/Podfile-quick+nimble b/Template/optional/Podfile-quick+nimble new file mode 100644 index 0000000..c6a949d --- /dev/null +++ b/Template/optional/Podfile-quick+nimble @@ -0,0 +1,53 @@ +workspace '{PROJECT}' +inhibit_all_warnings! +use_frameworks! + + +# Shared declarations + +def dependency_pods + # Fill in as needed +end + +def testing_pods + pod 'Quick' + pod 'Nimble' +end + + +# Framework targets + +target '{PROJECT}-iOS' do + platform :ios, '8.0' + dependency_pods +end + +target '{PROJECT}-macOS' do + platform :osx, '10.9' + dependency_pods +end + +target '{PROJECT}-tvOS' do + platform :tvos, '9.0' + dependency_pods +end + +target '{PROJECT}-watchOS' do + platform :watchos, '2.0' + dependency_pods +end + + +# Test targets + +target '{PROJECT}-iOS Tests' do + testing_pods +end + +target '{PROJECT}-macOS Tests' do + testing_pods +end + +target '{PROJECT}-tvOS Tests' do + testing_pods +end diff --git a/Template/{PROJECT}.xcodeproj/project.pbxproj b/Template/{PROJECT}.xcodeproj/project.pbxproj index 467cc95..4fbb655 100644 --- a/Template/{PROJECT}.xcodeproj/project.pbxproj +++ b/Template/{PROJECT}.xcodeproj/project.pbxproj @@ -653,7 +653,6 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.{PROJECT}.{PROJECT}-iOS"; PRODUCT_NAME = {PROJECT}; SKIP_INSTALL = YES; diff --git a/main.swift b/main.swift index db6f16f..d18dc5a 100755 --- a/main.swift +++ b/main.swift @@ -329,6 +329,9 @@ let authorName = arguments.authorName ?? askForAuthorName() let authorEmail = arguments.authorEmail ?? askForAuthorEmail() let gitHubURL = arguments.githubURL ?? askForGitHubURL(destination: destination) let organizationName = arguments.organizationName ?? askForOptionalInfo(question: "🏢 What's your organization name?") +let useCocoapods = askForBooleanInfo(question: "🛠 Use Cocoapods to develop and test your project?") +let useQuickAndNimble = askForBooleanInfo(question: "🔍 Use Quick and Nimble testing frameworks? (via Cocoapods)") +let installCocoapods = useCocoapods || useQuickAndNimble print("---------------------------------------------------------------------") print("SwiftPlate will now generate a project with the following parameters:") @@ -348,6 +351,14 @@ if let organizationName = organizationName { print("🏢 Organization Name: \(organizationName)") } +if installCocoapods { + if useQuickAndNimble { + print("🔍 Using Quick and Nimble (via Cocoapods)") + } else { + print("🛠 Using Cocoapods") + } +} + print("---------------------------------------------------------------------") if !arguments.forceEnabled { @@ -363,6 +374,7 @@ do { let temporaryDirectoryPath = destination + "/swiftplate_temp" let gitClonePath = "\(temporaryDirectoryPath)/SwiftPlate" let templatePath = "\(gitClonePath)/Template" + let optionalItemsPath = templatePath + "/Optional" performCommand(description: "Removing any previous temporary folder") { try? fileManager.removeItem(atPath: temporaryDirectoryPath) @@ -379,11 +391,12 @@ do { try performCommand(description: "Copying template folder") { let ignorableItems: Set = ["readme.md", "license"] - let ignoredItems = try fileManager.contentsOfDirectory(atPath: destination).map { + var ignoredItems = try fileManager.contentsOfDirectory(atPath: destination).map { $0.lowercased() }.filter { ignorableItems.contains($0) } + ignoredItems.append("optional") for itemName in try fileManager.contentsOfDirectory(atPath: templatePath) { let originPath = templatePath + "/" + itemName @@ -396,6 +409,34 @@ do { try fileManager.copyItem(atPath: originPath, toPath: destinationPath) } + + if useCocoapods && !useQuickAndNimble { + let originPath = optionalItemsPath + "/" + "Podfile-blank" + let destinationPath = destination + "/" + "Podfile" + try fileManager.copyItem(atPath: originPath, toPath: destinationPath) + } + + if useQuickAndNimble { + + let podfileOriginPath = optionalItemsPath + "/" + "Podfile-quick+nimble" + let podfileDestinationPath = destination + "/" + "Podfile" + try fileManager.copyItem(atPath: podfileOriginPath, toPath: podfileDestinationPath) + + let linuxOriginPath = optionalItemsPath + "/" + "LinuxMain-quick+nimble.swift" + let linuxDestinationPath = destination + "/Tests/" + "LinuxMain.swift" + try fileManager.removeItem(atPath: linuxDestinationPath) + try fileManager.copyItem(atPath: linuxOriginPath, toPath: linuxDestinationPath) + + let testsOriginPath = optionalItemsPath + "/" + "ExampleTests-quick+nimble.swift" + let testsDestinationPath = destination + "/Tests/{PROJECT}Tests/" + "{PROJECT}Tests.swift" + try fileManager.removeItem(atPath: testsDestinationPath) + try fileManager.copyItem(atPath: testsOriginPath, toPath: testsDestinationPath) + + let packageOriginPath = optionalItemsPath + "/" + "Package-quick+nimble.swift" + let packageDestinationPath = destination + "/" + "Package.swift" + try fileManager.removeItem(atPath: packageDestinationPath) + try fileManager.copyItem(atPath: packageOriginPath, toPath: packageDestinationPath) + } } try performCommand(description: "Removing temporary folder") { @@ -413,6 +454,12 @@ do { try replacer.process(filesInFolderWithPath: destination) } + + if installCocoapods { + performCommand(description: "Setting up Cocoapods (running pod install)") { + Process().launchBash(withCommand: "pod install") + } + } print("All done! 🎉 Good luck with your project! 🚀") } catch {