pub fn normalize_command_for_shell(command: &str) -> String {
if !cfg!(windows) {
return command.to_string();
}
let (_, flag) = crate::shell::shell_and_flag();
if flag != "/C" {
return command.to_string();
}
let bytes = command.as_bytes();
let mut result = Vec::with_capacity(bytes.len() + 16);
let mut in_single = false;
let mut in_double = false;
for (i, &b) in bytes.iter().enumerate() {
if b == b'\'' && !in_double {
in_single = !in_single;
} else if b == b'"' && !in_single {
in_double = !in_double;
} else if b == b';' && !in_single && !in_double {
result.extend_from_slice(b" && ");
continue;
}
result.push(b);
let _ = i;
}
String::from_utf8(result).unwrap_or_else(|_| command.to_string())
}
pub fn contains_auth_flow(output: &str) -> bool {
let lower = output.to_lowercase();
const STRONG_SIGNALS: &[&str] = &[
"devicelogin",
"deviceauth",
"device_code",
"device code",
"device-code",
"verification_uri",
"user_code",
"one-time code",
];
if STRONG_SIGNALS.iter().any(|s| lower.contains(s)) {
return true;
}
const WEAK_SIGNALS: &[&str] = &[
"enter the code",
"enter this code",
"enter code:",
"use the code",
"use a web browser to open",
"open the page",
"authenticate by visiting",
"sign in with the code",
"sign in using a code",
"verification code",
"authorize this device",
"waiting for authentication",
"waiting for login",
"waiting for you to authenticate",
"open your browser",
"open in your browser",
];
let has_weak_signal = WEAK_SIGNALS.iter().any(|s| lower.contains(s));
if !has_weak_signal {
return false;
}
lower.contains("http://") || lower.contains("https://")
}