Saltar al contenido principal

Clase 05 — Strings Multilínea

¿Cómo escribir textos largos en YAML sin perder legibilidad? YAML ofrece dos operadores de bloque: Literal (|) y Folded (>).

El problema

# ❌ Poco legible
descripcion: "Este es un texto muy largo que describe la aplicación y sus funcionalidades principales incluyendo autenticación, base de datos y API REST"

Literal Block Scalar (|) — Preserva saltos de línea

descripcion: |
Esta es la primera línea.
Esta es la segunda línea.
Esta es la tercera línea.

Resultado: "Esta es la primera línea.\nEsta es la segunda línea.\nEsta es la tercera línea.\n"

Folded Block Scalar (>) — Une líneas en una sola

descripcion: >
Esta es una frase larga
que se escribió en múltiples
líneas pero se unirá
en una sola.

Resultado: "Esta es una frase larga que se escribió en múltiples líneas pero se unirá en una sola.\n"

Folded con párrafos

# Las líneas vacías crean párrafos (saltos de línea reales)
texto: >
Primer párrafo que se une
en una sola línea.

Segundo párrafo que también
se une en una línea.

Tercer párrafo.

Resultado: "Primer párrafo que se une en una sola línea.\nSegundo párrafo que también se une en una línea.\nTercer párrafo.\n"

Chomping — Controlar el salto de línea final

IndicadorNombreComportamiento
| o >Clip (default)Un salto de línea al final
|- o >-StripSin salto de línea al final
|+ o >+KeepMantiene TODOS los saltos finales
# Clip (default) - Un \n al final
clip: |
Hola
Mundo

# Strip - Sin \n al final
strip: |-
Hola
Mundo

# Keep - Mantiene todos los \n finales
keep: |+
Hola
Mundo

Resultados:

clip:  "Hola\nMundo\n"
strip: "Hola\nMundo"
keep: "Hola\nMundo\n\n\n"

Ejemplo: Scripts en GitHub Actions

# .github/workflows/ci.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup y Build
run: |
echo "Instalando dependencias..."
npm install
echo "Ejecutando tests..."
npm test
echo "Construyendo aplicación..."
npm run build
echo "Build completado!"

- name: Deploy con script complejo
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "Deploying a producción..."
aws s3 sync ./build s3://mi-bucket-prod/
else
echo "Deploying a staging..."
aws s3 sync ./build s3://mi-bucket-staging/
fi

Ejemplo: Kubernetes ConfigMap con archivos

apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
server_name ejemplo.com;

location / {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /static {
alias /var/www/static;
expires 30d;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

default.conf: |
upstream backend {
server api-1:8080;
server api-2:8080;
server api-3:8080;
}

Ejemplo: Docker Compose con scripts de inicialización

version: "3.8"

services:
app:
build: .
depends_on:
- postgres
labels:
com.example.description: >-
Esta aplicación gestiona la API principal
del sistema de Pokémon, incluyendo endpoints
de búsqueda, creación y actualización.

init-db:
image: postgres:16-alpine
depends_on:
- postgres
command: >
bash -c "
echo 'Esperando a PostgreSQL...'
until pg_isready -h postgres -U postgres; do
sleep 2
done
echo 'PostgreSQL listo!'
psql -h postgres -U postgres -c 'CREATE DATABASE IF NOT EXISTS app_db;'
echo 'Base de datos creada!'
"

Ejemplo: Helm values con templates

app:
name: mi-api

config: |
[database]
host = {{ .Values.db.host }}
port = {{ .Values.db.port }}
name = {{ .Values.db.name }}

[server]
port = {{ .Values.app.port }}
workers = {{ .Values.app.workers }}
debug = false

changelog: |-
## v2.0.0
- Migración a FastAPI
- Nuevo endpoint de búsqueda
- Soporte para paginación

## v1.0.0
- Release inicial
- CRUD básico de Pokémon

Indentación en bloques multilínea

# Indicador de indentación explícito
datos:
script: |2
Esta línea tiene 6 espacios
Y esta también
El "2" indica 2 espacios de indentación del bloque

# Sin indicador (se detecta automáticamente)
otro_script: |
Esta línea tiene 4 espacios
Se detecta automáticamente

Resumen visual

|   → Literal (mantiene \n)         "línea1\nlínea2\n"
|- → Literal Strip (sin \n final) "línea1\nlínea2"
|+ → Literal Keep (todos los \n) "línea1\nlínea2\n\n"
> → Folded (una línea) "línea1 línea2\n"
>- → Folded Strip "línea1 línea2"
>+ → Folded Keep "línea1 línea2\n\n"

Ejercicios

  1. Escribí un GitHub Actions workflow donde un step ejecute un script de 10+ líneas con |
  2. Creá un Kubernetes ConfigMap que contenga un archivo .env y un nginx.conf completos
  3. Experimentá con |, |-, >, >- y verificá las diferencias con Python:
    import yaml
    data = yaml.safe_load(open("test.yaml"))
    for k, v in data.items():
    print(f"{k}: {repr(v)}")