Skip to content

Commit 7ab3257

Browse files
committed
Merge pull request #26 from mpurland/build-scripts
Make builds consistent
2 parents bb7a67b + d210d3f commit 7ab3257

File tree

7 files changed

+359
-11
lines changed

7 files changed

+359
-11
lines changed

.travis.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
language: objective-c
2-
osx_image: xcode7
3-
4-
before_install:
5-
- gem install xcpretty-travis-formatter --no-rdoc --no-ri --no-document --quiet
6-
7-
install:
8-
- git submodule update -i --recursive
9-
10-
script:
11-
- set -o pipefail && xcodebuild -project Concurrent.xcodeproj -scheme Concurrent -sdk macosx ONLY_ACTIVE_ARCH=NO clean build test | xcpretty -c -f `xcpretty-travis-formatter`
12-
- set -o pipefail && xcodebuild -project Concurrent.xcodeproj -scheme Concurrent-iOS -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO clean build test | xcpretty -c -f `xcpretty-travis-formatter`
2+
osx_image: xcode7.1
3+
before_install: true
4+
install: true
5+
script: script/cibuild Concurrent Concurrent-iOS

script/LICENSE.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
**Copyright (c) 2013 Justin Spahr-Summers**
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7+
the Software, and to permit persons to whom the Software is furnished to do so,
8+
subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

