Skip to content

Commit

Permalink
Add support for installing Stagehand via SPM (#15)
Browse files Browse the repository at this point in the history
* Adds support for installing Stagehand via Swift Package Manager
* Adds scripts for running builds on CI
* Updates directory structure to recommended SPM structure
* Updates installation instructions in README

This resolves part of #2, since it only supports Stagehand and not StagehandTesting.
  • Loading branch information
NickEntin authored Mar 6, 2020
1 parent 213505d commit 7e69236
Show file tree
Hide file tree
Showing 30 changed files with 282 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ Pods/

# Swift Playgrounds
timeline.xctimeline

# Swift Pacakge Manager
generated/
.build/
.swiftpm/
13 changes: 7 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
language: objective-c
jobs:
- osx_image: xcode11.3
env: DEST='platform=iOS Simulator,OS=13.3,name=iPhone 11 Pro'
env: ACTIONS="xcode,pod-lint";PLATFORM="iOS_13"
- osx_image: xcode10.3
env: DEST='platform=iOS Simulator,OS=12.4,name=iPhone Xs'
env: ACTIONS="xcode,pod-lint";PLATFORM="iOS_12"
- osx_image: xcode10.3
env: DEST='platform=iOS Simulator,OS=11.4,name=iPhone X'
env: ACTIONS="xcode,pod-lint";PLATFORM="iOS_11"
- osx_image: xcode10.3
env: DEST='platform=iOS Simulator,OS=10.3.1,name=iPhone 7'
env: ACTIONS="xcode,pod-lint";PLATFORM="iOS_10"
- osx_image: xcode11.3
env: ACTIONS="spm";PLATFORM="iOS_13"
install:
- bundle install --gemfile=Example/Gemfile
- bundle exec --gemfile=Example/Gemfile pod install --project-directory=Example
script:
- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/Stagehand.xcworkspace -scheme "Stagehand Demo App" -sdk iphonesimulator -destination "$DEST" ONLY_ACTIVE_ARCH=NO | xcpretty
- bundle exec --gemfile=Example/Gemfile pod lib lint
- ./Scripts/ci.sh
branches:
only:
- master
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
iOSSnapshotTestCase: 9ab44cb5aa62b84d31847f40680112e15ec579a6
Stagehand: a4a339d2b1227bbffadd18877b2ae28cec416b1f
StagehandTesting: 410114f4d7583665f5e8498de1e4d631b0f49997
Stagehand: 6d360781f1e1ad7c15a16253952164c0035010d1
StagehandTesting: 941f1f1e381cf27e91a677895e249a3078e863e9

PODFILE CHECKSUM: e2058eb578e4d6fb432b015c43b4e221c1b70e87

Expand Down
42 changes: 42 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// swift-tools-version:5.0.1

//
// Copyright 2020 Square Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import PackageDescription

let package = Package(
name: "Stagehand",
platforms: [
.iOS(.v10),
],
products: [
.library(
name: "Stagehand",
targets: ["Stagehand"]
),
],
targets: [
.target(
name: "Stagehand",
dependencies: [],
path: "Sources/Stagehand"
),
],
swiftLanguageVersions: [.v5]
)

let version = Version(2, 0, 3)
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,30 @@ Stagehand provides a modern, type-safe API for building animations on iOS. Stage

## Installation

Stagehand is available through [CocoaPods](https://cocoapods.org). To install it, simply add the following line to your Podfile:
### CocoaPods

To install Stagehand via [CocoaPods](https://cocoapods.org), simply add the following line to your `Podfile`:

```ruby
pod 'Stagehand'
```

To install StagehandTesting, the animation snapshot testing utilities, add the following line to your test target definition in your `Podfile`:

```ruby
pod 'StagehandTesting'
```

### Swift Package Manager

To install Stagehand via [Swift Package Manager](https://github.com/apple/swift-package-manager), add the following to your `Package.swift`:

```swift
dependencies: [
.package(url: "https://github.com/cashapp/stagehand", from: "2.0.3"),
],
```

## Getting Started with Stagehand

An animation begins with the construction of an `Animation`. An `Animation` is generic over a type of element and acts as a definition of how that element should be animated.
Expand Down
182 changes: 182 additions & 0 deletions Scripts/build.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/usr/bin/env swift

import Foundation

// Usage: build.swift <spm|xcode> <platform> [<path_to_xcpretty>]

func execute(commandPath: String, arguments: [String], pipedTo pipeProcess: Process? = nil) throws {
let task = Process()
task.launchPath = commandPath
task.arguments = arguments

let argumentsString = arguments
.map { argument in
if argument.contains(" ") {
return "\"\(argument)\""
} else {
return argument
}
}
.joined(separator: " ")

if let pipeProcess = pipeProcess, let pipePath = pipeProcess.launchPath {
let pipe = Pipe()
task.standardOutput = pipe
pipeProcess.standardInput = pipe

print("Launching command: \(commandPath) \(argumentsString) | \(pipePath)")

} else {
print("Launching command: \(commandPath) \(argumentsString)")
}

task.launch()

pipeProcess?.launch()

task.waitUntilExit()

guard task.terminationStatus == 0 else {
throw TaskError.code(task.terminationStatus)
}
}

enum TaskError: Error {
case code(Int32)
}

enum Platform: String, CustomStringConvertible {
case iOS_13
case iOS_12
case iOS_11
case iOS_10

var destination: String {
switch self {
case .iOS_13:
return "platform=iOS Simulator,OS=13.3,name=iPhone 11 Pro"
case .iOS_12:
return "platform=iOS Simulator,OS=12.4,name=iPhone Xs"
case .iOS_11:
return "platform=iOS Simulator,OS=11.4,name=iPhone X"
case .iOS_10:
return "platform=iOS Simulator,OS=10.3.1,name=iPhone 7"
}
}

var description: String {
return rawValue
}
}

enum Task: String, CustomStringConvertible {
case spm
case xcode

var workspace: String? {
switch self {
case .xcode:
return "Example/Stagehand.xcworkspace"
case .spm:
return nil
}
}

var project: String? {
switch self {
case .spm:
return "generated/Stagehand.xcodeproj"
case .xcode:
return nil
}
}

var scheme: String {
switch self {
case .xcode:
return "Stagehand Demo App"
case .spm:
return "Stagehand-Package"
}
}

var shouldGenerateXcodeProject: Bool {
switch self {
case .spm:
return true
case .xcode:
return false
}
}

var shouldRunTests: Bool {
switch self {
case .spm:
return false
case .xcode:
return true
}
}

var description: String {
return rawValue
}
}

guard CommandLine.arguments.count > 2 else {
print("Usage: build.swift [spm|xcode] <platform>")
throw TaskError.code(1)
}

let rawTask = CommandLine.arguments[1]
let rawPlatform = CommandLine.arguments[2]

guard let task = Task(rawValue: rawTask) else {
print("Received unknown task \"\(rawTask)\"")
throw TaskError.code(1)
}

if task.shouldGenerateXcodeProject {
try execute(commandPath: "/usr/bin/swift", arguments: ["package", "generate-xcodeproj", "--output=generated/"])
}

guard let platform = Platform(rawValue: rawPlatform) else {
print("Received unknown platform \"\(rawPlatform)\"")
throw TaskError.code(1)
}

var xcodeBuildArguments: [String] = []

if let workspace = task.workspace {
xcodeBuildArguments.append("-workspace")
xcodeBuildArguments.append(workspace)
} else if let project = task.project {
xcodeBuildArguments.append("-project")
xcodeBuildArguments.append(project)
}

xcodeBuildArguments.append(
contentsOf: [
"-scheme", task.scheme,
"-sdk", "iphonesimulator",
"-PBXBuildsContinueAfterErrors=0",
"-destination", platform.destination,
"ONLY_ACTIVE_ARCH=NO",
]
)

xcodeBuildArguments.append("build")

if task.shouldRunTests {
xcodeBuildArguments.append("test")
}

let xcpretty: Process?
if CommandLine.arguments.count > 3 {
xcpretty = .init()
xcpretty?.launchPath = CommandLine.arguments[3]
} else {
xcpretty = nil
}

try execute(commandPath: "/usr/bin/xcodebuild", arguments: xcodeBuildArguments, pipedTo: xcpretty)
22 changes: 22 additions & 0 deletions Scripts/ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash -l
set -e

# Find the directory in which this script resides.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

actionstr=$(echo $ACTIONS | tr "," "\n")
for action in $actionstr ; do
case $action in
xcode)
$DIR/build.swift xcode $PLATFORM `which xcpretty`
;;

spm)
$DIR/build.swift spm $PLATFORM
;;

pod-lint)
bundle exec --gemfile=Example/Gemfile pod lib lint --verbose --fail-fast
;;
esac
done
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// limitations under the License.
//

import Foundation
import QuartzCore

/// An animation driver that is controlled by a `CADisplayLink`. This driver is intended for use with non-interactive
/// animations that have a specified duration.
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion Stagehand.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Pod::Spec.new do |s|

s.swift_version = '5.0.1'

s.source_files = 'Stagehand/Classes/Core/**/*'
s.source_files = 'Sources/Stagehand/**/*'

s.frameworks = 'CoreGraphics', 'UIKit'

Expand Down
2 changes: 1 addition & 1 deletion StagehandTesting.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Pod::Spec.new do |s|

s.swift_version = '5.0.1'

s.source_files = 'Stagehand/Classes/Testing/**/*'
s.source_files = 'Sources/StagehandTesting/**/*'

# The dependency on Stagehand is pinned to the same version as StagehandTesting. This is because
# StagehandTesting depends on internal methods inside Stagehand, so the normal rules of semantic
Expand Down

0 comments on commit 7e69236

Please sign in to comment.