diff --git a/bin/efde.sh b/bin/efde.sh index dc7e092..6c3f1b5 100755 --- a/bin/efde.sh +++ b/bin/efde.sh @@ -1,8 +1,17 @@ #!/usr/bin/env bash set -euo pipefail # Debug mode -EFDE_MOD_DEBUG=true # Messages debug +EFDE_MOD_DEBUG=false # Messages debug EFDE_MOD_DEV=true # MMTodo: Prepared for create tmps +EFDE_CFG_SHOW_CLI=true #show COMMANDLINE +declare -gA GLOBAL_EFDE_CONFIG=( + [CLI_SHOW_DEFAULT]=true # Omite configuraciones personalizadas + [CLI_SHOW_CLI]=true # + [CLI_SHOW_OUTPUT]=false +) + + +GLOBAL_RUN_EFDE=$([ "$EFDE_MOD_DEBUG" = "true" ] && echo "e2" || echo "efde") [[ $(echo "$@" | grep -oP '(?<=--debug=)[^ ]+') = "true" && "$EFDE_MOD_DEBUG" = "false" ]] && EFDE_MOD_DEBUG=true @@ -15,17 +24,15 @@ resolve_absolute_dir() SOURCE="$(readlink ${SOURCE})" [[ ${SOURCE} != /* ]] && SOURCE="${DIR}/${SOURCE}" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located done + ABSOLUTE_BIN_PATH="$( cd -P "$( dirname ${SOURCE} )" && pwd )" ABSOLUTE_PATH="${ABSOLUTE_BIN_PATH}/.." EFDE_PATH_INSTALL="$(dirname $ABSOLUTE_BIN_PATH)" } - init_dirs() { resolve_absolute_dir - export DOCKERGENTO_DIR="${ABSOLUTE_PATH}" - export PATH_CONSOLE="${EFDE_PATH_INSTALL}/console" export PATH_BIN="${EFDE_PATH_INSTALL}/bin" @@ -37,41 +44,26 @@ init_dirs() init_dirs source "$PATH_CONSOLE/init" - - -main(){ - if efde.tasks.implemention.has_folder_implementation ; then - #ES SYMFONY CARGA MENU - echo "symfony" - else - menu_init - fi +menu_main(){ + common.tasks.menu.print_menu "Select an option:" "${efde_props_menu_MAIN[@]}" } -menu_init(){ - -#IFS=',' read -ra elements <<< "${ALL_MENUS["MENU_INIT"]}" -# -#for element in "${elements[@]}"; do -# echo "$element" -#done - #common.tasks.menu.print_menu "Select an option:" "${ALL_MENUS["MENU_INIT"][@]}" - common.tasks.menu.print_menu "Select an option:" "${MENU_INIT[@]}" - RESPONSE_CODE=${MENU_RESPONSE_ARRAY_ASOCITIVE['code']} - RESPONSE_TITLE=${MENU_RESPONSE_ARRAY_ASOCITIVE['title']} +menu_implementation(){ + local PATH_ENV=$(efde.tasks.implemention.get_current_path_env_file) + variables_string="$(efde.tasks.config.load_variables_from_file ${PATH_ENV})" + # Evaluar la cadena de variables + eval "$variables_string" + RUN_FUNCTION_IMPLEMENTATION_MAIN= "$IMPLEMENTION.tasks.menu.main" - efde.tasks.implemention.setup_environment $RESPONSE_CODE - exit; - if common.tasks.module.exists_function "$RESPONSE_CODE.tasks.install.environment" ;then - efde.tasks.implemention.setup_environment $RESPONSE_CODE - else - common.tasks.message.danger "The installation of the selected environment is not yet available '$RESPONSE_TITLE'" + ${RUN_FUNCTION_IMPLEMENTATION_MAIN} +} - common.tasks.prompt.confirm_default_yes "Back to menu?" && menu_init - fi +main(){ + if ! efde.tasks.implemention.has_folder_implementation ; then + menu_main + fi + menu_implementation } main - - diff --git a/console/common/core b/console/common/core index 8e96fab..536b0ce 100755 --- a/console/common/core +++ b/console/common/core @@ -6,43 +6,24 @@ _mod_.console_clear() { clear } -#_mod_.check_mode_debug() { -# [ "$EFDE_MOD_DEBUG" == "true" ] || [ "$EFDE_MOD_DEBUG" == "core" ] -#} - -_mod_.msg_debug(){ - local level="${2:-0}" - local end="${3:-0}" - local prefix="" - - if [ "$level" -eq 1 ]; then - prefix+="├──" - fi - if [ "$level" -gt 1 ]; then - for ((i=1; i/dev/null - fi + command printf "${color_start}$1${color_end}\n" 2>/dev/null + fi + fi } _mod_.msg_danger(){ @@ -54,10 +35,23 @@ _mod_.msg_danger(){ fi } +_mod_.load_common_msg(){ + PATH_MODULE=$1 + FILE="msg" + MODULE_NAME="common" + ELEMENT="tasks" + _mod_.replacemod --file-name="$FILE" --new-name="$MODULE_NAME.$ELEMENT.$FILE" --source-path="$PATH_MODULE/$ELEMENT/$FILE" +} + +_mod_.essential_run() { type "common.tasks.msg.print" &> /dev/null; } + _mod_.load_module(){ + # ESSENTIAL MODULE !!!!! + ! _mod_.essential_run && _mod_.load_common_msg $1 + local PATH_MODULE=$1 local elements=("props" "tasks") - + _mod_.step _mod_.msg_debug "Module: $MODULE_NAME" 1 for element in "${elements[@]}"; do @@ -65,6 +59,7 @@ _mod_.load_module(){ if [ -d "$CHECK_PATH" ]; then _mod_.msg_debug "Group: $element" 2 for file in $(ls -1 $CHECK_PATH); do + [ "$file" == "msg" ] && continue _mod_.msg_debug "Element: $file" 3 _mod_.replacemod --file-name="$file" --new-name="$MODULE_NAME.$element.${file%}" --source-path="$CHECK_PATH/$file" done @@ -74,8 +69,10 @@ _mod_.load_module(){ _mod_.replacemod () { local FILE_NAME NEW_NAME SOURCE_PATH - local USED="The '$FUNCNAME' method must contain the 3 required parameters \n--file-name='file \n--new-name='common.task' \n--source-path='path/folder/file" - + local USED="The $FUNCNAME method must contain the 3 required parameters" + USED+="\n--file-name='file" + USED+="\n--new-name='common.tasks'" + USED+="\n--source-path='path/folder/file" if [[ $# != 3 ]]; then _mod_.msg_danger $USED 3 _mod_.msg_debug "$@" 3 @@ -106,7 +103,16 @@ _mod_.replacemod () { if [ "$EFDE_MOD_DEV" = "true" ] || [ ! -f "$PATH_TARGET" ]; then - sed "s/_mod_/$NEW_NAME/g" "$SOURCE_PATH" > "$PATH_TARGET" + # old only replace functions + #sed "s/_mod_/$NEW_NAME/g" "$SOURCE_PATH" > "$PATH_TARGET" + + if echo "$NEW_NAME" | grep -qi ".tasks."; then + sed -E "s/_mod_\.([a-zA-Z_][a-zA-Z0-9_]*)/${NEW_NAME}.\1/g" "$SOURCE_PATH" > "$PATH_TARGET" + else + NEW_NAME_VAR=$(echo "$NEW_NAME" | sed "s/tasks/props/" | tr "." "_") + sed -E "s/_mod_([a-zA-Z_][a-zA-Z0-9_]*)/${NEW_NAME_VAR}_\1/g" "$SOURCE_PATH" > "$PATH_TARGET" + fi + if [ ! $? -eq 0 ]; then _mod_.msg_danger "[ERROR] The conversion could not be carried out, report this!" 4 _mod_.msg_danger "Source: $SOURCE_PATH" 5 diff --git a/console/common/props/menu b/console/common/props/menu index 578391f..18c3738 100644 --- a/console/common/props/menu +++ b/console/common/props/menu @@ -3,10 +3,10 @@ #declare -a MENU=('tools,Tools, ' 'symfony,Install Symfony, ' 'magento,Coming soon - Install Magento | Wordpress | Prestashop | Drupal | React | Angular | Vue | Next, ') #ALL_MENUS["MENU_INIT"]="${MENU[@]}" -MENU_INIT=( - 'tools,Tools, ' +_mod_INIT=( + 'tools,Tools, ESTE' 'symfony,Install Symfony, ' - 'magento,Coming soon - Install Magento | Wordpress | Prestashop | Drupal | React | Angular | Vue | Next, ') + 'magento,Coming soon Install Magento | Wordpress | Prestashop | Drupal | React | Angular | Vue | Next ') # 'magento,Coming soon - Install Magento, ' # 'wordpress,Coming soon - Install Wordpress, ' # 'woocommerce,Coming soon - Install WooCommerce, ' diff --git a/console/common/tasks/command_line b/console/common/tasks/command_line new file mode 100644 index 0000000..2424bbb --- /dev/null +++ b/console/common/tasks/command_line @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +_mod_.run() { + if [ "$#" -ne 3 ]; then + local USED="" + USED+="Error: Three parameters are required:\n" + USED+=" - FORCE_SHOW_CLI FORCE_SHOW_OUTPUT COMMAND_LINE\n" + USED+="\n parameters:\n ${@}\n" + USED+="\n Example:\n" + USED+=" - $FUNCNAME FORCE_SHOW_CLI=true FORCE_SHOW_OUTPUT=true COMMAND_LINE\n" + USED+=" - $FUNCNAME 1 0 'cd folder'" + common.tasks.message.danger $USED + return 1 + fi + + local FORCE_SHOW_CLI FORCE_SHOW_OUTPUT COMMAND_LINE + + FORCE_SHOW_CLI=$1 + FORCE_SHOW_OUTPUT=$2 + COMMAND_LINE="$3" + + if [ "${GLOBAL_EFDE_CONFIG['CLI_SHOW_DEFAULT']}" = "true" ]; then + FORCE_SHOW_CLI=${GLOBAL_EFDE_CONFIG['CLI_SHOW_CLI']} + FORCE_SHOW_OUTPUT=${GLOBAL_EFDE_CONFIG['CLI_SHOW_OUTPUT']} + #[ "${GLOBAL_EFDE_CONFIG['CLI_SHOW_CLI']}" = "true" ] && FORCE_SHOW_CLI=true + #[ "${GLOBAL_EFDE_CONFIG['CLI_SHOW_OUTPUT']}" = "true" ] && FORCE_SHOW_OUTPUT=true + fi + + if [ "${FORCE_SHOW_CLI}" = "true" ]; then + common.tasks.message.info "# RUN CLI > ${COMMAND_LINE}" + fi + + if [ "${FORCE_SHOW_OUTPUT}" = "false" ]; then + ${COMMAND_LINE} > /dev/null 2>&1 + else + ${COMMAND_LINE} + fi +} \ No newline at end of file diff --git a/console/common/tasks/env_variable b/console/common/tasks/env_variable new file mode 100644 index 0000000..276c22c --- /dev/null +++ b/console/common/tasks/env_variable @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +set -euo pipefail + +_mod_.set_variable() { + + if [ "$#" -ne 3 ]; then + echo "Error: Se requieren tres parámetros: key, value, file" + return 1 + fi + + local key="$1" + local value="$2" + local file="$3" + + key=$(echo "$key" | tr '[:lower:]' '[:upper:]' | tr ' ' '_') + + if [ ! -e "$file" ]; then + touch "$file" + fi + + if grep -q "^$key=" "$file"; then + # Update existing + sed -i "s/^$key=.*/$key=\"$value\"/" "$file" + else + # add new + echo "$key=\"$value\"" >> "$file" + fi +} + +_mod_.get_variable() { + if [ "$#" -ne 2 ]; then + echo "Error: Se requieren dos parámetros: key, file" + return 1 + fi + + local key="$1" + local file="$2" + + key=$(echo "$key" | tr '[:lower:]' '[:upper:]' | tr ' ' '_') + + if [ -e "$file" ]; then + local value=$(grep "^$key=" "$file" | sed "s/^$key=//") + if [ -n "$value" ]; then + value=$(echo "$value" | sed 's/^"\(.*\)"$/\1/') + echo -n "$value" + else + echo "No encontrado" + fi + else + echo "Error: El archivo $file no existe." + return 1 + fi +} +# +# +## USAGED +## Call: +## SETUP_ENVIRONMENT=( +## [NAME]="MyName" +## [CREATE_AT]="2000-01-01" +## [IMPLEMENTION]="efde" +## ) +## VAR_STRING="$(_mod_.prepare_string_to_env SETUP_ENVIRONMENT)" +## +## echo -e "$VAR_STRING" > "$PATH_FILE" +## +## Response: +## 'NAME="MyName"\nCREATE_AT="2000-01-01"\nIMPLEMENTION="efde"' +#_mod_.prepare_string_to_env(){ +# local -n env_array=$1 +# local env_str="" +# +# for key in "${!env_array[@]}"; do +# value="${env_array[$key]}" +# env_str+="\n$key=\"$value\"" +# done +# +# env_str="${env_str:2}" # Remove firts \n +# +# echo "$env_str" +#} +# +#_mod_.load_variables_from_file() { +# local file_path="$1" +# local variables="" +# +# if [ -f "$file_path" ]; then +# # Leer el archivo y construir la cadena de variables +# while IFS='=' read -r key value; do +# # Eliminar espacios en blanco alrededor de la clave y el valor +# key=$(echo "$key" | sed 's/^[ \t]*//;s/[ \t]*$//') +# value=$(echo "$value" | sed 's/^[ \t]*//;s/[ \t]*$//') +# +# # Agregar la variable a la cadena +# variables+="$key=\"$value\" " +# done < "$file_path" +# +# # Eliminar posibles espacios en blanco al final +# variables=$(echo "$variables" | sed 's/[ \t]*$//') +# +# # Devolver la cadena de variables +# echo "$variables" +# else +# echo "Error: El archivo $file_path no existe." +# return 1 +# fi +#} \ No newline at end of file diff --git a/console/common/tasks/menu b/console/common/tasks/menu index bf32dcf..3ae1817 100644 --- a/console/common/tasks/menu +++ b/console/common/tasks/menu @@ -2,13 +2,13 @@ set -euo pipefail MENU_RESPONSE_CHOICE="" #VARIABLE GLOBAL - HIGH SOLUTION ;) -declare -gA MENU_RESPONSE_ARRAY_ASOCITIVE +declare -gA GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE # USAGE # my_array=( -# 'code 0,Title 0,Description 0' -# 'code 1,Title 1,Description 1' -# 'code-2,Title 2,Description 2' +# 'code, Title 0, Description 0' +# 'function_name, Title 1, Description 1' +# 'common.tasks.module.function, Title 2, Description 2' # ) # # common.tasks.menu.show_menu "¿Question?" "${my_array[@]}" @@ -26,25 +26,35 @@ _mod_.print_menu(){ IFS=',' read -r -a values <<< "$option" if [[ ${#values[@]} -ge 2 ]]; then titulo=${values[1]} - descripcion=${values[2]} - #common.tasks.message.echo "$i $titulo" - printf "%-0s. %-40s %s\n" "$i" "$titulo" "$descripcion" + description=$([ "$EFDE_MOD_DEBUG" = "true" ] && echo ${values[0]} || echo ${values[2]}) + printf "%-0s. %-40s %s\n" "$i" "$titulo" "$description" else common.tasks.message.warning "Opción inválida: $option" fi done - common.tasks.message.info "\nPress I to get info about efde" - common.tasks.message.info "Press Q to quit" + common.tasks.message.info "\nPress R to return | Q to quit | I for info" - choice=$(common.tasks.prompt.request_input "$(common.tasks.message.success "Enter the option number: ")") + choice=$(common.tasks.prompt.request_input "$(common.tasks.message.success "Enter the option number:") ") if [[ $choice =~ ^[0-9]+$ && $choice -ge 0 && $choice -le $(( ${#options[@]} -1 )) ]]; then - #echo "option $((choice )) | value : ${options[$selected_number]}" MENU_RESPONSE_CHOICE=$choice - _mod_.menu_response_asociative "${MENU_INIT[$MENU_RESPONSE_CHOICE]}" + GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['choice']=$MENU_RESPONSE_CHOICE + + _mod_.menu_response_asociative "${options[$MENU_RESPONSE_CHOICE]}" + common.console_clear + local RUN_FUNCTION=${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function']} + if common.tasks.module.exists_function "$RUN_FUNCTION" ;then + _mod_.msg_debug + ${RUN_FUNCTION} + fi +# else +# common.msg_danger "Error: ${RUN_FUNCTION^^} The functions don't exists" +# _mod_.print_menu "$question" "${options[@]}" +# fi else [[ "$choice" == "q" ]] && exit 0 + [[ "$choice" == "r" ]] && { common.console_clear; ${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function_old']}; return; } common.console_clear common.tasks.message.danger "La opción '$choice' no está en la lista." _mod_.print_menu "$question" "${options[@]}" @@ -57,11 +67,36 @@ _mod_.menu_response_asociative(){ IFS=',' read -r -a VALUES <<< "$MENU_ARRAY" if [[ ${#VALUES[@]} -ge 2 ]]; then - MENU_RESPONSE_ARRAY_ASOCITIVE['code']="${VALUES[0]}" - MENU_RESPONSE_ARRAY_ASOCITIVE['title']="${VALUES[1]}" - MENU_RESPONSE_ARRAY_ASOCITIVE['description']="${VALUES[2]}" + + # Return function menu + # MMTodo: Review + # Solo se puede hacer un solo return, + # Solucion acumular historico de functions, durante el ciclo de vida de la ejecucion + if [[ ! -n "${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function']+isset}" ]]; then + GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function_old']="" + else + GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function_old']="${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function']}" + fi + + GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function']="${VALUES[0]}" + GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['title']="${VALUES[1]}" + GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['description']="${VALUES[2]}" + else echo "Error: Formato de entrada incorrecto" # Mensaje de error exit 1 fi } + +_mod_.msg_debug(){ + common.msg_debug "#######################################################################" + common.msg_debug "# MENU " + common.msg_debug "GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE:" 1 + common.msg_debug "title: ${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['title']}" 2 + common.msg_debug "description: ${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['description']}" 2 + common.msg_debug "functions:" 2 + common.msg_debug "new: ${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function']}" 3 + common.msg_debug "old: ${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function_old']}" 3 1 + common.msg_debug "-----------------------------------------------------------------------" +} + diff --git a/console/common/tasks/message b/console/common/tasks/message index ed8e236..cb5d447 100644 --- a/console/common/tasks/message +++ b/console/common/tasks/message @@ -1,22 +1,21 @@ #!/usr/bin/env bash set -euo pipefail - _mod_.echo() { # shellcheck disable=SC2068 local MSG="$(_mod_.msg_color $@)" - command printf "$MSG" 2>/dev/null + command printf "$MSG\n" 2>/dev/null } _mod_.msg_color(){ local MSG START_COLOR INIT_COLOR=${COLOR_RESET} case $1 in - success) shift; MSG="${B_GREEN}$@${COLOR_RESET}\n";; - info) shift; MSG="${B_CYAN}$@${COLOR_RESET}\n";; - warning) shift; MSG="${B_YELLOW}$@${COLOR_RESET}\n";; - danger) shift; MSG="${B_RED}$@${COLOR_RESET}\n";; - debug) shift; MSG="${B_PURPLE}$@${COLOR_RESET}\n";; - *) MSG="$@\n";; + success) shift; MSG="${B_GREEN}$@${COLOR_RESET}";; + info) shift; MSG="${B_CYAN}$@${COLOR_RESET}";; + warning) shift; MSG="${B_YELLOW}$@${COLOR_RESET}";; + danger) shift; MSG="${B_RED}$@${COLOR_RESET}";; + debug) shift; MSG="${B_PURPLE}$@${COLOR_RESET}";; + *) MSG="$@";; esac echo "$MSG" @@ -30,7 +29,7 @@ _mod_.msg_type(){ error) shift; type="Error";; warning) shift; type="Warning";; danger) shift; type="Danger";; - *) echo $@; return;; + *) echo "$@"; return;; esac # shellcheck disable=SC2145 @@ -38,23 +37,23 @@ _mod_.msg_type(){ } _mod_.success(){ - _mod_.echo success $@ + _mod_.echo success "$@" } _mod_.info(){ - _mod_.echo info $@ + _mod_.echo info "$@" } _mod_.warning(){ - _mod_.echo warning $@ + _mod_.echo warning "$@" } _mod_.danger(){ - _mod_.echo danger $@ + _mod_.echo danger "$@" } _mod_.debug(){ if [ "$EFDE_MOD_DEBUG" = "true" ] ; then - _mod_.echo debug $@ + _mod_.echo debug "$@" fi } \ No newline at end of file diff --git a/console/common/tasks/module b/console/common/tasks/module index 43a0b53..7deb67a 100644 --- a/console/common/tasks/module +++ b/console/common/tasks/module @@ -5,10 +5,6 @@ _mod_.check() { echo "Load " $(basename "${BASH_SOURCE[0]}") } -_mod_.menu(){ - echo "test" -} - _mod_.exists_function(){ [ "$(type -t "$1")" = "function" ] } \ No newline at end of file diff --git a/console/common/tasks/msg b/console/common/tasks/msg new file mode 100644 index 0000000..96ffc9b --- /dev/null +++ b/console/common/tasks/msg @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -euo pipefail + +_mod_.debug(){ + local level="${2:-0}" + local end="${3:-0}" + local prefix="" + + if [ "$level" -eq 1 ]; then + prefix+="├──" + fi + if [ "$level" -gt 1 ]; then + for ((i=1; i/dev/null + fi +} + +_mod_.danger(){ + local level="${2:-0}" + if [ "$EFDE_MOD_DEBUG" = "true" ] ; then + _mod_.debug "\033[1;31m$1\033[0m" $level + else + command printf "\033[1;31m$1\033[0m\n" 2>/dev/null + fi +} \ No newline at end of file diff --git a/console/common/tasks/prompt b/console/common/tasks/prompt index 4427561..2c0bc88 100644 --- a/console/common/tasks/prompt +++ b/console/common/tasks/prompt @@ -1,12 +1,36 @@ #!/usr/bin/env bash set -euo pipefail +################################################################################################################### +# IMPORTANT +#------------------------------------------------------------------------------------------------------------------ +# En Bash, la convención general es utilizar el +# valor de retorno del comando o función para indicar el éxito o fracaso de la operación. +# El código de retorno 0 se usa para indicar éxito (o "true") y cualquier otro valor se usa para indicar fracaso (o "false"). +# +# USED SIMPLE +# _mod_.confirm_default_no "Question?" && action_function +# _mod_.confirm_default_yes "Question?" && action_function +# +# USED Extra +# local RESULT=true +# if common.tasks.prompt.confirm_default_yes "Question? " ; then +# RESULT=true +# fi +# +# if [ "$RESULT" = "true" ]; then +# echo "webapp" +# fi +################################################################################################################### # Read a single char from /dev/tty, prompting with "$*" # Note: pressing enter will return a null string. Perhaps a version terminated with X and then remove it in caller? # See https://unix.stackexchange.com/a/367880/143394 for dealing with multi-byte, etc. _mod_.get_keypress() { local REPLY IFS= - printf >/dev/tty '%s' "$*" + + #printf >/dev/tty '%s' "$*" #MMTodo: Original + printf >/dev/tty "%b" "$*" #MMTodo: apply color + #[[ $ZSH_VERSION ]] && read -rk1 # Use -u0 to read from STDIN # See https://unix.stackexchange.com/q/383197/143394 regarding '\n' -> '' [[ $BASH_VERSION ]] && read -# Usage: _mod_.confirm_default_no "Dangerous. Are you sure?" && action_function +# Usage: +# _mod_.confirm_default_no "Dangerous. Are you sure?" && action_function _mod_.confirm_default_no() { local prompt="${*:-Are you sure} [y/N]? " _mod_.get_yes_keypress "$prompt" 1 @@ -41,13 +66,14 @@ _mod_.confirm_default_no() { # Prompt to confirm, defaulting to YES on # Usage: -# _mod_.confirm_default_yes "question?" && action_function +# _mod_.confirm_default_yes "question?" && action_function _mod_.confirm_default_yes() { local prompt="${*:-Are you sure} [Y/n]? " _mod_.get_yes_keypress "$prompt" 0 } _mod_.request_input() { - read -r -p "$@" value - echo $value + local prompt="$*" + read -r -p "$(printf "%b" "$prompt")" value + echo "$value" } diff --git a/console/docker/init b/console/docker/init new file mode 100644 index 0000000..a98edaa --- /dev/null +++ b/console/docker/init @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +MODULE_PATH=$(dirname "${BASH_SOURCE[0]}") +MODULE_NAME="$(basename "$(dirname "${BASH_SOURCE[0]}")")" + +common.load_module $MODULE_PATH + + + + diff --git a/console/docker/tasks/main b/console/docker/tasks/main new file mode 100644 index 0000000..b6812f5 --- /dev/null +++ b/console/docker/tasks/main @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -euo pipefail +declare -g GLOBAL_DOCKER_COMPOSE_COMMAND + +# https://docs.docker.com/compose/ +# From the end of June 2023 Compose V1 won’t be supported anymore and will be removed from all Docker Desktop versions. +if docker compose version > /dev/null 2>&1; then + GLOBAL_DOCKER_COMPOSE_COMMAND="docker compose" +else + GLOBAL_DOCKER_COMPOSE_COMMAND="docker-compose" +fi + +_mod_.dp_up(){ + _mod_.dp_command_run "up -d --build" +} + +_mod_.dp_start(){ + _mod_.dp_command_run "start" +} + +_mod_.dp_stop(){ + _mod_.dp_command_run "stop" +} + +_mod_.dp_all_stop(){ + local CONTAINERS=$(docker ps -q) + if [ -n "$CONTAINERS" ]; then + common.tasks.command_line.run false false "docker stop $CONTAINERS" + fi +} + +_mod_.dp_command_run(){ + local COMMAND_RUN="${GLOBAL_DOCKER_COMPOSE_COMMAND} $@" + common.tasks.command_line.run true false "${COMMAND_RUN}" +} + + +_mod_.apache_stop(){ + if systemctl is-active --quiet apache2; then + local QUESTION="APACHE2 is ON, do you want to turn it OFF?" + if common.tasks.prompt.confirm_default_yes "$QUESTION" ; then + local COMMAND_RUN="sudo service apache2 stop" + common.tasks.command_line.run true false ${COMMAND_RUN} + fi + fi +} diff --git a/console/efde/init b/console/efde/init index a98edaa..9b4ddbd 100644 --- a/console/efde/init +++ b/console/efde/init @@ -4,8 +4,4 @@ set -euo pipefail MODULE_PATH=$(dirname "${BASH_SOURCE[0]}") MODULE_NAME="$(basename "$(dirname "${BASH_SOURCE[0]}")")" -common.load_module $MODULE_PATH - - - - +common.load_module $MODULE_PATH \ No newline at end of file diff --git a/console/efde/props/menu b/console/efde/props/menu new file mode 100644 index 0000000..c5e83d0 --- /dev/null +++ b/console/efde/props/menu @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +#declare -gA ALL_MENUS +#declare -a MENU=('tools,Tools, ' 'symfony,Install Symfony, ' 'magento,Coming soon - Install Magento | Wordpress | Prestashop | Drupal | React | Angular | Vue | Next, ') +#ALL_MENUS["MENU_INIT"]="${MENU[@]}" + +_mod_MAIN=( + 'tools,Tools, ESTE' + 'symfony.tasks.menu.create_environment,Install Symfony, ') diff --git a/console/efde/tasks/config b/console/efde/tasks/config index 8c852f8..9ea0399 100644 --- a/console/efde/tasks/config +++ b/console/efde/tasks/config @@ -47,6 +47,32 @@ _mod_.show_config() { echo "t" } +_mod_.set_environment_variable() { + + if [ "$#" -ne 3 ]; then + echo "Error: Se requieren tres parámetros: key, value, file" + return 1 + fi + + local key="$1" + local value="$2" + local file="$3" + + key=$(echo "$key" | tr '[:lower:]' '[:upper:]' | tr ' ' '_') + + if [ ! -e "$file" ]; then + touch "$file" + fi + + if grep -q "^$key=" "$file"; then + # Update existing + sed -i "s/^$key=.*/$key=\"$value\"/" "$file" + else + # add new + echo "$key=\"$value\"" >> "$file" + fi +} + # USAGED # Call: # SETUP_ENVIRONMENT=( @@ -54,7 +80,9 @@ _mod_.show_config() { # [CREATE_AT]="2000-01-01" # [IMPLEMENTION]="efde" # ) -# _mod_.prepare_string_to_env SETUP_ENVIRONMENT +# VAR_STRING="$(_mod_.prepare_string_to_env SETUP_ENVIRONMENT)" +# +# echo -e "$VAR_STRING" > "$PATH_FILE" # # Response: # 'NAME="MyName"\nCREATE_AT="2000-01-01"\nIMPLEMENTION="efde"' @@ -72,3 +100,53 @@ _mod_.prepare_string_to_env(){ echo "$env_str" } +_mod_.get_environment_variable() { + if [ "$#" -ne 2 ]; then + echo "Error: Se requieren dos parámetros: key, file" + return 1 + fi + + local key="$1" + local file="$2" + + key=$(echo "$key" | tr '[:lower:]' '[:upper:]' | tr ' ' '_') + + if [ -e "$file" ]; then + local value=$(grep "^$key=" "$file" | sed "s/^$key=//") + if [ -n "$value" ]; then + echo "$value" + else + echo "No encontrado" + fi + else + echo "Error: El archivo $file no existe." + return 1 + fi +} + +_mod_.load_variables_from_file() { + local file_path="$1" + local variables="" + + if [ -f "$file_path" ]; then + # Leer el archivo y construir la cadena de variables + while IFS='=' read -r key value; do + # Eliminar espacios en blanco alrededor de la clave y el valor + key=$(echo "$key" | sed 's/^[ \t]*//;s/[ \t]*$//') + value=$(echo "$value" | sed 's/^[ \t]*//;s/[ \t]*$//') + + # Agregar la variable a la cadena + variables+="$key=\"$value\" " + done < "$file_path" + + # Eliminar posibles espacios en blanco al final + variables=$(echo "$variables" | sed 's/[ \t]*$//') + + # Devolver la cadena de variables + echo "$variables" + else + echo "Error: El archivo $file_path no existe." + return 1 + fi +} + diff --git a/console/efde/tasks/implemention b/console/efde/tasks/implemention index 96151aa..769b5de 100644 --- a/console/efde/tasks/implemention +++ b/console/efde/tasks/implemention @@ -1,47 +1,88 @@ #!/usr/bin/env bash set -euo pipefail -IMPLEMENTION_EFDE_FOLDER=".efde" -declare -gA SETUP_ENVIRONMENT=( +declare -gA GLOBAL_SETUP_IMPLEMENTION=( [NAME]="" [CREATE_AT]="" [IMPLEMENTION]="" ) +declare -gA GLOBAL_IMPLEMENTION_EFDE_FOLDER=( + [FOLDER]=".efde" + [FILE_ENV]=".env" +) + +################################ +# CURRENT PROJECT +#------------------------------- +_mod_.get_current_path_env_file(){ + echo "$(pwd)/${GLOBAL_IMPLEMENTION_EFDE_FOLDER['FILE_ENV']}" +} + +################################ +# NEW OR CLONE PROJECT +#------------------------------- +_mod_.clear_global_variables(){ + GLOBAL_SETUP_IMPLEMENTION=() +} + +_mod_.get_new_path_project(){ + echo "$(pwd)/${GLOBAL_SETUP_IMPLEMENTION['NAME']}" +} + +_mod_.get_new_path_implemention(){ + echo "$(_mod_.get_new_path_project)/${GLOBAL_IMPLEMENTION_EFDE_FOLDER['FOLDER']}" +} + +_mod_.get_new_path_env_file(){ + echo "$(_mod_.get_new_path_implemention)/${GLOBAL_IMPLEMENTION_EFDE_FOLDER['FILE_ENV']}" +} _mod_.has_folder_implementation(){ - common.tasks.directory.exists "$(pwd)/$IMPLEMENTION_EFDE_FOLDER" + common.tasks.directory.exists "$(_mod_.get_new_path_implemention)" +} + +_mod_.create_symbolic_link_env(){ +local ORIGIN="${GLOBAL_IMPLEMENTION_EFDE_FOLDER['FOLDER']}/${GLOBAL_IMPLEMENTION_EFDE_FOLDER['FILE_ENV']}" + local TARGET="$(_mod_.get_new_path_project)/.env" + ln -sfT "$ORIGIN" "$TARGET" } _mod_.create_folder(){ - common.tasks.directory.create_recursive "$(pwd)/$1" + local FOLDER_PROJECT="$(_mod_.get_new_path_project)" + local FOLDER_IMPLEMENTION="$(_mod_.get_new_path_implemention)" + + if common.tasks.directory.exists "$FOLDER_PROJECT"; then + common.tasks.message.danger "Error: The project name already exists in this directory.\nVerify: $FOLDER_PROJECT" + _mod_.setup_environment + fi + common.tasks.directory.create_recursive "$FOLDER_IMPLEMENTION" } -_mod_.setup_environment(){ - local FUNCTION_INSTALL=$(printf "%s.tasks.install.environment" $RESPONSE_CODE) - local STRING_ENV="" +_mod_.set_envs(){ + local FILE="$(_mod_.get_new_path_env_file)" + efde.tasks.config.set_environment_variable $1 $2 $FILE +} +_mod.set_all_env(){ + local FILE="$(_mod_.get_new_path_env_file)" + local DATA_ENV="$(efde.tasks.config.prepare_string_to_env GLOBAL_SETUP_IMPLEMENTION)" - if ! common.tasks.module.exists_function "$FUNCTION_INSTALL" ;then - common.tasks.message.danger "The installation of the selected environment is not yet available '$RESPONSE_TITLE'" - common.tasks.prompt.confirm_default_yes "Back to menu?" && menu_init - fi + echo -e "$DATA_ENV" > "$FILE" - SETUP_ENVIRONMENT=( - [NAME]=$(_mod_.project_name) - [CREATE_AT]=$(common.tasks.datetime.get_formatted_datetime "%Y-%m-%d") - [IMPLEMENTION]=$RESPONSE_CODE - ) + _mod_.create_symbolic_link_env +} - _mod_.create_folder "${SETUP_ENVIRONMENT['NAME']}/$IMPLEMENTION_EFDE_FOLDER" - STRING_ENV="$(efde.tasks.config.prepare_string_to_env SETUP_ENVIRONMENT)" - echo -e "$STRING_ENV" > "${SETUP_ENVIRONMENT['NAME']}/$IMPLEMENTION_EFDE_FOLDER/env" +_mod_.copy_environment(){ + local ORIGIN="$PATH_CONSOLE/${GLOBAL_SETUP_IMPLEMENTION['IMPLEMENTION']}/environment/" + local TARGET="$(_mod_.get_new_path_project)" - cd "${SETUP_ENVIRONMENT['NAME']}" - $FUNCTION_INSTALL + shopt -s dotglob + cp -r "$ORIGIN"/* "$TARGET" + shopt -u dotglob } _mod_.project_name(){ - local value=$(common.tasks.prompt.request_input "$(common.tasks.message.warning "Enter the project name\nProject name: ")") + local value=$(common.tasks.prompt.request_input "$(common.tasks.message.warning "Enter the project name\nProject name:") ") if ! [[ "$value" =~ ^[[:alnum:][:space:]]+$ ]]; then common.tasks.message.danger "The entered value can only contain letters or numbers." @@ -51,3 +92,15 @@ _mod_.project_name(){ echo "$(common.tasks.string.convert_string_to_camelcase "$value")" } + +_mod_.setup_environment(){ + + GLOBAL_SETUP_IMPLEMENTION['NAME']=$(_mod_.project_name) + GLOBAL_SETUP_IMPLEMENTION['CREATE_AT']=$(common.tasks.datetime.get_formatted_datetime "%Y-%m-%d") + + _mod_.create_folder + _mod_.copy_environment + _mod.set_all_env +} + + diff --git a/environments/symfony/.docker/nginx/Dockerfile b/console/symfony/environment/.docker/nginx/Dockerfile similarity index 100% rename from environments/symfony/.docker/nginx/Dockerfile rename to console/symfony/environment/.docker/nginx/Dockerfile diff --git a/environments/symfony/.docker/nginx/default.conf b/console/symfony/environment/.docker/nginx/default.conf similarity index 100% rename from environments/symfony/.docker/nginx/default.conf rename to console/symfony/environment/.docker/nginx/default.conf diff --git a/environments/symfony/.docker/php/7.4/cli/Dockerfile b/console/symfony/environment/.docker/php/7.4/cli/Dockerfile similarity index 100% rename from environments/symfony/.docker/php/7.4/cli/Dockerfile rename to console/symfony/environment/.docker/php/7.4/cli/Dockerfile diff --git a/environments/symfony/.docker/php/7.4/fpm/Dockerfile b/console/symfony/environment/.docker/php/7.4/fpm/Dockerfile similarity index 100% rename from environments/symfony/.docker/php/7.4/fpm/Dockerfile rename to console/symfony/environment/.docker/php/7.4/fpm/Dockerfile diff --git a/environments/symfony/.docker/php/7.4/fpm/php.ini b/console/symfony/environment/.docker/php/7.4/fpm/php.ini similarity index 100% rename from environments/symfony/.docker/php/7.4/fpm/php.ini rename to console/symfony/environment/.docker/php/7.4/fpm/php.ini diff --git a/environments/symfony/.docker/php/8.1/cli/Dockerfile b/console/symfony/environment/.docker/php/8.1/cli/Dockerfile similarity index 100% rename from environments/symfony/.docker/php/8.1/cli/Dockerfile rename to console/symfony/environment/.docker/php/8.1/cli/Dockerfile diff --git a/environments/symfony/.docker/php/8.1/fpm/Dockerfile b/console/symfony/environment/.docker/php/8.1/fpm/Dockerfile similarity index 100% rename from environments/symfony/.docker/php/8.1/fpm/Dockerfile rename to console/symfony/environment/.docker/php/8.1/fpm/Dockerfile diff --git a/environments/symfony/.docker/php/8.1/fpm/php.ini b/console/symfony/environment/.docker/php/8.1/fpm/php.ini similarity index 100% rename from environments/symfony/.docker/php/8.1/fpm/php.ini rename to console/symfony/environment/.docker/php/8.1/fpm/php.ini diff --git a/environments/symfony/.gitignore b/console/symfony/environment/.gitignore similarity index 100% rename from environments/symfony/.gitignore rename to console/symfony/environment/.gitignore diff --git a/environments/symfony/docker-compose.yml b/console/symfony/environment/docker-compose.yml similarity index 100% rename from environments/symfony/docker-compose.yml rename to console/symfony/environment/docker-compose.yml diff --git a/console/symfony/props/menu b/console/symfony/props/menu index 4740e7c..294d455 100644 --- a/console/symfony/props/menu +++ b/console/symfony/props/menu @@ -1,16 +1,18 @@ #!/usr/bin/env bash -MENU_INIT=( - 'tools,Tools, ' - 'symfony,Install Symfony, ' - 'magento,Coming soon - Install Magento | Wordpress | Prestashop | Drupal | React | Angular | Vue | Next, ' -# 'magento,Coming soon - Install Magento, ' -# 'wordpress,Coming soon - Install Wordpress, ' -# 'woocommerce,Coming soon - Install WooCommerce, ' -# 'prestashop,Coming soon - Install Prestashop, ' -# 'drupal,Coming soon - Install Drupal, ' -# 'react,Coming soon - Install React, ' -# 'angular,Coming soon - Install Angular, ' -# 'vue,Coming soon - Install Vue, ' -# 'next,Coming soon - Install Next, ' -) \ No newline at end of file +_mod_MAIN=( + 'symfony.tasks.menu.show_config_efde,EFDE show config, ' + 'console,Console, ' + 'docker,Docker, ' +) + +_mod_CREATE_ENVIRONMENT=( + 'symfony.tasks.install.create_new_environment,Create new app, ' + 'symfony.tasks.install.clone_environment,Clone existing app, ' +) + +_mod_CREATE_ENVIRONMENT_VERSION=( + '5,Symfony 5.x,This version works with PHP-7.x' + '6,Symfony 6.x,This version works with PHP-8.x' +) + diff --git a/console/symfony/tasks/install b/console/symfony/tasks/install index 229dd07..130f018 100644 --- a/console/symfony/tasks/install +++ b/console/symfony/tasks/install @@ -1,12 +1,73 @@ #!/usr/bin/env bash set -euo pipefail +declare -gA GLOBAL_SYMFONY_INSTALL=( + [INSTALL_WEBAPP]=false + [MESSAGE_WARNING]="Default will install symfony for microservice projects or apis" + [MESSAGE_ASK]=$(common.tasks.message.msg_color warning "Do you want to install the packages for webapp?") + [MESSAGE_CLONE_GIT]="Enter the url of your repository" + [MESSAJE_CLONE_URL]=$(common.tasks.message.msg_color warning "Enter URL (https):") +) -_mod_.environment(){ - echo "INSTALAR SYMFONY $(pwd)" - echo $PATH_CONSOLE +_mod_.run_app_cli(){ + # shellcheck disable=SC2145 + symfony.tasks.main.run_command_app_cli "$@" } -_mod_.move_environment(){ - #mv $PATH_SETUP/symfony $(pwd)/ - echo "te" +_mod_.question_versions(){ + # PHP and Symfony version + symfony.tasks.menu.create_environment_version + local VERSION_PHP VERSION_SYMFONY + VERSION_SYMFONY=${GLOBAL_MENU_RESPONSE_ARRAY_ASOCITIVE['function']} + VERSION_PHP=$( [ "$VERSION_SYMFONY" == "5" ] && echo "7.4" || echo "8.1" ) + + GLOBAL_SETUP_IMPLEMENTION['IMPLEMENTION']="symfony" + GLOBAL_SETUP_IMPLEMENTION['VERSION']="$VERSION_SYMFONY" + GLOBAL_SETUP_IMPLEMENTION['PHP_VERSION']="$VERSION_PHP" +} + +_mod_.question_type(){ + # Type Instalation API or WEBAPP + common.tasks.message.info "${GLOBAL_SYMFONY_INSTALL['MESSAGE_WARNING']}" + if common.tasks.prompt.confirm_default_yes "${GLOBAL_SYMFONY_INSTALL['MESSAGE_ASK']}" ; then + GLOBAL_SYMFONY_INSTALL['INSTALL_WEBAPP']=true + fi +} + +_mod_.get_env_version(){ + local PATH_ENV="$(efde.tasks.implemention.get_current_path_env_file)" + echo $(common.tasks.env_variable.get_variable "VERSION" "$PATH_ENV") +} + +_mod_.prepare_setup_environment(){ + efde.tasks.implemention.setup_environment + # Siempre entro al proyecto + common.tasks.command_line.run false false "cd $(efde.tasks.implemention.get_new_path_project)" +} + +_mod_.create_new_environment(){ + _mod_.question_versions + _mod_.question_type + _mod_.prepare_setup_environment + _mod_.run_app_cli "composer create-project symfony/skeleton:$(_mod_.get_env_version).* ." + [ "${GLOBAL_SYMFONY_INSTALL['INSTALL_WEBAPP']}" = "true" ] && _mod_.run_app_cli "composer require webapp" + _mod_.docker_start +} + +_mod_.clone_environment(){ + _mod_.question_versions + _mod_.prepare_setup_environment + common.tasks.message.warning "${GLOBAL_SYMFONY_INSTALL['MESSAGE_CLONE_GIT']}" + local REPOSITORY_URL=$(common.tasks.prompt.request_input "${GLOBAL_SYMFONY_INSTALL['MESSAJE_CLONE_URL']} ") + + # MMTodo: Mover a un metodo de tasks.git + common.tasks.command_line.run true false "git clone $REPOSITORY_URL $(pwd)/app" + _mod_.docker_start +} + +_mod_.docker_start(){ + symfony.tasks.main.permissions_fix + docker.tasks.main.apache_stop + docker.tasks.main.dp_all_stop + docker.tasks.main.dp_up + efde.tasks.implemention.clear_global_variables } \ No newline at end of file diff --git a/console/symfony/tasks/main b/console/symfony/tasks/main new file mode 100644 index 0000000..95fb7e8 --- /dev/null +++ b/console/symfony/tasks/main @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +_mod_.run_command_app_cli(){ + # shellcheck disable=SC2145 + docker.tasks.main.dp_command_run "run --rm app_cli ${@}" +} + +_mod_.permissions_fix(){ + local PATH_APP="./app" + ! common.tasks.directory.exists "$PATH_APP" && common.tasks.directory.create_recursive "$PATH_APP" + common.tasks.command_line.run true false "sudo chown -R $USER:$USER $PATH_APP" +} diff --git a/console/symfony/tasks/menu b/console/symfony/tasks/menu new file mode 100644 index 0000000..a765a7f --- /dev/null +++ b/console/symfony/tasks/menu @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +_mod_.main(){ + common.tasks.menu.print_menu "Select an option:" "${symfony_props_menu_MAIN[@]}" +} + +_mod_.create_environment(){ + common.tasks.menu.print_menu "Select an option:" "${symfony_props_menu_CREATE_ENVIRONMENT[@]}" +} + +_mod_.create_environment_version(){ + common.tasks.menu.print_menu "Select an option:" "${symfony_props_menu_CREATE_ENVIRONMENT_VERSION[@]}" +} + +_mod_.show_config_efde(){ + cat "$(efde.tasks.implemention.get_current_path_env_file)" + if common.tasks.prompt.confirm_default_yes "Back to menu?"; then + common.console_clear + _mod_.main + else + exit + fi +} \ No newline at end of file diff --git a/docs/Developer.md b/docs/Developer.md new file mode 100644 index 0000000..e69de29 diff --git a/i18n/en_US b/i18n/en_US new file mode 100644 index 0000000..e69de29 diff --git a/i18n/es_ES b/i18n/es_ES new file mode 100644 index 0000000..e69de29