-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathutils.rs
129 lines (110 loc) · 3.08 KB
/
utils.rs
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
122
123
124
125
126
127
128
129
use anyhow::Result;
use assert_cmd::assert::Assert;
use assert_cmd::cargo::cargo_bin;
use assert_cmd::prelude::OutputAssertExt;
use rexpect::process::wait::WaitStatus;
use rexpect::session::PtySession;
use std::env;
use std::ffi::OsStr;
use std::io;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
#[derive(Debug)]
pub struct Ion {
cmd: Command,
}
impl Ion {
pub fn new() -> Self {
let program = cargo_bin("ion");
let cmd = Command::new(program);
Self { cmd }
}
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
self.cmd.arg(arg);
self
}
pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Self
where
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
self.cmd.env(key, val);
self
}
pub fn output(&mut self) -> io::Result<Output> {
self.cmd.output()
}
pub fn assert(&mut self) -> Assert {
OutputAssertExt::assert(self)
}
pub fn spawn(&self, timeout_ms: Option<u64>) -> Result<PtySession> {
let mut command = Command::new(cargo_bin("ion"));
for arg in self.cmd.get_args() {
command.arg(arg);
}
for (key, val) in self.cmd.get_envs() {
if let Some(val) = val {
command.env(key, val);
}
}
if let Some(cwd) = self.cmd.get_current_dir() {
command.current_dir(cwd);
}
Ok(rexpect::session::spawn_command(command, timeout_ms)?)
}
pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Self {
self.cmd.current_dir(dir);
self
}
pub fn packages_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Self {
self.current_dir(packages_dir().join(dir));
self
}
pub fn scratch_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Self {
self.current_dir(scratch_dir().join(dir));
self
}
pub fn packages(&mut self) -> &mut Self {
self.current_dir(packages_dir());
self
}
pub fn scratch(&mut self) -> &mut Self {
self.current_dir(scratch_dir());
self
}
}
impl Default for Ion {
fn default() -> Self {
Self::new()
}
}
impl<'c> OutputAssertExt for &'c mut Ion {
fn assert(self) -> Assert {
let output = match self.output() {
Ok(output) => output,
Err(err) => {
panic!("Failed to spawn {self:?}: {err}");
}
};
Assert::new(output).append_context("command", format!("{:?}", self.cmd))
}
}
pub trait AssertSuccess {
fn success(&mut self) -> Result<()>;
}
impl AssertSuccess for PtySession {
fn success(&mut self) -> Result<()> {
if let WaitStatus::Exited(_, 0) = self.process.wait()? {
Ok(())
} else {
Err(anyhow::anyhow!("Process exited with non-zero status"))
}
}
}
pub fn packages_dir() -> PathBuf {
let root = env::var("CARGO_MANIFEST_DIR").unwrap();
PathBuf::from(root).join("tests").join("packages")
}
pub fn scratch_dir() -> PathBuf {
packages_dir().join("scratch")
}