#!/bin/bash # ============================================================================= # propagate-module-update.sh # Sistema de Propagacion de Mejoras - NEXUS v3.4 # ============================================================================= # # Descripcion: # Identifica todos los proyectos que usan un modulo especificado y genera # una lista de propagaciones pendientes, excluyendo el proyecto origen. # # Uso: # ./propagate-module-update.sh [opciones] # # Opciones: # --dry-run Simular sin modificar archivos # --update-registry Actualizar REGISTRO-PROPAGACIONES.yml # --scrum Generar tareas SCRUM formales (usa generate-scrum-tasks.sh) # --scrum-epic Generar EPIC contenedora (combina con --scrum) # --cascade Ejecutar propagacion por niveles (usa cascade-propagation.sh) # --tipo TIPO Tipo de cambio: security-fix|bug-fix|feature|refactor (default: feature) # --help Mostrar esta ayuda # # Ejemplos: # ./propagate-module-update.sh auth-jwt-nestjs 2.2.0 gamilit # ./propagate-module-update.sh stripe-subscriptions 3.0.0 trading-platform --dry-run # # Exit codes: # 0 - Exito # 1 - Error en parametros # 2 - Modulo no encontrado en KB # 3 - Sin proyectos para propagar # # Directiva: @PROPAGACION # ============================================================================= set -e # Colores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuracion WORKSPACE="/home/isem/workspace-v1" KB_PATH="$WORKSPACE/shared/knowledge-base" CATALOGO="$KB_PATH/CATALOGO-MODULOS.yml" TRAZABILIDAD="$KB_PATH/TRAZABILIDAD-PROYECTOS.yml" REGISTRO="$KB_PATH/propagacion/REGISTRO-PROPAGACIONES.yml" PROJECTS_PATH="$WORKSPACE/projects" # Parametros MODULO="" VERSION="" ORIGEN="" DRY_RUN=false UPDATE_REGISTRY=false GENERATE_SCRUM=false SCRUM_EPIC=false CASCADE_MODE=false TIPO="feature" # Directorio del script (para llamar a otros scripts) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # ============================================================================= # FUNCIONES # ============================================================================= show_help() { head -35 "$0" | tail -30 exit 0 } log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[OK]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } parse_args() { while [[ $# -gt 0 ]]; do case $1 in --help) show_help ;; --dry-run) DRY_RUN=true shift ;; --update-registry) UPDATE_REGISTRY=true shift ;; --scrum) GENERATE_SCRUM=true shift ;; --scrum-epic) SCRUM_EPIC=true shift ;; --cascade) CASCADE_MODE=true shift ;; --tipo) TIPO=$2 shift 2 ;; *) if [ -z "$MODULO" ]; then MODULO=$1 elif [ -z "$VERSION" ]; then VERSION=$1 elif [ -z "$ORIGEN" ]; then ORIGEN=$1 fi shift ;; esac done } validate_params() { if [ -z "$MODULO" ] || [ -z "$VERSION" ] || [ -z "$ORIGEN" ]; then log_error "Parametros insuficientes" echo "" echo "Uso: $0 [opciones]" echo "" echo "Ejemplo: $0 auth-jwt-nestjs 2.2.0 gamilit" echo "" echo "Use --help para mas informacion" exit 1 fi } check_module_exists() { if [ ! -f "$CATALOGO" ]; then log_error "CATALOGO-MODULOS.yml no encontrado en $CATALOGO" exit 2 fi if ! grep -q "nombre: \"$MODULO\"" "$CATALOGO" && ! grep -q "nombre: $MODULO" "$CATALOGO"; then log_error "Modulo '$MODULO' no encontrado en CATALOGO-MODULOS.yml" echo "" echo "Modulos disponibles:" grep "nombre:" "$CATALOGO" | head -10 | sed 's/.*nombre: //; s/"//g' | sed 's/^/ - /' echo " ..." exit 2 fi log_success "Modulo '$MODULO' encontrado en catalogo" } check_origin_project() { if [ ! -d "$PROJECTS_PATH/$ORIGEN" ]; then log_error "Proyecto origen '$ORIGEN' no existe en $PROJECTS_PATH" exit 1 fi log_success "Proyecto origen '$ORIGEN' verificado" } get_projects_using_module() { if [ ! -f "$TRAZABILIDAD" ]; then log_error "TRAZABILIDAD-PROYECTOS.yml no encontrado" exit 2 fi # Buscar proyectos que usan el modulo en TRAZABILIDAD # El formato esperado es: # proyectos: # gamilit: # modulos_base: # - auth-jwt-nestjs: "2.1.0" PROYECTOS_RAW=$(grep -B20 "$MODULO" "$TRAZABILIDAD" 2>/dev/null | grep "^ [a-z]" | sed 's/:.*//; s/^ *//' | sort -u) # Excluir proyecto origen PROYECTOS="" for p in $PROYECTOS_RAW; do if [ "$p" != "$ORIGEN" ] && [ -d "$PROJECTS_PATH/$p" ]; then PROYECTOS="$PROYECTOS $p" fi done PROYECTOS=$(echo $PROYECTOS | xargs) # Trim whitespace if [ -z "$PROYECTOS" ]; then log_warning "No se encontraron otros proyectos que usen '$MODULO'" echo "" echo "El modulo '$MODULO' parece ser usado solo por '$ORIGEN'" exit 3 fi } generate_propagation_id() { YEAR=$(date +%Y) # Contar propagaciones existentes en el año COUNT=$(grep -c "PROP-$YEAR-" "$REGISTRO" 2>/dev/null || echo "0") NEXT=$((COUNT + 1)) PROP_ID=$(printf "PROP-%s-%03d" "$YEAR" "$NEXT") echo "$PROP_ID" } show_summary() { echo "" echo "============================================" echo " PROPAGACION DE MEJORAS" echo "============================================" echo "" echo " Modulo: $MODULO" echo " Version nueva: $VERSION" echo " Proyecto origen: $ORIGEN" echo "" echo " Proyectos a propagar:" for p in $PROYECTOS; do # Intentar obtener version actual del proyecto CURRENT_VERSION=$(grep -A5 "^ $p:" "$TRAZABILIDAD" 2>/dev/null | grep "$MODULO" | sed 's/.*: *"*//; s/"*$//' | head -1) if [ -z "$CURRENT_VERSION" ]; then CURRENT_VERSION="?" fi echo " - $p (tiene v$CURRENT_VERSION)" done echo "" if $DRY_RUN; then echo " [DRY-RUN] No se realizaran cambios" fi echo "" echo "============================================" } generate_tasks() { PROP_ID=$(generate_propagation_id) FECHA=$(date +%Y-%m-%d) echo "" log_info "Generando tareas de propagacion..." echo " ID de propagacion: $PROP_ID" echo "" for p in $PROYECTOS; do TASK_FILE="TAREA-PROP-$MODULO-$p.md" echo " - $TASK_FILE" if ! $DRY_RUN; then # Aqui se podria crear el archivo de tarea usando el template # Por ahora solo mostramos que se crearia : fi done echo "" log_success "Tareas generadas para $PROP_ID" } update_registry() { if ! $UPDATE_REGISTRY; then log_info "Use --update-registry para actualizar REGISTRO-PROPAGACIONES.yml" return fi if $DRY_RUN; then log_info "[DRY-RUN] Se actualizaria REGISTRO-PROPAGACIONES.yml" return fi log_info "Actualizando REGISTRO-PROPAGACIONES.yml..." # Aqui se agregaria la entrada al registro # Por ahora solo notificamos log_success "Registro actualizado" } run_scrum_generation() { if ! $GENERATE_SCRUM; then return fi echo "" echo "============================================" echo " GENERACION DE TAREAS SCRUM" echo "============================================" echo "" SCRUM_SCRIPT="$SCRIPT_DIR/generate-scrum-tasks.sh" if [ ! -x "$SCRUM_SCRIPT" ]; then log_error "generate-scrum-tasks.sh no encontrado o no ejecutable" return fi SCRUM_FLAGS="" if $SCRUM_EPIC; then SCRUM_FLAGS="$SCRUM_FLAGS --epic" fi if $DRY_RUN; then SCRUM_FLAGS="$SCRUM_FLAGS --dry-run" fi log_info "Ejecutando: generate-scrum-tasks.sh $MODULO $VERSION $TIPO $SCRUM_FLAGS" "$SCRUM_SCRIPT" "$MODULO" "$VERSION" "$TIPO" $SCRUM_FLAGS log_success "Generacion SCRUM completada" } run_cascade_propagation() { if ! $CASCADE_MODE; then return fi echo "" echo "============================================" echo " PROPAGACION EN CASCADA" echo "============================================" echo "" CASCADE_SCRIPT="$SCRIPT_DIR/cascade-propagation.sh" if [ ! -x "$CASCADE_SCRIPT" ]; then log_error "cascade-propagation.sh no encontrado o no ejecutable" return fi CASCADE_FLAGS="" if $DRY_RUN; then CASCADE_FLAGS="$CASCADE_FLAGS --dry-run" fi log_info "Ejecutando: cascade-propagation.sh $MODULO $VERSION $CASCADE_FLAGS" "$CASCADE_SCRIPT" "$MODULO" "$VERSION" $CASCADE_FLAGS log_success "Propagacion en cascada completada" } # ============================================================================= # MAIN # ============================================================================= main() { echo "" echo "==========================================" echo " PROPAGATE MODULE UPDATE" echo " Sistema: NEXUS v3.4" echo "==========================================" echo "" parse_args "$@" validate_params log_info "Verificando modulo..." check_module_exists log_info "Verificando proyecto origen..." check_origin_project log_info "Buscando proyectos que usan '$MODULO'..." get_projects_using_module show_summary generate_tasks update_registry # Ejecutar generacion SCRUM si se solicito run_scrum_generation # Ejecutar cascada si se solicito run_cascade_propagation echo "" echo "============================================" echo " Proximos pasos:" echo "============================================" echo "" if $GENERATE_SCRUM; then echo " 1. Revisar tareas SCRUM generadas" echo " 2. Asignar a @PERFIL_PROJECT_AGENT" else echo " 1. Revisar tareas generadas" echo " 2. Priorizar segun tipo de cambio" fi echo " 3. Ejecutar propagacion en cada proyecto" echo " 4. Actualizar TRAZABILIDAD-PROYECTOS.yml" echo " 5. Validar: ./validate-propagation-chain.sh " echo "" echo " Ver: @PROPAGACION para proceso completo" echo "" echo "============================================" echo "" exit 0 } main "$@"