← Índice

0.4 La puerta

Esta traducción fue asistida por IA y revisada superficialmente. Si encuentras errores o algo no suena natural, escríbeme — lo agradezco.

Conocer los comandos es una cosa. Recordarlos cada vez es otra. Un artesano experimentado no pasa un día sin comprobar - no porque sea vigilante, sino porque comprobar hace mucho que se convirtió en parte del movimiento. El aprendiz lo hace por fuerza de voluntad. La fuerza de voluntad es conocida por ser poco fiable.

Lo que necesitas

Se conocen cinco comandos. Pero ejecutarlos uno a uno, en el orden correcto, cada vez - eso es una carga que la gente empieza a ignorar. Lo que se necesita es un único punto de entrada que lo compruebe todo a la vez y no permita dar el trabajo por terminado hasta que haya pasado por él.

También hace falta un documento más: una descripción de cómo entrar al taller. Un nuevo desarrollador que clone el repositorio debería poder ejecutar tq sin hacer preguntas.

El ritual

Crea un Makefile en la raíz del proyecto - junto a Cargo.toml:

# ==================================================================================== #
# HELPERS
# ==================================================================================== #

## help: print this help message
.PHONY: help
help:
	@echo 'Usage:'
	@sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /'

# ==================================================================================== #
# DEVELOPMENT
# ==================================================================================== #

## run: run tq
.PHONY: run
run:
	@cargo run

## build: build debug binary
.PHONY: build
build:
	@cargo build

## check: cargo check + clippy
.PHONY: check
check:
	@cargo check && cargo clippy

## fmt: format code
.PHONY: fmt
fmt:
	@cargo fmt

## test: run tests
.PHONY: test
test:
	@cargo test

# ==================================================================================== #
# QUALITY CONTROL
# ==================================================================================== #

## ci: full check - format, linting and tests
.PHONY: ci
ci:
	@cargo fmt --check && cargo clippy -- -D warnings && cargo test

# ==================================================================================== #
# BUILD
# ==================================================================================== #

## clean: remove build artifacts
.PHONY: clean
clean:
	@cargo clean

Importante: la sangría en un Makefile debe ser un carácter de tabulación. Los espacios producirán un error.

make ci es la puerta. Este comando decide si el trabajo está terminado:

make ci
   Compiling tq v0.1.0 (.../tq)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s
     Running unittests src/main.rs (target/debug/deps/tq-...)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Todavía no hay tests - eso cambia al final del primer milestone. make ci no objeta una suite de tests vacía. Objeta código sin formatear, que falla Clippy o que no compila.

Ahora README.md. Créalo junto al Makefile:

# tq

A task manager. Work in progress.

## Requirements

- [Rust](https://rustup.rs/) - latest stable version
- `make`

## Quick start

    cargo run
    # or
    make run

## Development

    make ci       # format + clippy + tests
    make fmt      # format code
    make check    # cargo check + clippy
    make test     # tests
    make clean    # remove build artifacts

El resultado

make ci pasa. La puerta está levantada - el trabajo sin terminar no pasa por ella.

El código de tq no cambió en este capítulo - la puerta se construyó alrededor de lo que ya existe. Por coherencia sigue en 0-the-workshop/04-the-gate/.


Lore: Cómo funciona el Makefile

make help no lee un archivo de descripción separado - parsea el propio Makefile. Los comentarios de la forma ## objetivo: descripción no son solo comentarios; son datos:

@sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /'

${MAKEFILE_LIST} es una variable de Make que contiene los nombres de todos los archivos cargados. Normalmente es solo Makefile, pero si un Makefile incluye otro, sed recorrerá ambos.

Tres pasos:

  1. sed -n 's/^##//p' - encuentra las líneas que empiezan con ##, elimina el prefijo y las imprime. Todo lo demás se ignora.

  2. column -t -s ':' - alinea la salida en columnas, dividiendo por :. Por eso run: run tq y ci: full check - format, linting and tests quedan alineados, independientemente de la longitud del nombre del objetivo.

  3. sed -e 's/^/ /' - añade una sangría antes de cada línea.

.PHONY declara los objetivos como falsos: Make asume por defecto que un objetivo es un nombre de archivo y omite el comando si ya existe un archivo con ese nombre. run, build, ci no son archivos. Sin .PHONY, make build podría quedarse en silencio si existiera un directorio build/.

@ al inicio de un comando suprime su eco en el terminal. Sin él, make run imprimiría cargo run antes de ejecutarlo. Con él - solo aparece la salida propia del comando.


Lore: —check y por qué ci no formatea

make fmt ejecuta cargo fmt - el comando que reescribe archivos en su lugar. En make ci, el comando es cargo fmt --check: solo comprueba y sale con error si el formateo no coincide con lo esperado.

La diferencia importa. Si make ci se ejecuta automáticamente - en un servidor, en un pipeline - no debe modificar archivos en silencio. Un error es visible; una corrección silenciosa no lo es. En el trabajo local: ejecuta make fmt, luego make ci de nuevo.