Saltar a contenido

Escribir YAML Sensato

YAML es un lenguaje de marcado que tiene algunas características interesantes pero también muchas trampas y dificultades.

Usar líneas de comentarios

Puede usar líneas de comentarios en YAML. Simplemente inicie una línea con el carácter almohadilla/hash, al igual que en muchos lenguajes de scripting shell:

# comentario aquí
do:
         ### la indentación no es importante para los comentarios
   # ahora algo de acción
   - npm install yaml  # algo de auto-referencia aquí...
   # esto también es importante:
   - npm install someotherthing

Los comentarios se eliminan durante el análisis y no interfieren con sus comandos.

Manejo de errores

Cuando se procesa un rulebook, lo primero que hace el motor de rulebook de Clarive es analizar la estructura YAML.

El analizador de rulebook de Clarive intenta capturar tantos errores de YAML como sea posible durante la fase de análisis de YAML. Los errores de análisis de YAML se ven así:

error parsing YAML YAML::XS::Load Error: The problem:

    mapping values are not allowed in this context

was found at document: 1, line: 2, column: 16
1:
2:   - echo: hello:
------------------^
3:

El error anterior apunta a una estructura YAML inválida, dos puntos inesperados dentro del valor para el op echo. La línea y flecha ------^ debajo de la línea 2 apunta al carácter inválido detectado por el analizador YAML.

Trampas comunes

La mayoría de los errores de YAML pueden evitarse siguiendo algunas pautas destacadas aquí.

Anidamiento

Asegúrese de anidar sus estructuras correctamente. El analizador YAML de rulebook requiere al menos 1 espacio para indentar elementos en YAML.

# la indentación de un espacio es exagerar un poco
do:
 - ls /tmp
 - exit 0

Tenga cuidado con los ops hash planos, como try-catch e if-then-else. Las claves deben estar perfectamente alineadas para que se analicen y compilen correctamente:

do:
   - if: '{{ 1 == 1 }}'
     then:
        - npm install yaml
     else:
        - fail: not true there

Preste atención a los ops if-then-else anteriores. Están perfectamente alineados en la columna 6. Cualquier desalineación y no se interpretarán correctamente.

Usar comillas abundantemente

YAML absorbe valores de clave sin comillas, lo que puede ser muy conveniente. Pero acostúmbrese a poner sus cadenas entre comillas. Mejora la legibilidad y reduce errores.

do:

  # esto funciona
  - echo: hello world

  # pero esto es más legible
  - echo: "hello world"

Valores que parecen YAML anidado

Como en el error mostrado arriba, usar dos puntos dentro de sus valores de cadena puede ser interpretado como claves hash por el analizador:

do:
  # errores desagradables aquí
  - echo: hello: world

Errores de plantilla handlebar

Los bloques de plantilla handlebar {{ ... }} pueden confundirse fácilmente con estructuras hash como { foo: 100, bar: 200 }. Lo más probable es que el analizador YAML no arroje un error en este caso y su bloque handlebar será tratado como un hash inválido que generará errores más adelante, en las fases de compilación o ejecución.

La solución es usar comillas alrededor de los bloques handlebar para evitar confundir al motor de rulebook.

do:
  - echo: "{{ 'this is ' + 10 + ' times better' }}"

Escapar caracteres especiales

YAML interpreta caracteres de control especiales, como \n o \t. Cuando se combinan con ciertos ops o comandos shell, puede generar errores inesperados en lugares extraños que parecen correctos, especialmente con código ClaJS de handlebar {{ ... }}.

Por ejemplo, esto no será analizado correctamente por el motor ClaJS. La nueva línea necesita ser escapada, de lo contrario el analizador YAML introducirá una nueva línea antes de que el ejecutor ClaJS procese el texto.

do:
   - mydata =: |
         line1
         line2
   - lines =: "{{ mydata.split('\n') }}"   # esto fallará con un error JS
   - lines =: "{{ mydata.split('\\n') }}"  # ahora eso es mejor

Tenga en cuenta que los valores de cadenas construidos con los operadores mayor que y pipe en realidad ignoran los caracteres de nueva línea, por lo tanto no es necesario escaparlos.

do:
   - mydata =: |
         line1
         line2

   # esto es lo mismo que arriba, pero no se necesita escapar
   - lines =: |
       {{ mydata.split('\n') }}

   # igual aquí con un do:, no es necesario escapar:
   - lines = do: |
         mydata.split('\n')

La Diferencia entre > y |

El operador mayor que > absorberá todas las líneas como una sola línea.

El operador pipe | mantendrá el carácter de nueva línea al final de cada línea.