Saltar al contenido principal

¿Qué idiota escribió este código?

· 4 min de lectura
Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Por fin sucedió: introduje un error que solo aparece en un caso de uso y no se puede resolver porque es el resultado de usar una versión antigua y una nueva de Oh My Posh simultáneamente. ¿Quién haría eso, te preguntarás? Pues, puede ocurrir si usas WSL en Windows, o máquinas virtuales en cualquier sistema mientras compartes la misma configuración entre instalaciones. No es el caso de uso principal, pero tampoco es exótico.

¿Qué sucedió?

A principios de año, tras una gran lucha, finalmente pude implementar la actualización arquitectónica más importante desde la reescritura en Go. Esto requirió migrar configuraciones antiguas para evitar que los usuarios finales tuvieran que descifrar cómo mapear cada elemento, un proceso lógico donde las computadoras obviamente son más eficientes.

Para facilitarlo, añadí una propiedad de configuración llamada version que se incrementa cuando la configuración evoluciona y activa una migración automática cuando es necesario. La lógica para detectar la necesidad de migración es la siguiente:

if !env.Flags().Migrate && cfg.Version != configVersion {
cfg.BackupAndMigrate(env)
}

Si eres observador, quizá ya detectes el problema al conocer el caso de uso. Para quienes prefieren leer sin analizar, el resultado es directo: siempre ejecuta la migración, ya sea forzada (mediante oh-my-posh config migrate manual) o cuando la versión de configuración actual no coincide con la requerida. ¿Sencillo, verdad? Funciona según lo esperado al actualizar Oh My Posh. El problema surge cuando tienes una configuración compartida y usas múltiples versiones de Oh My Posh en la misma máquina.

Imagina trabajar con varios shells: uno es WSL Ubuntu con Oh My Posh en versión 1 (S1). Un día actualizas PowerShell en Windows a la versión más reciente, usando versión 2 (S2). Al iniciar S2, migra automáticamente la configuración a versión 2, trasladando la propiedad template al modelo del segmento.

En la práctica, esta configuración versión 1:

{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"version": 1,
"blocks": [
{
"type": "prompt",
"alignment": "left",
"segments": [
{
"background": "#9A348E",
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"properties": {
"template": "{{ .UserName }} "
},
"style": "diamond",
"type": "session"
}
]
}
]
}

Se migra a:

{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"version": 2,
"blocks": [
{
"type": "prompt",
"alignment": "left",
"segments": [
{
"background": "#9A348E",
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"template": "{{ .UserName }} ",
"style": "diamond",
"type": "session"
}
]
}
]
}

Genial, sin interacción del usuario y todo funciona como está diseñado. Pero ahora quieres usar S1, y por la lógica, Oh My Posh detecta que 2 != 1 y se activa la migración para versión 1. La migración en sí no es problemática, pero Oh My Posh no reconoce la propiedad template en segment en este caso. El resultado final de nuestra configuración anterior es bastante molesto ya que ahora nos queda esto:

{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"version": 1,
"blocks": [
{
"type": "prompt",
"alignment": "left",
"segments": [
{
"background": "#9A348E",
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"style": "diamond",
"type": "session"
}
]
}
]
}

😱 ¡la plantilla desapareció! No hay pánico aún: Oh My Posh usará la plantilla predeterminada para mostrar un prompt, y la migración crea un backup de tu configuración versión 2 correcta. Hasta aquí puedes revertir. Es molesto, pero tus ajustes locales persisten. Pero si continúas trabajando en S2 en este punto, sobrescribirá tu backup con la configuración defectuosa versión 1.

Aunque la solución en código es trivial, es imposible propagarla a versiones antiguas. Los usuarios actualizarán a la versión más reciente, y en este escenario específico puede causar problemas. Se recomienda actualizar todas las versiones simultáneamente, migrando solo una vez sin dejar versiones "antiguas" que desencadenen este efecto secundario.

La solución real está en 7.52.1, pero por razones obvias solo funcionará al migrar desde versión 2 hacia nuevas versiones de configuración futuras.

if !env.Flags().Migrate && cfg.Version < configVersion {
cfg.BackupAndMigrate(env)
}

Aunque me esfuerzo por anticipar todos los casos extremos al validar esta lógica, a veces se me escapan algunos. Incluso revisando este caso me cuesta entender cómo no lo consideré, pero igual sucedió. ¿La buena noticia? No volverá a pasar 😅