//! Lectura de variables de entorno del proyecto durante el renombre `takana` → `takana`. //! //! # Por qué existe esto en vez de un `sed` //! //! Las variables de entorno del proyecto **no son superficie interna**: son contrato de usuario, //! del mismo tipo que un verbo de CLI. Hay knobs del instalador entre ellas (`HAMMER_TZ`, //! `HAMMER_KEYMAP`, `HAMMER_HOSTNAME`), el entorno del worker las trae puestas desde perfiles de //! shell y units de systemd que **viven fuera del repo**, y `mirror-env.sh` exporta las del espejo. //! Un renombre duro no falla ruidosamente: la variable simplemente no aparece, se toma el valor por //! defecto y el build se comporta distinto sin que nada lo diga. //! //! Por eso valen las dos formas: **`TAKANA_X` gana; si no está, se cae a `HAMMER_X`** (ADR 0016). //! La caída se retira en la etapa 6 del renombre, cuando no queden entornos con la forma vieja. /// Lee una variable aceptando el nombre nuevo y, si falta, el viejo. /// /// Se le pasa el nombre **canónico** (`TAKANA_…`) para que un `grep` del nombre nuevo encuentre /// todas las lecturas; el nombre viejo se deriva cambiando el prefijo. pub fn var(nombre: &str) -> Option { con_caida(nombre, |n| std::env::var(n).ok()) } /// Igual que [`var`], para valores que no tienen por qué ser UTF-8 (rutas). pub fn var_os(nombre: &str) -> Option { con_caida(nombre, |n: &str| std::env::var_os(n)) } fn con_caida(nombre: &str, leer: impl Fn(&str) -> Option) -> Option { if let Some(v) = leer(nombre) { return Some(v); } let viejo = format!("HAMMER_{}", nombre.strip_prefix("TAKANA_")?); leer(&viejo) } #[cfg(test)] mod tests { // Cada test usa un nombre propio: el entorno del proceso es estado COMPARTIDO entre tests que // corren en hilos, y reusar el mismo nombre los hace pisarse de forma intermitente. #[test] fn prefiere_el_nombre_nuevo_sobre_el_viejo() { std::env::set_var("TAKANA_PRUEBA_A", "nuevo"); std::env::set_var("HAMMER_PRUEBA_A", "viejo"); assert_eq!(super::var("TAKANA_PRUEBA_A").as_deref(), Some("nuevo")); } #[test] fn cae_al_viejo_cuando_el_nuevo_no_esta() { std::env::set_var("HAMMER_PRUEBA_B", "viejo"); assert_eq!(super::var("TAKANA_PRUEBA_B").as_deref(), Some("viejo")); } #[test] fn sin_ninguna_de_las_dos_no_hay_valor() { assert_eq!(super::var("TAKANA_PRUEBA_C_QUE_NO_EXISTE"), None); } #[test] fn un_nombre_sin_prefijo_no_inventa_una_caida() { std::env::set_var("HAMMER_PRUEBA_D", "viejo"); assert_eq!(super::var("PRUEBA_D"), None); } #[test] fn var_os_tambien_cae() { std::env::set_var("HAMMER_PRUEBA_E", "viejo"); assert_eq!( super::var_os("TAKANA_PRUEBA_E").as_deref(), Some(std::ffi::OsStr::new("viejo")) ); } }