diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b03b8a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +tmp/ +cache/ diff --git a/commands/build.sh b/commands/build.sh index 3e36ae8..78d2fad 100755 --- a/commands/build.sh +++ b/commands/build.sh @@ -107,7 +107,7 @@ non_debug_print " ${GREEN}done${RESET}\n" # export SCRIPT_VARS # export SCRIPT_VARS_ENV # export SCRIPT_VARS_BUILD_ARGS -source "$ROOT_DIR/includes/get-script-vars.sh" +SILENT=false source "$ROOT_DIR/includes/get-script-vars.sh" # # Build docker-compose.yml diff --git a/commands/environment.sh b/commands/environment.sh index 7383668..34959f6 100755 --- a/commands/environment.sh +++ b/commands/environment.sh @@ -64,12 +64,12 @@ if ! $MODE_QUIET; then if ! $MODE_FORCE; then printf "Do you want to rebuild the project? (run with ${FLG_COL}--force${RESET} to always build)\n" printf "${YELLOW}WARNING${RESET}: This will ${RED}overwrite${RESET} existing docker files [y/N] " - read -n 1 -r + read -n 1 -r REPLY if [[ $REPLY =~ ^[Yy]$ ]]; then echo "" - bash $ENTRYPOINT build --force + bash $ENTRYPOINT up --force fi else - bash $ENTRYPOINT build --force + bash $ENTRYPOINT up --force fi fi diff --git a/commands/lock.sh b/commands/lock.sh index ed09ef8..2b6f108 100755 --- a/commands/lock.sh +++ b/commands/lock.sh @@ -60,12 +60,12 @@ if ! $MODE_NO_BUILD; then if ! $MODE_FORCE; then printf "Do you want to rebuild the project? (run with ${FLG_COL}--force${RESET} to always build)\n" printf "${YELLOW}WARNING${RESET}: This will ${RED}overwrite${RESET} existing docker files [y/N] " - read -n 1 -r + read -n 1 -r REPLY echo "" if [[ $REPLY =~ ^[Yy]$ ]]; then - bash $ENTRYPOINT build --force + bash $ENTRYPOINT up --force fi else - bash $ENTRYPOINT build --force + bash $ENTRYPOINT up --force fi fi diff --git a/commands/modules.sh b/commands/modules.sh index dd6e7eb..6586fd9 100755 --- a/commands/modules.sh +++ b/commands/modules.sh @@ -26,6 +26,8 @@ MODE_NO_BUILD=false MODE_NO_SCRIPTS=false MODE_PRINT_ACTIVE_ONLY=false +UP_ARGS=() + while [[ "$#" -gt 0 ]]; do case $1 in -h | --help) @@ -35,6 +37,9 @@ while [[ "$#" -gt 0 ]]; do printf " ${FLG_COL}-a${RESET}, ${FLG_COL}--active${RESET}" printf "\t\tOnly list active modules\n" + printf " ${FLG_COL}--no-chown${RESET}" + printf "\t\t\tPass --no-chown to 'sync' command\n" + printf " ${FLG_COL}--no-build${RESET}" printf "\t\t\tDon't attempt to build\n" @@ -51,9 +56,14 @@ while [[ "$#" -gt 0 ]]; do ;; --no-build) MODE_NO_BUILD=true + UP_ARGS+=("--no-build") ;; --no-scripts) MODE_NO_SCRIPTS=true + UP_ARGS+=("--no-scripts") + ;; + --no-chown) + UP_ARGS+=("--no-chown") ;; -a | --active) MODE_PRINT_ACTIVE_ONLY=true @@ -99,7 +109,7 @@ source "$ROOT_DIR/includes/blueprint/populate_env.sh" "" yq_read_array MODULES_TO_LOAD 'modules' EXPLICIT_MODULES_LIST=(${MODULES_TO_LOAD[@]}) -source "$ROOT_DIR/includes/resolve-dependencies.sh" ${MODULES_TO_LOAD[@]} +SILENT=true source "$ROOT_DIR/includes/resolve-dependencies.sh" ${MODULES_TO_LOAD[@]} ACTIVE_MODULES_LIST=(${MODULES_TO_LOAD[@]}) MODULES_LIST=() @@ -221,6 +231,7 @@ else done fi +script_paths=() needs_rebuild=false for MODULE in "${MODULES[@]}"; do @@ -247,63 +258,59 @@ for MODULE in "${MODULES[@]}"; do ;; esac - if ! $MODE_QUIET && ! $MODE_NO_BUILD && $needs_rebuild; then - if ! $MODE_FORCE; then - printf "Do you want to rebuild the project? (run with ${FLG_COL}--force${RESET} to always build)\n" - printf "${YELLOW}WARNING${RESET}: This will ${RED}overwrite${RESET} existing docker files [y/N] " - read -n 1 -r - echo "" - if [[ $REPLY =~ ^[Yy]$ ]]; then - bash $ENTRYPOINT build --force - else - continue - fi - else - bash $ENTRYPOINT build --force - fi + # Add base blueprint module scripts first + path="$BLUEPRINT_DIR/modules/$MODULE/scripts/$ACTION.sh" + if [[ -f "$path" ]]; then + script_paths+=("$path") fi - if ! $MODE_NO_SCRIPTS; then - script_paths=() - - # Add base blueprint module scripts first - path="$BLUEPRINT_DIR/modules/$MODULE/scripts/$ACTION.sh" - if [[ -f "$path" ]]; then - script_paths+=("$path") - fi + # Then add environment module scripts + path="$ENV_DIR/modules/$MODULE/scripts/$ACTION.sh" + if [[ -f "$path" ]]; then + script_paths+=("$path") + fi +done - # Then add environment module scripts - path="$ENV_DIR/modules/$MODULE/scripts/$ACTION.sh" - if [[ -f "$path" ]]; then - script_paths+=("$path") +if ! $MODE_QUIET && ! $MODE_NO_BUILD && $needs_rebuild; then + if ! $MODE_FORCE; then + printf "Do you want to rebuild the project? (run with ${FLG_COL}--force${RESET} to always build)\n" + printf "${YELLOW}WARNING${RESET}: This will ${RED}overwrite${RESET} existing docker files [y/N] " + read -n 1 -r REPLY + echo "" + if [[ $REPLY =~ ^[Yy]$ ]]; then + bash $ENTRYPOINT up --force ${UP_ARGS[@]} fi + else + bash $ENTRYPOINT up --force ${UP_ARGS[@]} + fi +fi - status=0 +if ! $MODE_NO_SCRIPTS; then + status=0 - # export SCRIPT_VARS - # export SCRIPT_VARS_ENV - # export SCRIPT_VARS_BUILD_ARGS - source "$ROOT_DIR/includes/get-script-vars.sh" + # export SCRIPT_VARS + # export SCRIPT_VARS_ENV + # export SCRIPT_VARS_BUILD_ARGS + source "$ROOT_DIR/includes/get-script-vars.sh" - for path in "${script_paths[@]}"; do - printf "Running script for module '$MODULE'...\n" - debug_print "Running script: ${path#$BLUEPRINT_DIR/}" + for path in "${script_paths[@]}"; do + printf "Running script for module '$MODULE'...\n" + debug_print "Running script: ${path#$BLUEPRINT_DIR/}" - PROGRAM="$(source "$ROOT_DIR/includes/script/prepare.sh" "$(cat "$path")")" + PROGRAM="$(source "$ROOT_DIR/includes/script/prepare.sh" "$(cat "$path")")" - command="bash -c \"$PROGRAM\"" - bash $ENTRYPOINT "${SCRIPT_VARS_ENV[@]}" $DEFAULT_SERVICE exec "$command" + command="bash -c \"$PROGRAM\"" + bash $ENTRYPOINT "${SCRIPT_VARS_ENV[@]}" $DEFAULT_SERVICE exec "$command" - status=$? - - if [[ $status > 0 ]]; then - break - fi - done + status=$? if [[ $status > 0 ]]; then - printf -- "${RED}ERROR${RESET}: Module script returned non-zero code: ${path#$BLUEPRINT_DIR/}\n" - exit $status + break fi + done + + if [[ $status > 0 ]]; then + printf -- "${RED}ERROR${RESET}: Module script returned non-zero code: ${path#$BLUEPRINT_DIR/}\n" + exit $status fi -done +fi diff --git a/commands/new.sh b/commands/new.sh index d091f65..7c45280 100755 --- a/commands/new.sh +++ b/commands/new.sh @@ -130,7 +130,7 @@ fi if ! [[ -f "$PWD/$PROJECT_BLUEPRINT_FILE" ]]; then # export BLUEPRINT_PATH - SILENT=false source "$ROOT_DIR/includes/blueprint/compile.sh" "$BLUEPRINT" + SILENT=true source "$ROOT_DIR/includes/blueprint/compile.sh" "$BLUEPRINT" debug_switch_context "NEW" # Populate project blueprint @@ -195,8 +195,6 @@ if ! [[ -f "$PWD/$PROJECT_BLUEPRINT_FILE" ]]; then fi done - rm -f "$BLUEPRINT_PATH" - fi if $FORCE_GENERATE; then diff --git a/commands/process.sh b/commands/process.sh index a263d31..1ae036e 100755 --- a/commands/process.sh +++ b/commands/process.sh @@ -54,7 +54,7 @@ fi while [[ "$#" -gt 0 ]]; do case $1 in -h | --help) - printf "${CMD_COL}process${RESET} [${FLG_COL}options${RESET}] ${ARG_COL}${RESET}" + printf "${CMD_COL}process${RESET} ${ARG_COL}${RESET} [${FLG_COL}options${RESET}]" printf "\t" printf "Preprocess dockerfile template from the blueprint\n" diff --git a/commands/pull.sh b/commands/pull.sh index 6899a8a..e545a95 100755 --- a/commands/pull.sh +++ b/commands/pull.sh @@ -17,6 +17,8 @@ # Function mode allows to use this command in conjunction # with others (i.e. create). +debug_switch_context "PULL" + # # Read arguments # @@ -30,8 +32,9 @@ MODE_GET_QUALIFIED=false while [[ "$#" -gt 0 ]]; do case $1 in -h | --help) - printf "${CMD_COL}pull${RESET} ${ARG_COL}${RESET} [${FLG_COL}options${RESET}]" - printf "\tDownload the latest version of blueprint\n" + if [[ "$WITH_USAGE" -eq 1 ]]; then printf "Usage:\n"; fi + printf "${CMD_COL}pull${RESET} [${ARG_COL}${RESET}] [${FLG_COL}options${RESET}]" + printf "\tDownload the latest version of a blueprint\n" printf " ${FLG_COL}--clean${RESET}" printf "\t\t\tRemove already existing copy of a blueprint and install fresh download\n" @@ -49,14 +52,8 @@ while [[ "$#" -gt 0 ]]; do MODE_GET_QUALIFIED=true ;; *) - if [[ -z "$1" ]]; then - printf "Usage: " - bash $ENTRYPOINT pull --help - exit 1 - fi - if [[ -z $BLUEPRINT ]]; then - BLUEPRINT=$1 + BLUEPRINT="$1" fi ;; esac @@ -64,6 +61,25 @@ while [[ "$#" -gt 0 ]]; do shift done +if [[ -z "$BLUEPRINT" ]]; then + ! $AS_FUNCTION && debug_print "No blueprint name provided - trying to resolve from $PROJECT_BLUEPRINT_FILE..." + + # Try to read blueprint name from docker-blueprint.yml + if [[ -f "$PROJECT_BLUEPRINT_FILE" ]]; then + yq_read_value BLUEPRINT 'from' + if [[ -z "$BLUEPRINT" ]]; then + ! $AS_FUNCTION && printf "${RED}ERROR${RESET}: Unable to resolve blueprint from project blueprint file.\n\n" + WITH_USAGE=1 bash $ENTRYPOINT pull --help + exit 1 + else + ! $AS_FUNCTION && debug_print "Found blueprint '$BLUEPRINT' in project blueprint file" + fi + else + bash $ENTRYPOINT pull --help + exit 1 + fi +fi + # # Parse blueprint name and branch # @@ -174,7 +190,14 @@ else else PREVIOUS_DIR="$PWD" cd "$BLUEPRINT_DIR" - git fetch >/dev/null + git checkout master &>/dev/null + git pull &>/dev/null + if [[ $? -gt 0 ]]; then + cd "$PREVIOUS_DIR" + printf "${RED}ERROR${RESET}: Blueprint directory has local changes\n" + printf "You can clear local changes with 'docker-blueprint pull --clean'\n" + exit 1 + fi cd "$PREVIOUS_DIR" fi fi @@ -222,6 +245,21 @@ if ! $MODE_DRY_RUN; then fi fi + yq_read_value CHECKPOINT 'version' + + # Set the blueprint repository to the version specified. + # This allows to always safely reproduce previous versions of the blueprint. + if [[ -n "$CHECKPOINT" ]]; then + if ! $AS_FUNCTION; then + printf "${BLUE}INFO${RESET}: Version lock applied: ${CYAN}$CHECKPOINT${RESET}\n" + git checkout $CHECKPOINT 2>/dev/null + else + git checkout $CHECKPOINT &>/dev/null + fi + else + ! $AS_FUNCTION && printf "${BLUE}INFO${RESET}: No version lock found - using latest version.\n" + fi + cd $PREVIOUS_DIR fi diff --git a/commands/run.sh b/commands/run.sh index 661ade7..28cb31c 100755 --- a/commands/run.sh +++ b/commands/run.sh @@ -140,6 +140,8 @@ elif [[ -n "$PROJECT_CONTEXT" ]]; then debug_print "Using DEFAULT context: $PROJECT_CONTEXT" fi +debug_print "Program to run:\n%s\n" "$PROGRAM" + # Escape backslashes first PROGRAM="$(echo "$PROGRAM" | sed -E 's/\\/\\\\/g')" # Escape variable sign ($) to execute it inside runtime @@ -149,10 +151,9 @@ PROGRAM="$(echo "$PROGRAM" | sed -E 's/"/\\"/g')" command="env ${ENV_PREFIX[*]} $RUNTIME \"$PROGRAM\"" -debug_print "Program to run:\n$PROGRAM" debug_print "Running..." -bash $ENTRYPOINT ${ENTRYPOINT_ARGS[*]} -- $SERVICE $COMMAND_VERB "$command" +bash $ENTRYPOINT ${ENTRYPOINT_ARGS[*]} $SERVICE $COMMAND_VERB "$command" for key in "${ENVIRONMENT_KEYS[@]}"; do unset $key diff --git a/commands/sync.sh b/commands/sync.sh index b3304be..6bee836 100755 --- a/commands/sync.sh +++ b/commands/sync.sh @@ -12,6 +12,7 @@ shift MODE_NO_CHOWN=false MODE_SKIP_USER=false +MODE_SKIP_ENV=false while [[ "$#" -gt 0 ]]; do case $1 in @@ -28,11 +29,13 @@ while [[ "$#" -gt 0 ]]; do ;; --no-chown) MODE_NO_CHOWN=true - ;; --skip-user) MODE_SKIP_USER=true ;; + --skip-env) + MODE_SKIP_ENV=true + ;; esac shift @@ -64,12 +67,23 @@ if ! $MODE_SKIP_USER && [[ -n "$SYNC_USER" ]]; then fi fi -if [[ -f .env ]]; then +if ! $MODE_SKIP_ENV && [[ -f .env ]]; then debug_print "Found .env file in the project directory" debug_print "Looking for docker-compose files..." + files=( + docker-compose.$PROJECT_CONTEXT.y*ml + docker-compose.y*ml + ) + temp_file="$TEMP_DIR/docker-compose.env" - for file in docker-compose*; do + touch "$temp_file" + + for file in ${files[@]}; do + if [[ ! -f "$file" ]]; then + continue + fi + debug_print "Found file: $file" if [[ ! -f "$temp_file" ]]; then diff --git a/commands/up.sh b/commands/up.sh index 3fda85f..242b90c 100755 --- a/commands/up.sh +++ b/commands/up.sh @@ -31,9 +31,6 @@ while [[ "$#" -gt 0 ]]; do printf " ${FLG_COL}--no-sync${RESET}" printf "\t\t\tDon't attempt to sync service container with the local environment\n" - printf " ${FLG_COL}--no-chown${RESET}" - printf "\t\t\tPass --no-chown to 'sync' command\n" - printf " ${FLG_COL}--no-build${RESET}" printf "\t\t\tDon't attempt to build the blueprint\n" @@ -51,6 +48,21 @@ while [[ "$#" -gt 0 ]]; do printf "\t\t\t\tThis will force to regenerate new docker files\n" printf "\t\t\t\tpotentially overwriting current ones\n" + printf " ${FLG_COL}--no-chown${RESET}" + printf "\t\t\tPass --no-chown to 'sync' command\n" + + printf " ${FLG_COL}--skip-user${RESET}" + printf "\t\t\tPass --skip-user to 'sync' command\n" + + printf " ${FLG_COL}--skip-env${RESET}" + printf "\t\t\tPass --skip-env to 'sync' command\n" + + printf " ${FLG_COL}--skip-compose${RESET}" + printf "\t\tDon't generate docker-compose files\n" + + printf " ${FLG_COL}--skip-dockerfile${RESET}" + printf "\t\tDon't generate dockerfiles\n" + exit ;; -f | --force) @@ -71,6 +83,12 @@ while [[ "$#" -gt 0 ]]; do --no-chown) SYNC_ARGS+=('--no-chown') ;; + --skip-user) + SYNC_ARGS+=('--skip-user') + ;; + --skip-env) + SYNC_ARGS+=('--skip-env') + ;; --no-sync) MODE_SYNC=false ;; @@ -131,7 +149,7 @@ if [[ -f "$path" ]]; then debug_print "Found: ${path#$BLUEPRINT_DIR/}" fi -source "$ROOT_DIR/includes/resolve-dependencies.sh" "" +SILENT=true source "$ROOT_DIR/includes/resolve-dependencies.sh" "" ACTIVE_MODULES_LIST=(${MODULES_TO_LOAD[@]}) for module in ${MODULES_TO_LOAD[@]}; do @@ -185,6 +203,8 @@ if [[ $status > 0 ]]; then exit $status fi -if ! $MODE_SCRIPTS_ONLY && $MODE_SYNC; then - bash $ENTRYPOINT sync --no-chown --skip-user +# Sync again, because new files could have been created by scripts + +if ! $MODE_NO_SCRIPTS && $MODE_SYNC; then + bash $ENTRYPOINT sync ${SYNC_ARGS[@]} --skip-user fi diff --git a/commands/upgrade.sh b/commands/upgrade.sh new file mode 100755 index 0000000..b1d278c --- /dev/null +++ b/commands/upgrade.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +debug_switch_context "UPGRADE" + +debug_print "Running the command..." + +shift + +MODE_FORCE=false +MODE_NO_BUILD=false + +while [[ "$#" -gt 0 ]]; do + case $1 in + -h | --help) + printf "${CMD_COL}upgrade${RESET}" + printf "\t\t\tUpgrade the blueprint version to the latest version\n" + exit + ;; + -f | --force) + MODE_FORCE=true + ;; + --no-build) + MODE_NO_BUILD=true + ;; + esac + + shift +done + +yq_read_value BLUEPRINT 'from' +yq_read_value PREVIOUS_VERSION 'version' + +debug_print "Current version: $PREVIOUS_VERSION" + +source "$ROOT_DIR/includes/blueprint/populate_env.sh" "" + +cd "$BLUEPRINT_DIR" + +target_branch="$(echo "$BLUEPRINT_QUALIFIED_NAME" | cut -d: -f2)" + +CHECKPOINT="$(git rev-parse origin/$target_branch)" +if [[ $? -eq 0 ]]; then + if [[ "$CHECKPOINT" != "$PREVIOUS_VERSION" ]]; then + printf "New version available: ${CYAN}$CHECKPOINT${RESET}\n" + else + printf "Already using latest version\n" + exit + fi +else + printf "${RED}ERROR${RESET}: Unable to checkout version $CHECKPOINT\n" + exit 1 +fi + +cd "$PROJECT_DIR" + +debug_print "New version: $CHECKPOINT" + +if ! $MODE_NO_BUILD; then + if ! $MODE_FORCE; then + printf "Do you want to rebuild the project? (run with ${FLG_COL}--force${RESET} to always build)\n" + printf "${YELLOW}WARNING${RESET}: This will ${RED}overwrite${RESET} existing docker files [y/N] " + read -n 1 -r REPLY + echo "" + if [[ $REPLY =~ ^[Yy]$ ]]; then + yq_write_value "version" "$CHECKPOINT" + bash $ENTRYPOINT up --force + fi + else + yq_write_value "version" "$CHECKPOINT" + bash $ENTRYPOINT up --force + fi +else + yq_write_value "version" "$CHECKPOINT" + printf "Updated version to the latest without rebuilding\n" + printf "You can build manually later with 'docker-blueprint build --force'\n" + printf "\n" +fi diff --git a/entrypoint.sh b/entrypoint.sh index be5f34e..0cbbf9a 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,16 +1,16 @@ #!/bin/bash # MIT License -# +# # Copyright (c) 2020-2021 Aleksei Ivanov -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. diff --git a/includes/blueprint/compile.sh b/includes/blueprint/compile.sh index 59d4cf9..74c7ba3 100755 --- a/includes/blueprint/compile.sh +++ b/includes/blueprint/compile.sh @@ -30,7 +30,7 @@ if [[ -n $CHECKPOINT ]]; then cd "$BLUEPRINT_DIR" git checkout $CHECKPOINT 2> /dev/null if [[ $? -eq 0 ]]; then - printf "Version: ${CYAN}$CHECKPOINT${RESET}\n" + ! $SILENT && printf "Version: ${CYAN}$CHECKPOINT${RESET}\n" else printf "${RED}ERROR${RESET}: Unable to checkout version $CHECKPOINT\n" exit 1 @@ -135,13 +135,14 @@ fi cd $BLUEPRINT_DIR -hash=$(git rev-parse HEAD) 2>/dev/null && \ - ! $SILENT && non_debug_print "." +hash=$(git rev-parse HEAD) 2>/dev/null if [[ $? > 0 ]]; then unset hash fi +! $SILENT && non_debug_print "." + cd $PROJECT_DIR # ... and store it for the version lock diff --git a/includes/get-script-vars.sh b/includes/get-script-vars.sh index 7a34517..e7d0f96 100644 --- a/includes/get-script-vars.sh +++ b/includes/get-script-vars.sh @@ -2,20 +2,29 @@ if [[ -z "$BLUEPRINT_PATH" ]]; then # export BLUEPRINT_PATH - SILENT=false source "$ROOT_DIR/includes/blueprint/compile.sh" "$BLUEPRINT" + SILENT=true source "$ROOT_DIR/includes/blueprint/compile.sh" "$BLUEPRINT" +fi + +if [[ -z $SILENT ]]; then + SILENT=false fi # Read values from merged blueprint -debug_newline_print "Reading configuration..." +! $SILENT && debug_newline_print "Reading configuration..." -yq_read_keys BUILD_ARGS_KEYS "build_args" "$BLUEPRINT_PATH" && non_debug_print "." +yq_read_keys BUILD_ARGS_KEYS "build_args" "$BLUEPRINT_PATH" +! $SILENT && non_debug_print "." SCRIPT_VARS=() +SCRIPT_VARS_ENV=() +SCRIPT_VARS_BUILD_ARGS=() add_variable() { debug_print "Added variable $1='$2'" SCRIPT_VARS+=("BLUEPRINT_$1=$2") + SCRIPT_VARS_ENV+=("-e BLUEPRINT_$1='$2'") + SCRIPT_VARS_BUILD_ARGS+=("--build-arg $1='$2'") } add_variable "BLUEPRINT_DIR" "${BLUEPRINT_DIR#"$PWD/"}" @@ -23,28 +32,34 @@ add_variable "ENV_DIR" "${ENV_DIR#"$PWD/"}" add_variable "ENV_NAME" "$ENV_NAME" for variable in ${BUILD_ARGS_KEYS[@]}; do - yq_read_value value "build_args.$variable" "$BLUEPRINT_PATH" && non_debug_print "." + yq_read_value value "build_args.$variable" "$BLUEPRINT_PATH" + ! $SILENT && non_debug_print "." # Replace build argument value with env variable value if it is set if [[ -n ${!variable+x} ]]; then value="${!variable:-}" fi - add_variable "$variable" "$value" && non_debug_print "." + add_variable "$variable" "$value" + ! $SILENT && non_debug_print "." done -yq_read_keys DEPENDENCIES_KEYS "dependencies" "$BLUEPRINT_PATH" && non_debug_print "." +yq_read_keys DEPENDENCIES_KEYS "dependencies" "$BLUEPRINT_PATH" +! $SILENT && non_debug_print "." for key in "${DEPENDENCIES_KEYS[@]}"; do - yq_read_array DEPS "dependencies.$key" "$BLUEPRINT_PATH" && non_debug_print "." + yq_read_array DEPS "dependencies.$key" "$BLUEPRINT_PATH" + ! $SILENT && non_debug_print "." key="$(echo "$key" | tr [:lower:] [:upper:])" add_variable "DEPS_$key" "${DEPS[*]}" done -yq_read_keys PURGE_KEYS "purge" "$BLUEPRINT_PATH" && non_debug_print "." +yq_read_keys PURGE_KEYS "purge" "$BLUEPRINT_PATH" +! $SILENT && non_debug_print "." for key in "${PURGE_KEYS[@]}"; do - yq_read_array PURGE "purge.$key" "$BLUEPRINT_PATH" && non_debug_print "." + yq_read_array PURGE "purge.$key" "$BLUEPRINT_PATH" + ! $SILENT && non_debug_print "." key="$(echo "$key" | tr [:lower:] [:upper:])" add_variable "PURGE_$key" "${PURGE[*]}" done @@ -69,26 +84,8 @@ for module in "${MODULES_TO_LOAD[@]}"; do fi done -non_debug_print " ${GREEN}done${RESET}\n" +! $SILENT && non_debug_print " ${GREEN}done${RESET}\n" export SCRIPT_VARS - -SCRIPT_VARS_BUILD_ARGS=() - -for var in "${SCRIPT_VARS[@]}"; do - name="$(echo "$var" | cut -d'=' -f1)" - value="$(echo "$var" | cut -d'=' -f2)" - SCRIPT_VARS_BUILD_ARGS+=("--build-arg $name='$value'") -done - -export SCRIPT_VARS_BUILD_ARGS - -SCRIPT_VARS_ENV=() - -for var in "${SCRIPT_VARS[@]}"; do - name="$(echo "$var" | cut -d'=' -f1)" - value="$(echo "$var" | cut -d'=' -f2)" - SCRIPT_VARS_ENV+=("-e $name='$value'") -done - export SCRIPT_VARS_ENV +export SCRIPT_VARS_BUILD_ARGS diff --git a/includes/yq.sh b/includes/yq.sh index 21c29ef..d009814 100755 --- a/includes/yq.sh +++ b/includes/yq.sh @@ -40,7 +40,7 @@ yq_merge() { yq_read_value() { if [[ -z "$3" ]]; then - FILE="$PROJECT_BLUEPRINT_FILE" + FILE="$PROJECT_DIR/$PROJECT_BLUEPRINT_FILE" else FILE="$3" fi @@ -50,7 +50,7 @@ yq_read_value() { yq_write_value() { if [[ -z "$3" ]]; then - FILE="$PROJECT_BLUEPRINT_FILE" + FILE="$PROJECT_DIR/$PROJECT_BLUEPRINT_FILE" else FILE="$3" fi @@ -60,7 +60,7 @@ yq_write_value() { yq_read_array() { if [[ -z "$3" ]]; then - FILE="$PROJECT_BLUEPRINT_FILE" + FILE="$PROJECT_DIR/$PROJECT_BLUEPRINT_FILE" else FILE="$3" fi @@ -70,7 +70,7 @@ yq_read_array() { yq_read_keys() { if [[ -z "$3" ]]; then - FILE="$PROJECT_BLUEPRINT_FILE" + FILE="$PROJECT_DIR/$PROJECT_BLUEPRINT_FILE" else FILE="$3" fi diff --git a/install.sh b/install.sh index a5d135d..bd2cd92 100755 --- a/install.sh +++ b/install.sh @@ -1,18 +1,107 @@ #!/bin/bash +HIGHLIGHT="\033[1;33m" +RESET="\033[0;0m" + REQUIREMENTS=( git - docker - docker-compose ) +is_wsl=false + +if grep -qEi "(Microsoft|WSL)" /proc/version &>/dev/null; then + is_wsl=true +fi + +can_install_docker=false + +is_ubuntu=false +if lsb_release -si &>/dev/null | grep -qEi "Ubuntu"; then + is_ubuntu=true + can_install_docker=true +fi + for PROGRAM in "${REQUIREMENTS[@]}"; do - if [[ -z $(which $PROGRAM) ]]; then + if [[ -z "$(which $PROGRAM)" ]]; then echo "Error: '$PROGRAM' is not installed. Please install '$PROGRAM' first." + if which apt-get &>/dev/null; then + echo "You can try install it by running 'sudo apt-get install $PROGRAM'" + fi exit 1 fi done +# +# docker installer +# + +if ! which docker &>/dev/null; then + printf "You do not appear to have 'docker' installed (${HIGHLIGHT}https://docker.com${RESET})\n" + + if $is_wsl; then + printf "We detected that you are running this installer under WSL.\n" + printf "Please install Docker for Desktop for the best experience:\n" + printf "${HIGHLIGHT}https://www.docker.com/products/docker-desktop${RESET}\n" + printf "\n" + printf "Do you want to continue installing? [y/N] " + read -n 1 -r REPLY + echo "" + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + else + printf "You can install docker using convinience script:\n" + printf "${HIGHLIGHT}https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script${RESET}\n" + exit 1 + fi + echo "" +fi + +# +# docker-compose installer +# + +if ! which docker-compose &>/dev/null; then + printf "You do not appear to have 'docker-compose' installed (${HIGHLIGHT}https://docs.docker.com/compose/install${RESET})\n" + + printf "We can attempt to automatically install 'docker-compose' using curl:\n" + printf "${HIGHLIGHT}https://docs.docker.com/compose/install/#install-compose-on-linux-systems${RESET}\n" + printf "\n" + printf "Do you want to automatically install 'docker-compose'? [Y/n] " + read -n 1 -r REPLY + echo "" + if [[ -z "$REPLY" ]] || [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Trying to install 'docker-compose'..." + sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + if [[ $? > 0 ]]; then + echo "Unable to install 'docker-compose', skipping..." + else + sudo chmod +x /usr/local/bin/docker-compose + fi + fi + echo "" +fi + +# +# yq installer +# + +if ! which yq &>/dev/null; then + printf "You do not appear to have 'yq' installed (${HIGHLIGHT}https://github.com/mikefarah/yq${RESET})\n" + printf "For the best experience it is recommended to install a standalone version of 'yq'\n" + printf "\n" + printf "Do you want to attempt to automatically install 'yq'? [Y/n] " + read -n 1 -r REPLY + echo "" + if [[ -z "$REPLY" ]] || [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Trying to install using webi..." + curl -sS https://webinstall.dev/yq@4 | bash + printf "\n" + printf "${HIGHLIGHT}Please restart your shell in order for the changes to take effect${RESET}\n" + printf "\n" + fi +fi + PROJECT_DIR=~/.docker-blueprint ENTRYPOINT="$PROJECT_DIR/entrypoint.sh"