1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::collections::BTreeMap;
use std::env::var_os as env;
use std::ffi::OsString;
pub use std::process::{Command, Stdio};
pub use cargo_metadata::camino::Utf8PathBuf;
use cargo_metadata::Message;
pub struct BinTest {
build_executables: BTreeMap<String, Utf8PathBuf>,
}
#[cfg(not(debug_assertions))]
const RELEASE_BUILD: bool = true;
#[cfg(debug_assertions)]
const RELEASE_BUILD: bool = false;
impl BinTest {
pub fn new() -> BinTest {
let mut cargo_build = Command::new(env("CARGO").unwrap_or_else(|| OsString::from("cargo")));
cargo_build
.args(["build", "--message-format", "json"])
.stdout(Stdio::piped());
if RELEASE_BUILD {
cargo_build.arg("--release");
}
let mut cargo_result = cargo_build.spawn().expect("'cargo build' success");
let mut build_executables = BTreeMap::new();
let reader = std::io::BufReader::new(cargo_result.stdout.take().unwrap());
for message in cargo_metadata::Message::parse_stream(reader) {
if let Message::CompilerArtifact(artifact) = message.unwrap() {
if let Some(executable) = artifact.executable {
build_executables.insert(
String::from(executable.file_stem().expect("filename")),
executable.to_path_buf(),
);
}
}
}
BinTest { build_executables }
}
pub fn list_executables(&self) -> std::collections::btree_map::Iter<'_, String, Utf8PathBuf> {
self.build_executables.iter()
}
pub fn command(&self, name: &str) -> Command {
Command::new(
self.build_executables
.get(name)
.unwrap_or_else(|| panic!("no such executable <<{}>>", name)),
)
}
}
impl Default for BinTest {
fn default() -> Self {
Self::new()
}
}