use std::io::IsTerminal;
#[derive(Debug, Clone)]
pub struct UiContext {
interactive: bool,
auto_yes: bool,
}
impl UiContext {
pub fn detect() -> Self {
let interactive = Self::detect_interactive();
Self {
interactive,
auto_yes: false,
}
}
pub fn non_interactive() -> Self {
Self {
interactive: false,
auto_yes: false,
}
}
pub fn with_auto_yes(mut self, yes: bool) -> Self {
self.auto_yes = yes;
self
}
pub fn is_interactive(&self) -> bool {
self.interactive
}
pub fn auto_yes(&self) -> bool {
self.auto_yes
}
pub fn use_fancy_output(&self) -> bool {
self.interactive
}
fn detect_interactive() -> bool {
if !std::io::stdout().is_terminal() {
return false;
}
if !std::io::stdin().is_terminal() {
return false;
}
if std::env::var("CI").is_ok() {
return false;
}
let ci_vars = [
"GITHUB_ACTIONS",
"GITLAB_CI",
"CIRCLECI",
"TRAVIS",
"JENKINS_URL",
"BUILDKITE",
"TEAMCITY_VERSION",
"TF_BUILD",
];
for var in ci_vars {
if std::env::var(var).is_ok() {
return false;
}
}
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn non_interactive_context() {
let ctx = UiContext::non_interactive();
assert!(!ctx.is_interactive());
assert!(!ctx.auto_yes());
}
#[test]
fn with_auto_yes() {
let ctx = UiContext::non_interactive().with_auto_yes(true);
assert!(ctx.auto_yes());
}
}