diff options
| author | luisgulo <luisgulo@gmail.com> | 2025-10-24 18:01:10 +0200 |
|---|---|---|
| committer | luisgulo <luisgulo@gmail.com> | 2025-10-24 18:01:10 +0200 |
| commit | 533e79ba959143f0459431a486bfb85c56c72ddc (patch) | |
| tree | 91974de1bbbdc4c51c76ed591fc5c6e02a3342b6 /core/modules/loop.sh | |
| parent | 45019c81cfd0fc1d18dce18cdfd5f127c6d61073 (diff) | |
Releasing code version 1.8.0
Diffstat (limited to 'core/modules/loop.sh')
| -rw-r--r-- | core/modules/loop.sh | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/core/modules/loop.sh b/core/modules/loop.sh new file mode 100644 index 0000000..3f7cb0d --- /dev/null +++ b/core/modules/loop.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# Module: loop +# Description: Ejecuta un módulo sobre una lista o matriz de valores +# Author: Luis GuLo +# Version: 0.3.0 +# Dependencies: echo, tee + +loop_task() { + local host="$1"; shift + declare -A args + local items_raw="" secondary_raw="" target_module="" + local fail_fast="true" + declare -A module_args + + # 🌐 Cargar traducciones + local lang="${shflow_vars[language]:-es}" + local trfile="$(dirname "${BASH_SOURCE[0]}")/loop.tr.${lang}" + declare -A tr + if [[ -f "$trfile" ]]; then + while IFS='=' read -r k v; do tr["$k"]="$v"; done < "$trfile" + fi + + # Parsear argumentos + for arg in "$@"; do + key="${arg%%=*}" + value="${arg#*=}" + case "$key" in + items) items_raw="$value" ;; + secondary) secondary_raw="$value" ;; + module) target_module="$value" ;; + fail_fast) fail_fast="$value" ;; + *) module_args["$key"]="$value" ;; + esac + done + + if [[ -z "$items_raw" || -z "$target_module" ]]; then + echo "${tr[missing_args]:-❌ [loop] Faltan argumentos obligatorios: items=... module=...}" + return 1 + fi + + IFS=',' read -r -a items <<< "$items_raw" + IFS=',' read -r -a secondary <<< "$secondary_raw" + + for item in "${items[@]}"; do + if [[ "$item" == *:* ]]; then + item_key="${item%%:*}" + item_value="${item#*:}" + else + item_key="$item" + item_value="" + fi + + if [[ -n "$secondary_raw" ]]; then + for sec in "${secondary[@]}"; do + run_module "$host" "$target_module" "$item" "$item_key" "$item_value" "$sec" module_args || { + echo "$(render_msg "${tr[fail_secondary]}" "item=$item" "secondary=$sec")" + [[ "$fail_fast" == "true" ]] && return 1 + } + done + else + run_module "$host" "$target_module" "$item" "$item_key" "$item_value" "" module_args || { + echo "$(render_msg "${tr[fail_item]}" "item=$item")" + [[ "$fail_fast" == "true" ]] && return 1 + } + fi + done +} + +run_module() { + local host="$1" + local module="$2" + local item="$3" + local item_key="$4" + local item_value="$5" + local secondary_item="$6" + declare -n args_ref="$7" + + local call_args=() + for key in "${!args_ref[@]}"; do + value="${args_ref[$key]}" + value="${value//\{\{item\}\}/$item}" + value="${value//\{\{item_key\}\}/$item_key}" + value="${value//\{\{item_value\}\}/$item_value}" + value="${value//\{\{secondary_item\}\}/$secondary_item}" + call_args+=("$key=$value") + done + + echo "🔁 [loop] → $module con item='$item' secondary='$secondary_item'" + + local PROJECT_ROOT="${SHFLOW_HOME:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}" + local MODULE_PATH="" + local SEARCH_PATHS=("$PROJECT_ROOT/core/modules" "$PROJECT_ROOT/user_modules" "$PROJECT_ROOT/community_modules") + for search_dir in "${SEARCH_PATHS[@]}"; do + while IFS= read -r -d '' candidate; do + [[ "$(basename "$candidate")" == "${module}.sh" ]] && MODULE_PATH="$candidate" && break 2 + done < <(find "$search_dir" -type f -name "${module}.sh" -print0) + done + + if [[ -z "$MODULE_PATH" ]]; then + echo "$(render_msg "${tr[module_not_found]}" "module=$module")" + return 1 + fi + + source "$MODULE_PATH" + ! declare -f "${module}_task" > /dev/null && echo "$(render_msg "${tr[task_not_found]}" "module=$module")" && return 1 + + "${module}_task" "$host" "${call_args[@]}" +} + +check_dependencies_loop() { + local lang="${shflow_vars[language]:-es}" + local trfile="$(dirname "${BASH_SOURCE[0]}")/loop.tr.${lang}" + declare -A tr + if [[ -f "$trfile" ]]; then + while IFS='=' read -r k v; do tr["$k"]="$v"; done < "$trfile" + fi + + local missing=() + for cmd in echo tee; do + command -v "$cmd" >/dev/null 2>&1 || missing+=("$cmd") + done + + if [[ ${#missing[@]} -gt 0 ]]; then + echo "$(render_msg "${tr[missing_deps]}" "cmds=${missing[*]}")" + return 1 + fi + + echo "${tr[deps_ok]:-✅ [loop] Dependencias disponibles.}" + return 0 +} |
