Skip to content

Commit d4a5fce

Browse files
committed
Touch up the iOS deploy script
1 parent 3800c73 commit d4a5fce

File tree

1 file changed

+90
-47
lines changed

1 file changed

+90
-47
lines changed

ci/ios/deploy_and_run_on_ios_simulator.rs

Lines changed: 90 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,68 @@
77
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
10-
//
10+
1111
// This is a script to deploy and execute a binary on an iOS simulator.
12-
// The primary use of this is to be able to run unit tests on the simulator and retrieve the results.
12+
// The primary use of this is to be able to run unit tests on the simulator and
13+
// retrieve the results.
1314
//
14-
// To do this through Cargo instead, use Dinghy (https://github.com/snipsco/dinghy):
15-
// cargo dinghy install, then cargo dinghy test.
15+
// To do this through Cargo instead, use Dinghy
16+
// (https://github.com/snipsco/dinghy): cargo dinghy install, then cargo dinghy
17+
// test.
1618

1719
use std::env;
18-
use std::fs::File;
20+
use std::fs::{self, File};
1921
use std::io::Write;
2022
use std::path::Path;
2123
use std::process;
2224
use std::process::Command;
2325

26+
macro_rules! t {
27+
($e:expr) => (match $e {
28+
Ok(e) => e,
29+
Err(e) => panic!("{} failed with: {}", stringify!($e), e),
30+
})
31+
}
32+
2433
// Step one: Wrap as an app
2534
fn package_as_simulator_app(crate_name: &str, test_binary_path: &Path) {
2635
println!("Packaging simulator app");
27-
Command::new("rm").arg("-rf").arg("ios_simulator_app").status().unwrap();
28-
Command::new("mkdir").arg("ios_simulator_app").check_status();
29-
Command::new("cp").arg(test_binary_path).arg(["ios_simulator_app/", crate_name].join("")).check_status();
30-
let mut f = File::create("ios_simulator_app/Info.plist").unwrap();
31-
f.write_all(&[
32-
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
33-
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">",
34-
"<plist version=\"1.0\">",
35-
" <dict>",
36-
" <key>CFBundleExecutable</key>",
37-
&[" <string>", crate_name, "</string>"].join(""),
38-
" <key>CFBundleIdentifier</key>",
39-
" <string>com.rust.unittests</string>",
40-
" </dict>",
41-
"</plist>"].join("\n").into_bytes()).unwrap();
36+
drop(fs::remove_dir_all("ios_simulator_app"));
37+
t!(fs::create_dir("ios_simulator_app"));
38+
t!(fs::copy(test_binary_path,
39+
Path::new("ios_simulator_app").join(crate_name)));
40+
41+
let mut f = t!(File::create("ios_simulator_app/Info.plist"));
42+
t!(f.write_all(format!(r#"
43+
<?xml version="1.0" encoding="UTF-8"?>
44+
<!DOCTYPE plist PUBLIC
45+
"-//Apple//DTD PLIST 1.0//EN"
46+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
47+
<plist version="1.0">
48+
<dict>
49+
<key>CFBundleExecutable</key>
50+
<string>{}</string>
51+
<key>CFBundleIdentifier</key>
52+
<string>com.rust.unittests</string>
53+
</dict>
54+
</plist>
55+
"#, crate_name).as_bytes()));
4256
}
4357

4458
// Step two: Start the iOS simulator
4559
fn start_simulator() {
4660
println!("Looking for iOS simulator");
47-
let output = Command::new("xcrun").arg("simctl").arg("list").output().unwrap();
61+
let output = t!(Command::new("xcrun").arg("simctl").arg("list").output());
62+
assert!(output.status.success());
4863
let mut simulator_exists = false;
4964
let mut simulator_booted = false;
5065
let mut found_rust_sim = false;
51-
let stdout = String::from_utf8(output.stdout).unwrap();
66+
let stdout = t!(String::from_utf8(output.stdout));
5267
for line in stdout.lines() {
5368
if line.contains("rust_ios") {
5469
if found_rust_sim {
55-
panic!("Duplicate rust_ios simulators found. Please double-check xcrun simctl list.");
70+
panic!("Duplicate rust_ios simulators found. Please \
71+
double-check xcrun simctl list.");
5672
}
5773
simulator_exists = true;
5874
simulator_booted = line.contains("(Booted)");
@@ -62,43 +78,69 @@ fn start_simulator() {
6278

6379
if simulator_exists == false {
6480
println!("Creating iOS simulator");
65-
Command::new("xcrun").arg("simctl").arg("create").arg("rust_ios")
66-
.arg("com.apple.CoreSimulator.SimDeviceType.iPhone-SE").arg("com.apple.CoreSimulator.SimRuntime.iOS-10-2").check_status();
81+
Command::new("xcrun")
82+
.arg("simctl")
83+
.arg("create")
84+
.arg("rust_ios")
85+
.arg("com.apple.CoreSimulator.SimDeviceType.iPhone-SE")
86+
.arg("com.apple.CoreSimulator.SimRuntime.iOS-10-2")
87+
.check_status();
6788
} else if simulator_booted == true {
6889
println!("Shutting down already-booted simulator");
69-
Command::new("xcrun").arg("simctl").arg("shutdown").arg("rust_ios").check_status();
90+
Command::new("xcrun")
91+
.arg("simctl")
92+
.arg("shutdown")
93+
.arg("rust_ios")
94+
.check_status();
7095
}
7196

7297
println!("Starting iOS simulator");
73-
// We can't uninstall the app (if present) as that will hang if the simulator isn't completely booted;just erase the simulator instead.
98+
// We can't uninstall the app (if present) as that will hang if the
99+
// simulator isn't completely booted; just erase the simulator instead.
74100
Command::new("xcrun").arg("simctl").arg("erase").arg("rust_ios").check_status();
75101
Command::new("xcrun").arg("simctl").arg("boot").arg("rust_ios").check_status();
76102
}
77103

78104
// Step three: Install the app
79-
fn install_app_to_simulator() {
105+
fn install_app_to_simulator() {
80106
println!("Installing app to simulator");
81-
Command::new("xcrun").arg("simctl").arg("install").arg("booted").arg("ios_simulator_app/").check_status();
107+
Command::new("xcrun")
108+
.arg("simctl")
109+
.arg("install")
110+
.arg("booted")
111+
.arg("ios_simulator_app/")
112+
.check_status();
82113
}
83114

84115
// Step four: Run the app
85116
fn run_app_on_simulator() {
86117
println!("Running app");
87-
let output = Command::new("xcrun").arg("simctl").arg("launch").arg("--console").arg("booted").arg("com.rust.unittests").output().unwrap();
88-
let mut test_run_passed = false;
89-
let stdout = String::from_utf8(output.stdout).unwrap();
90-
for line in stdout.lines() {
91-
println!("{}", line);
92-
93-
if test_run_passed == false {
94-
// Based on all.rs test output
95-
test_run_passed = line.contains("PASSED") && line.contains("tests");
96-
}
97-
}
118+
let output = t!(Command::new("xcrun")
119+
.arg("simctl")
120+
.arg("launch")
121+
.arg("--console")
122+
.arg("booted")
123+
.arg("com.rust.unittests")
124+
.output());
125+
126+
println!("stdout --\n{}\n", String::from_utf8_lossy(&output.stdout));
127+
println!("stderr --\n{}\n", String::from_utf8_lossy(&output.stderr));
128+
129+
let stdout = String::from_utf8_lossy(&output.stdout);
130+
let passed = stdout.lines()
131+
.find(|l| l.contains("PASSED"))
132+
.map(|l| l.contains("tests"))
133+
.unwrap_or(false);
98134

99135
println!("Shutting down simulator");
100-
Command::new("xcrun").arg("simctl").arg("shutdown").arg("rust_ios").check_status();
101-
assert!(test_run_passed);
136+
Command::new("xcrun")
137+
.arg("simctl")
138+
.arg("shutdown")
139+
.arg("rust_ios")
140+
.check_status();
141+
if !passed {
142+
panic!("tests didn't pass");
143+
}
102144
}
103145

104146
trait CheckStatus {
@@ -107,22 +149,23 @@ trait CheckStatus {
107149

108150
impl CheckStatus for Command {
109151
fn check_status(&mut self) {
110-
assert!(self.status().unwrap().success());
152+
println!("\trunning: {:?}", self);
153+
assert!(t!(self.status()).success());
111154
}
112155
}
113156

114-
pub fn main() {
157+
fn main() {
115158
let args: Vec<String> = env::args().collect();
116159
if args.len() != 2 {
117-
println!("Usage: {:?} executable", Path::new(&args[0]).file_name().unwrap());
160+
println!("Usage: {} <executable>", args[0]);
118161
process::exit(-1);
119162
}
120-
163+
121164
let test_binary_path = Path::new(&args[1]);
122165
let crate_name = test_binary_path.file_name().unwrap();
123166

124167
package_as_simulator_app(crate_name.to_str().unwrap(), test_binary_path);
125168
start_simulator();
126169
install_app_to_simulator();
127170
run_app_on_simulator();
128-
}
171+
}

0 commit comments

Comments
 (0)