script/README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# objc-build-scripts
2+
3+
This project is a collection of scripts created with two goals:
4+
5+
1. To standardize how Objective-C projects are bootstrapped after cloning
6+
1. To easily build Objective-C projects on continuous integration servers
7+
8+
## Scripts
9+
10+
Right now, there are two important scripts: [`bootstrap`](#bootstrap) and
11+
[`cibuild`](#cibuild). Both are Bash scripts, to maximize compatibility and
12+
eliminate pesky system configuration issues (like setting up a working Ruby
13+
environment).
14+
15+
The structure of the scripts on disk is meant to follow that of a typical Ruby
16+
project:
17+
18+
```
19+
script/
20+
bootstrap
21+
cibuild
22+
```
23+
24+
### bootstrap
25+
26+
This script is responsible for bootstrapping (initializing) your project after
27+
it's been checked out. Here, you should install or clone any dependencies that
28+
are required for a working build and development environment.
29+
30+
By default, the script will verify that [xctool][] is installed, then initialize
31+
and update submodules recursively. If any submodules contain `script/bootstrap`,
32+
that will be run as well.
33+
34+
To check that other tools are installed, you can set the `REQUIRED_TOOLS`
35+
environment variable before running `script/bootstrap`, or edit it within the
36+
script directly. Note that no installation is performed automatically, though
37+
this can always be added within your specific project.
38+
39+
### cibuild
40+
41+
This script is responsible for building the project, as you would want it built
42+
for continuous integration. This is preferable to putting the logic on the CI
43+
server itself, since it ensures that any changes are versioned along with the
44+
source.
45+
46+
By default, the script will run [`bootstrap`](#bootstrap), look for any Xcode
47+
workspace or project in the working directory, then build all targets/schemes
48+
(as found by `xcodebuild -list`) using [xctool][].
49+
50+
You can also specify the schemes to build by passing them into the script:
51+
52+
```sh
53+
script/cibuild ReactiveCocoa-Mac ReactiveCocoa-iOS
54+
```
55+
56+
As with the `bootstrap` script, there are several environment variables that can
57+
be used to customize behavior. They can be set on the command line before
58+
invoking the script, or the defaults changed within the script directly.
59+
60+
## Getting Started
61+
62+
To add the scripts to your project, read the contents of this repository into
63+
a `script` folder:
64+
65+
```
66+
$ git remote add objc-build-scripts https://github.com/jspahrsummers/objc-build-scripts.git
67+
$ git fetch objc-build-scripts
68+
$ git read-tree --prefix=script/ -u objc-build-scripts/master
69+
```
70+
71+
Then commit the changes, to incorporate the scripts into your own repository's
72+
history. You can also freely tweak the scripts for your specific project's
73+
needs.
74+
75+
To merge in upstream changes later:
76+
77+
```
78+
$ git fetch -p objc-build-scripts
79+
$ git merge --ff --squash -Xsubtree=script objc-build-scripts/master
80+
```
81+
82+
[xctool]: https://github.com/facebook/xctool

script/bootstrap

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/bash
2+
3+
export SCRIPT_DIR=$(dirname "$0")
4+
5+
##
6+
## Bootstrap Process
7+
##
8+
9+
main ()
10+
{
11+
local submodules=$(git submodule status)
12+
local result=$?
13+
14+
if [ "$result" -ne "0" ]
15+
then
16+
exit $result
17+
fi
18+
19+
if [ -n "$submodules" ]
20+
then
21+
echo "*** Updating submodules..."
22+
update_submodules
23+
fi
24+
}
25+
26+
bootstrap_submodule ()
27+
{
28+
local bootstrap="script/bootstrap"
29+
30+
if [ -e "$bootstrap" ]
31+
then
32+
echo "*** Bootstrapping $name..."
33+
"$bootstrap" >/dev/null
34+
else
35+
update_submodules
36+
fi
37+
}
38+
39+
update_submodules ()
40+
{
41+
git submodule sync --quiet && git submodule update --init && git submodule foreach --quiet bootstrap_submodule
42+
}
43+
44+
export -f bootstrap_submodule
45+
export -f update_submodules
46+
47+
main

script/cibuild

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/bin/bash
2+
3+
export SCRIPT_DIR=$(dirname "$0")
4+
5+
##
6+
## Configuration Variables
7+
##
8+
9+
SCHEMES="$@"
10+
11+
config ()
12+
{
13+
# The workspace to build.
14+
#
15+
# If not set and no workspace is found, the -workspace flag will not be passed
16+
# to `xctool`.
17+
#
18+
# Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will
19+
# take precedence.
20+
: ${XCWORKSPACE=$(find_pattern "*.xcworkspace")}
21+
22+
# The project to build.
23+
#
24+
# If not set and no project is found, the -project flag will not be passed
25+
# to `xctool`.
26+
#
27+
# Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will
28+
# take precedence.
29+
: ${XCODEPROJ=$(find_pattern "*.xcodeproj")}
30+
31+
# A bootstrap script to run before building.
32+
#
33+
# If this file does not exist, it is not considered an error.
34+
: ${BOOTSTRAP="$SCRIPT_DIR/bootstrap"}
35+
36+
# Extra options to pass to xctool.
37+
: ${XCTOOL_OPTIONS="RUN_CLANG_STATIC_ANALYZER=NO"}
38+
39+
# A whitespace-separated list of default schemes to build.
40+
#
41+
# Individual names can be quoted to avoid word splitting.
42+
: ${SCHEMES:=$(xcodebuild -list -project "$XCODEPROJ" 2>/dev/null | awk -f "$SCRIPT_DIR/schemes.awk")}
43+
44+
# A whitespace-separated list of executables that must be present and locatable.
45+
: ${REQUIRED_TOOLS="xctool"}
46+
47+
export XCWORKSPACE
48+
export XCODEPROJ
49+
export BOOTSTRAP
50+
export XCTOOL_OPTIONS
51+
export SCHEMES
52+
export REQUIRED_TOOLS
53+
}
54+
55+
##
56+
## Build Process
57+
##
58+
59+
main ()
60+
{
61+
config
62+
63+
if [ -n "$REQUIRED_TOOLS" ]
64+
then
65+
echo "*** Checking dependencies..."
66+
check_deps
67+
fi
68+
69+
if [ -f "$BOOTSTRAP" ]
70+
then
71+
echo "*** Bootstrapping..."
72+
"$BOOTSTRAP" || exit $?
73+
fi
74+
75+
echo "*** The following schemes will be built:"
76+
echo "$SCHEMES" | xargs -n 1 echo " "
77+
echo
78+
79+
echo "$SCHEMES" | xargs -n 1 | (
80+
local status=0
81+
82+
while read scheme
83+
do
84+
build_scheme "$scheme" || status=1
85+
done
86+
87+
exit $status
88+
)
89+
}
90+
91+
check_deps ()
92+
{
93+
for tool in $REQUIRED_TOOLS
94+
do
95+
which -s "$tool"
96+
if [ "$?" -ne "0" ]
97+
then
98+
echo "*** Error: $tool not found. Please install it and cibuild again."
99+
exit 1
100+
fi
101+
done
102+
}
103+
104+
find_pattern ()
105+
{
106+
ls -d $1 2>/dev/null | head -n 1
107+
}
108+
109+
run_xctool ()
110+
{
111+
if [ -n "$XCWORKSPACE" ]
112+
then
113+
xctool -workspace "$XCWORKSPACE" $XCTOOL_OPTIONS "$@" 2>&1
114+
elif [ -n "$XCODEPROJ" ]
115+
then
116+
xctool -project "$XCODEPROJ" $XCTOOL_OPTIONS "$@" 2>&1
117+
else
118+
echo "*** No workspace or project file found."
119+
exit 1
120+
fi
121+
}
122+
123+
parse_build ()
124+
{
125+
awk -f "$SCRIPT_DIR/xctool.awk" 2>&1 >/dev/null
126+
}
127+
128+
build_scheme ()
129+
{
130+
local scheme=$1
131+
132+
echo "*** Building and testing $scheme..."
133+
echo
134+
135+
local sdkflag=
136+
local action=test
137+
138+
# Determine whether we can run unit tests for this target.
139+
run_xctool -scheme "$scheme" run-tests | parse_build
140+
141+
local awkstatus=$?
142+
143+
if [ "$awkstatus" -eq "1" ]
144+
then
145+
# SDK not found, try for iphonesimulator.
146+
sdkflag="-sdk iphonesimulator"
147+
148+
# Determine whether the unit tests will run with iphonesimulator
149+
run_xctool $sdkflag -scheme "$scheme" run-tests | parse_build
150+
151+
awkstatus=$?
152+
153+
if [ "$awkstatus" -ne "0" ]
154+
then
155+
# Unit tests will not run on iphonesimulator.
156+
sdkflag=""
157+
fi
158+
fi
159+
160+
if [ "$awkstatus" -ne "0" ]
161+
then
162+
# Unit tests aren't supported.
163+
action=build
164+
fi
165+
166+
run_xctool $sdkflag -scheme "$scheme" $action
167+
}
168+
169+
export -f build_scheme
170+
export -f run_xctool
171+
export -f parse_build
172+
173+
main

script/schemes.awk

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
BEGIN {
2+
FS = "\n";
3+
}
4+
5+
/Schemes:/ {
6+
while (getline && $0 != "") {
7+
sub(/^ +/, "");
8+
print "'" $0 "'";
9+
}
10+
}

script/xctool.awk

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Exit statuses:
2+
#
3+
# 0 - No errors found.
4+
# 1 - Wrong SDK. Retry with SDK `iphonesimulator`.
5+
# 2 - Missing target.
6+
7+
BEGIN {
8+
status = 0;
9+
}
10+
11+
{
12+
print;
13+
}
14+
15+
/Testing with the '(.+)' SDK is not yet supported/ {
16+
status = 1;
17+
}
18+
19+
/does not contain a target named/ {
20+
status = 2;
21+
}
22+
23+
END {
24+
exit status;
25+
}

0 commit comments

Comments
 (0)