use std::ffi::OsString;
use tracing::info;
pub struct EnvVars;
impl EnvVars {
pub const PATH: &'static str = "PATH";
pub const HOME: &'static str = "HOME";
pub const CI: &'static str = "CI";
pub const SKIP: &'static str = "SKIP";
pub const PREK_HOME: &'static str = "PREK_HOME";
pub const PREK_COLOR: &'static str = "PREK_COLOR";
pub const PREK_SKIP: &'static str = "PREK_SKIP";
pub const PREK_ALLOW_NO_CONFIG: &'static str = "PREK_ALLOW_NO_CONFIG";
pub const PREK_NO_CONCURRENCY: &'static str = "PREK_NO_CONCURRENCY";
pub const PREK_NO_FAST_PATH: &'static str = "PREK_NO_FAST_PATH";
pub const PREK_UV_SOURCE: &'static str = "PREK_UV_SOURCE";
pub const PREK_NATIVE_TLS: &'static str = "PREK_NATIVE_TLS";
pub const SSL_CERT_FILE: &'static str = "SSL_CERT_FILE";
pub const PREK_CONTAINER_RUNTIME: &'static str = "PREK_CONTAINER_RUNTIME";
pub const PREK_INTERNAL__TEST_DIR: &'static str = "PREK_INTERNAL__TEST_DIR";
pub const PREK_INTERNAL__SORT_FILENAMES: &'static str = "PREK_INTERNAL__SORT_FILENAMES";
pub const PREK_INTERNAL__SKIP_POST_CHECKOUT: &'static str = "PREK_INTERNAL__SKIP_POST_CHECKOUT";
pub const PREK_INTERNAL__RUN_ORIGINAL_PRE_COMMIT: &'static str =
"PREK_INTERNAL__RUN_ORIGINAL_PRE_COMMIT";
pub const PREK_INTERNAL__GO_BINARY_NAME: &'static str = "PREK_INTERNAL__GO_BINARY_NAME";
pub const PREK_INTERNAL__NODE_BINARY_NAME: &'static str = "PREK_INTERNAL__NODE_BINARY_NAME";
pub const PREK_GENERATE: &'static str = "PREK_GENERATE";
pub const VIRTUAL_ENV: &'static str = "VIRTUAL_ENV";
pub const PYTHONHOME: &'static str = "PYTHONHOME";
pub const UV_PYTHON: &'static str = "UV_PYTHON";
pub const UV_CACHE_DIR: &'static str = "UV_CACHE_DIR";
pub const UV_PYTHON_INSTALL_DIR: &'static str = "UV_PYTHON_INSTALL_DIR";
pub const UV_MANAGED_PYTHON: &'static str = "UV_MANAGED_PYTHON";
pub const UV_NO_MANAGED_PYTHON: &'static str = "UV_NO_MANAGED_PYTHON";
pub const NPM_CONFIG_USERCONFIG: &'static str = "NPM_CONFIG_USERCONFIG";
pub const NPM_CONFIG_PREFIX: &'static str = "NPM_CONFIG_PREFIX";
pub const NODE_PATH: &'static str = "NODE_PATH";
pub const GOTOOLCHAIN: &'static str = "GOTOOLCHAIN";
pub const GOROOT: &'static str = "GOROOT";
pub const GOPATH: &'static str = "GOPATH";
pub const GOBIN: &'static str = "GOBIN";
pub const LUA_PATH: &'static str = "LUA_PATH";
pub const LUA_CPATH: &'static str = "LUA_CPATH";
pub const GEM_HOME: &'static str = "GEM_HOME";
pub const GEM_PATH: &'static str = "GEM_PATH";
pub const BUNDLE_IGNORE_CONFIG: &'static str = "BUNDLE_IGNORE_CONFIG";
pub const BUNDLE_GEMFILE: &'static str = "BUNDLE_GEMFILE";
}
impl EnvVars {
pub const PRE_COMMIT_HOME: &'static str = "PRE_COMMIT_HOME";
const PRE_COMMIT_ALLOW_NO_CONFIG: &'static str = "PRE_COMMIT_ALLOW_NO_CONFIG";
const PRE_COMMIT_NO_CONCURRENCY: &'static str = "PRE_COMMIT_NO_CONCURRENCY";
}
impl EnvVars {
pub fn var_os(name: &str) -> Option<OsString> {
#[allow(clippy::disallowed_methods)]
std::env::var_os(name).or_else(|| {
let name = Self::pre_commit_name(name)?;
let val = std::env::var_os(name)?;
info!("Falling back to pre-commit environment variable for {name}");
Some(val)
})
}
pub fn is_set(name: &str) -> bool {
Self::var_os(name).is_some()
}
pub fn var(name: &str) -> Result<String, std::env::VarError> {
match Self::var_os(name) {
Some(s) => s.into_string().map_err(std::env::VarError::NotUnicode),
None => Err(std::env::VarError::NotPresent),
}
}
pub fn var_as_bool(name: &str) -> Option<bool> {
if let Some(val) = EnvVars::var_os(name)
&& let Some(val) = val.to_str()
&& let Some(val) = EnvVars::parse_boolish(val)
{
Some(val)
} else {
None
}
}
fn parse_boolish(val: &str) -> Option<bool> {
const TRUE_LITERALS: [&str; 6] = ["y", "yes", "t", "true", "on", "1"];
const FALSE_LITERALS: [&str; 6] = ["n", "no", "f", "false", "off", "0"];
let val = val.to_lowercase();
let pat = val.as_str();
if TRUE_LITERALS.contains(&pat) {
Some(true)
} else if FALSE_LITERALS.contains(&pat) {
Some(false)
} else {
None
}
}
fn pre_commit_name(name: &str) -> Option<&str> {
match name {
Self::PREK_ALLOW_NO_CONFIG => Some(Self::PRE_COMMIT_ALLOW_NO_CONFIG),
Self::PREK_NO_CONCURRENCY => Some(Self::PRE_COMMIT_NO_CONCURRENCY),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::EnvVars;
#[test]
fn test_parse_boolish() {
let true_values = ["y", "yes", "t", "true", "on", "1"];
let false_values = ["n", "no", "f", "false", "off", "0"];
for val in true_values {
assert_eq!(EnvVars::parse_boolish(val), Some(true),);
assert_eq!(EnvVars::parse_boolish(&val.to_uppercase()), Some(true),);
}
for val in false_values {
assert_eq!(EnvVars::parse_boolish(val), Some(false),);
assert_eq!(EnvVars::parse_boolish(&val.to_uppercase()), Some(false),);
}
assert_eq!(EnvVars::parse_boolish("maybe"), None);
assert_eq!(EnvVars::parse_boolish(""), None);
assert_eq!(EnvVars::parse_boolish("123"), None);
}
}