From 45ee7b7ccc5e5a027fa834f1ac25237494b8db25 Mon Sep 17 00:00:00 2001 From: Aron Cedercrantz Date: Mon, 21 Apr 2014 17:23:11 +0200 Subject: [PATCH 1/4] Add build and bootstrap scripts. - These are read in from https://github.com/jspahrsummers/objc-build-scripts. --- script/LICENSE.md | 18 ++++++ script/README.md | 82 ++++++++++++++++++++++++++ script/bootstrap | 80 +++++++++++++++++++++++++ script/cibuild | 142 +++++++++++++++++++++++++++++++++++++++++++++ script/schemes.awk | 12 ++++ script/xctool.awk | 25 ++++++++ 6 files changed, 359 insertions(+) create mode 100644 script/LICENSE.md create mode 100644 script/README.md create mode 100755 script/bootstrap create mode 100755 script/cibuild create mode 100644 script/schemes.awk create mode 100644 script/xctool.awk diff --git a/script/LICENSE.md b/script/LICENSE.md new file mode 100644 index 0000000..8d92384 --- /dev/null +++ b/script/LICENSE.md @@ -0,0 +1,18 @@ +**Copyright (c) 2013 Justin Spahr-Summers** + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/script/README.md b/script/README.md new file mode 100644 index 0000000..f66206f --- /dev/null +++ b/script/README.md @@ -0,0 +1,82 @@ +# objc-build-scripts + +This project is a collection of scripts created with two goals: + + 1. To standardize how Objective-C projects are bootstrapped after cloning + 1. To easily build Objective-C projects on continuous integration servers + +## Scripts + +Right now, there are two important scripts: [`bootstrap`](#bootstrap) and +[`cibuild`](#cibuild). Both are Bash scripts, to maximize compatibility and +eliminate pesky system configuration issues (like setting up a working Ruby +environment). + +The structure of the scripts on disk is meant to follow that of a typical Ruby +project: + +``` +script/ + bootstrap + cibuild +``` + +### bootstrap + +This script is responsible for bootstrapping (initializing) your project after +it's been checked out. Here, you should install or clone any dependencies that +are required for a working build and development environment. + +By default, the script will verify that [xctool][] is installed, then initialize +and update submodules recursively. If any submodules contain `script/bootstrap`, +that will be run as well. + +To check that other tools are installed, you can set the `REQUIRED_TOOLS` +environment variable before running `script/bootstrap`, or edit it within the +script directly. Note that no installation is performed automatically, though +this can always be added within your specific project. + +### cibuild + +This script is responsible for building the project, as you would want it built +for continuous integration. This is preferable to putting the logic on the CI +server itself, since it ensures that any changes are versioned along with the +source. + +By default, the script will run [`bootstrap`](#bootstrap), look for any Xcode +workspace or project in the working directory, then build all targets/schemes +(as found by `xcodebuild -list`) using [xctool][]. + +You can also specify the schemes to build by passing them into the script: + +```sh +script/cibuild ReactiveCocoa-Mac ReactiveCocoa-iOS +``` + +As with the `bootstrap` script, there are several environment variables that can +be used to customize behavior. They can be set on the command line before +invoking the script, or the defaults changed within the script directly. + +## Getting Started + +To add the scripts to your project, read the contents of this repository into +a `script` folder: + +``` +$ git remote add objc-build-scripts https://github.com/jspahrsummers/objc-build-scripts.git +$ git fetch objc-build-scripts +$ git read-tree --prefix=script/ -u objc-build-scripts/master +``` + +Then commit the changes, to incorporate the scripts into your own repository's +history. You can also freely tweak the scripts for your specific project's +needs. + +To merge in upstream changes later: + +``` +$ git fetch -p objc-build-scripts +$ git merge --ff --squash -Xsubtree=script objc-build-scripts/master +``` + +[xctool]: https://github.com/facebook/xctool diff --git a/script/bootstrap b/script/bootstrap new file mode 100755 index 0000000..89cbb8e --- /dev/null +++ b/script/bootstrap @@ -0,0 +1,80 @@ +#!/bin/bash + +export SCRIPT_DIR=$(dirname "$0") + +## +## Configuration Variables +## + +config () +{ + # A whitespace-separated list of executables that must be present and locatable. + : ${REQUIRED_TOOLS="xctool"} + + export REQUIRED_TOOLS +} + +## +## Bootstrap Process +## + +main () +{ + config + + if [ -n "$REQUIRED_TOOLS" ] + then + echo "*** Checking dependencies..." + check_deps + fi + + local submodules=$(git submodule status) + local result=$? + + if [ "$result" -ne "0" ] + then + exit $result + fi + + if [ -n "$submodules" ] + then + echo "*** Updating submodules..." + update_submodules + fi +} + +check_deps () +{ + for tool in $REQUIRED_TOOLS + do + which -s "$tool" + if [ "$?" -ne "0" ] + then + echo "*** Error: $tool not found. Please install it and bootstrap again." + exit 1 + fi + done +} + +bootstrap_submodule () +{ + local bootstrap="script/bootstrap" + + if [ -e "$bootstrap" ] + then + echo "*** Bootstrapping $name..." + "$bootstrap" >/dev/null + else + update_submodules + fi +} + +update_submodules () +{ + git submodule sync --quiet && git submodule update --init && git submodule foreach --quiet bootstrap_submodule +} + +export -f bootstrap_submodule +export -f update_submodules + +main diff --git a/script/cibuild b/script/cibuild new file mode 100755 index 0000000..e9aa65a --- /dev/null +++ b/script/cibuild @@ -0,0 +1,142 @@ +#!/bin/bash + +export SCRIPT_DIR=$(dirname "$0") + +## +## Configuration Variables +## + +SCHEMES="$@" + +config () +{ + # The workspace to build. + # + # If not set and no workspace is found, the -workspace flag will not be passed + # to `xctool`. + # + # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will + # take precedence. + : ${XCWORKSPACE=$(find_pattern "*.xcworkspace")} + + # The project to build. + # + # If not set and no project is found, the -project flag will not be passed + # to `xctool`. + # + # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will + # take precedence. + : ${XCODEPROJ=$(find_pattern "*.xcodeproj")} + + # A bootstrap script to run before building. + # + # If this file does not exist, it is not considered an error. + : ${BOOTSTRAP="$SCRIPT_DIR/bootstrap"} + + # Extra options to pass to xctool. + : ${XCTOOL_OPTIONS="RUN_CLANG_STATIC_ANALYZER=NO"} + + # A whitespace-separated list of default schemes to build. + # + # Individual names can be quoted to avoid word splitting. + : ${SCHEMES:=$(xcodebuild -list 2>/dev/null | awk -f "$SCRIPT_DIR/schemes.awk")} + + export XCWORKSPACE + export XCODEPROJ + export BOOTSTRAP + export XCTOOL_OPTIONS + export SCHEMES +} + +## +## Build Process +## + +main () +{ + config + + if [ -f "$BOOTSTRAP" ] + then + echo "*** Bootstrapping..." + "$BOOTSTRAP" || exit $? + fi + + echo "*** The following schemes will be built:" + echo "$SCHEMES" | xargs -n 1 echo " " + echo + + echo "$SCHEMES" | xargs -n 1 | ( + local status=0 + + while read scheme + do + build_scheme "$scheme" || status=1 + done + + exit $status + ) +} + +find_pattern () +{ + ls -d $1 2>/dev/null | head -n 1 +} + +run_xctool () +{ + if [ -n "$XCWORKSPACE" ] + then + xctool -workspace "$XCWORKSPACE" $XCTOOL_OPTIONS "$@" 2>&1 + elif [ -n "$XCODEPROJ" ] + then + xctool -project "$XCODEPROJ" $XCTOOL_OPTIONS "$@" 2>&1 + else + echo "*** No workspace or project file found." + exit 1 + fi +} + +parse_build () +{ + awk -f "$SCRIPT_DIR/xctool.awk" 2>&1 >/dev/null +} + +build_scheme () +{ + local scheme=$1 + + echo "*** Cleaning $scheme..." + run_xctool -scheme "$scheme" clean >/dev/null || exit $? + + echo "*** Building and testing $scheme..." + echo + + local sdkflag= + local action=test + + # Determine whether we can run unit tests for this target. + run_xctool -scheme "$scheme" run-tests | parse_build + + local awkstatus=$? + + if [ "$awkstatus" -ne "0" ] + then + # Unit tests aren't supported. + action=build + fi + + if [ "$awkstatus" -eq "1" ] + then + # Build for iOS. + sdkflag="-sdk iphonesimulator" + fi + + run_xctool $sdkflag -scheme "$scheme" $action +} + +export -f build_scheme +export -f run_xctool +export -f parse_build + +main diff --git a/script/schemes.awk b/script/schemes.awk new file mode 100644 index 0000000..d101b4f --- /dev/null +++ b/script/schemes.awk @@ -0,0 +1,12 @@ +BEGIN { + FS = "\n"; +} + +/Targets:/ { + while (getline && $0 != "") { + if ($0 ~ /Test/) continue; + + sub(/^ +/, ""); + print "'" $0 "'"; + } +} diff --git a/script/xctool.awk b/script/xctool.awk new file mode 100644 index 0000000..f613258 --- /dev/null +++ b/script/xctool.awk @@ -0,0 +1,25 @@ +# Exit statuses: +# +# 0 - No errors found. +# 1 - Wrong SDK. Retry with SDK `iphonesimulator`. +# 2 - Missing target. + +BEGIN { + status = 0; +} + +{ + print; +} + +/Testing with the '(.+)' SDK is not yet supported/ { + status = 1; +} + +/does not contain a target named/ { + status = 2; +} + +END { + exit status; +} From a0543dd8d75197b252bd97fb573b8c131aa5cdf6 Mon Sep 17 00:00:00 2001 From: Aron Cedercrantz Date: Mon, 21 Apr 2014 17:24:33 +0200 Subject: [PATCH 2/4] Add Travis-CI integration config. - Makes use of the `cibuild` script from jspahrsummers/objc-build-scripts. - E-mail notifications are turned off. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d0c76b9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: objective-c +script: script/cibuild +notifications: + email: false From 91264b07b4e7ebf640ceeba0e083a3547b7da0ea Mon Sep 17 00:00:00 2001 From: Aron Cedercrantz Date: Mon, 21 Apr 2014 17:27:26 +0200 Subject: [PATCH 3/4] Add Travis-CI build status to readme. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8744ca2..842296a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#Butter# +#Butter [![Build Status](https://travis-ci.org/ButterKit/Butter.svg?branch=master)](https://travis-ci.org/ButterKit/Butter)# Butter is a framework for OS X that seeks to provide a set of commonly used controls which are full replacements for their cell-based AppKit counterparts. This framework is still a work in progress, but it is **usable in production apps.** From 224691ed722fd8876bce2758655da77c29a4bd51 Mon Sep 17 00:00:00 2001 From: Aron Cedercrantz Date: Mon, 21 Apr 2014 20:47:07 +0200 Subject: [PATCH 4/4] Remove xctool bootstrap dependency. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The project doesn’t depend on it, rather the `cibuild` script depends on xctool, thus it should be removed. --- script/bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/bootstrap b/script/bootstrap index 89cbb8e..855d55b 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -9,7 +9,7 @@ export SCRIPT_DIR=$(dirname "$0") config () { # A whitespace-separated list of executables that must be present and locatable. - : ${REQUIRED_TOOLS="xctool"} + : ${REQUIRED_TOOLS=""} export REQUIRED_TOOLS }