├── .gitattributes ├── .gitignore ├── src ├── commands │ ├── check.sh │ ├── restart.sh │ ├── enter.sh │ ├── stop.sh │ ├── exec.sh │ ├── config │ │ ├── docroot.sh │ │ ├── projects.sh │ │ ├── php.sh │ │ ├── mysql.sh │ │ └── apache.sh │ ├── version.sh │ ├── lib │ │ ├── docker.sh │ │ ├── config.sh │ │ └── choices.sh │ ├── mysql.sh │ ├── open.sh │ ├── run.sh │ ├── config.sh │ ├── update.sh │ └── help.sh ├── utils │ ├── codes.sh │ ├── prompt.sh │ └── messages.sh ├── config.sh ├── devilbox-cli.sh └── main.sh ├── .editorconfig ├── bin ├── clean.sh ├── lint.sh └── build.sh ├── package.json ├── LICENSE ├── CHANGELOG.md ├── README.md └── dist └── devilbox-cli.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /npm-debug.log 3 | -------------------------------------------------------------------------------- /src/commands/check.sh: -------------------------------------------------------------------------------- 1 | check_command () { 2 | ./check-config.sh 3 | } 4 | -------------------------------------------------------------------------------- /src/commands/restart.sh: -------------------------------------------------------------------------------- 1 | restart_command() { 2 | stop_command 3 | run_command "$@" 4 | } 5 | -------------------------------------------------------------------------------- /src/commands/enter.sh: -------------------------------------------------------------------------------- 1 | enter_command () { 2 | if ! is_running; then 3 | error "Devilbox containers are not running" 4 | return "$KO_CODE" 5 | fi 6 | ./shell.sh 7 | } 8 | -------------------------------------------------------------------------------- /src/commands/stop.sh: -------------------------------------------------------------------------------- 1 | stop_command () { 2 | if ! is_running; then 3 | error "Devilbox containers are not running" 4 | return "$KO_CODE" 5 | fi 6 | docker-compose stop 7 | docker-compose rm -f 8 | } 9 | -------------------------------------------------------------------------------- /src/commands/exec.sh: -------------------------------------------------------------------------------- 1 | exec_command() { 2 | if ! is_running; then 3 | error "Devilbox containers are not running" 4 | return "$KO_CODE" 5 | fi 6 | 7 | docker-compose exec -u devilbox php bash -c "$@" 8 | } 9 | -------------------------------------------------------------------------------- /src/commands/config/docroot.sh: -------------------------------------------------------------------------------- 1 | get_current_document_root () { 2 | get_readable_current_config "Document root" "$DOCROOT_CONFIG" 3 | } 4 | 5 | set_document_root () { 6 | local new=$1 7 | set_readable_config "Document root" "$DOCROOT_CONFIG" "$new" 8 | } 9 | -------------------------------------------------------------------------------- /src/commands/config/projects.sh: -------------------------------------------------------------------------------- 1 | get_current_projects_path () { 2 | get_readable_current_config "Projects path" "$WWWPATH_CONFIG" 3 | } 4 | 5 | set_projects_path () { 6 | local new=$1 7 | set_readable_config "Projects path" "$WWWPATH_CONFIG" "$new" 8 | } 9 | -------------------------------------------------------------------------------- /src/commands/version.sh: -------------------------------------------------------------------------------- 1 | version_command() { 2 | printf "\n" 3 | printf "%s\n" "$NAME v$VERSION ($DATE)" 4 | printf "%s\n" "${COLOR_LIGHT_GRAY}$DESCRIPTION${COLOR_DEFAULT}" 5 | printf "%s\n" "${COLOR_LIGHT_GRAY}$LINK${COLOR_DEFAULT}" 6 | printf "\n" 7 | } 8 | -------------------------------------------------------------------------------- /src/commands/lib/docker.sh: -------------------------------------------------------------------------------- 1 | is_running () { 2 | local all 3 | all=$(docker-compose ps 2> /dev/null | grep "devilbox" | awk '{print $3}' | grep "Up") 4 | if was_success; then 5 | return "$OK_CODE"; 6 | else 7 | return "$KO_CODE"; 8 | fi 9 | } 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.{yml,yaml}] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /bin/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT="devilbox-cli.sh" 4 | DIST_PATH="./dist/" 5 | BUILD="${DIST_PATH}${SCRIPT}" 6 | 7 | if [ -f "$BUILD" ]; then 8 | rm -rf "$BUILD" 9 | fi 10 | 11 | if [ ! -e "$DIST_PATH" ]; then 12 | mkdir -p "$DIST_PATH" 13 | fi 14 | 15 | echo "Done." 16 | exit 0 17 | -------------------------------------------------------------------------------- /src/commands/config/php.sh: -------------------------------------------------------------------------------- 1 | get_current_php_version () { 2 | get_readable_current_choice "PHP" "$PHP_CONFIG" 3 | } 4 | 5 | get_all_php_versions () { 6 | get_readable_all_choices "PHP" "$PHP_CONFIG" 7 | } 8 | 9 | set_php_version () { 10 | local new=$1 11 | set_readable_choice "PHP" "$PHP_CONFIG" "$new" 12 | } 13 | -------------------------------------------------------------------------------- /src/commands/mysql.sh: -------------------------------------------------------------------------------- 1 | mysql_command() { 2 | if ! is_running; then 3 | error "Devilbox containers are not running" 4 | return "$KO_CODE" 5 | fi 6 | 7 | if [ -z "$1" ]; then 8 | exec_command 'mysql -hmysql -uroot' 9 | else 10 | exec_command "mysql -hmysql -uroot -e '$1'" 11 | fi 12 | } 13 | -------------------------------------------------------------------------------- /src/commands/config/mysql.sh: -------------------------------------------------------------------------------- 1 | get_current_mysql_version () { 2 | get_readable_current_choice "MySql" "$MYSQL_CONFIG" 3 | } 4 | 5 | get_all_mysql_versions () { 6 | get_readable_all_choices "MySql" "$MYSQL_CONFIG" 7 | } 8 | 9 | set_mysql_version () { 10 | local new=$1 11 | set_readable_choice "MySql" "$MYSQL_CONFIG" "$new" 12 | } 13 | -------------------------------------------------------------------------------- /src/commands/config/apache.sh: -------------------------------------------------------------------------------- 1 | get_current_apache_version () { 2 | get_readable_current_choice "Apache" "$APACHE_CONFIG" 3 | } 4 | 5 | get_all_apache_versions () { 6 | get_readable_all_choices "Apache" "$APACHE_CONFIG" 7 | } 8 | 9 | set_apache_version () { 10 | local new=$1 11 | set_readable_choice "Apache" "$APACHE_CONFIG" "$new" 12 | } 13 | -------------------------------------------------------------------------------- /bin/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT="devilbox-cli.sh" 4 | SRC_PATH="./src/" 5 | 6 | command -v shellcheck >/dev/null 2>&1 || { echo >&2 "Shellcheck is required but it's not installed. Aborting."; exit 1; } 7 | 8 | cd "$SRC_PATH" && shellcheck --shell=bash -x "$SCRIPT" 9 | 10 | if [ "$?" -eq 0 ]; then 11 | echo "Valid." 12 | exit 0 13 | else 14 | echo "Invalid." 15 | exit 1 16 | fi 17 | -------------------------------------------------------------------------------- /src/utils/codes.sh: -------------------------------------------------------------------------------- 1 | ## Basic wrappers around exit codes 2 | 3 | OK_CODE=0 4 | KO_CODE=1 5 | 6 | was_success() { 7 | local exit_code=$? 8 | [ "$exit_code" -eq "$OK_CODE" ] 9 | } 10 | 11 | was_error() { 12 | local exit_code=$? 13 | [ "$exit_code" -eq "$KO_CODE" ] 14 | } 15 | 16 | die () { 17 | local exit_code=$1 18 | if [ ! -z "$exit_code" ]; then 19 | exit "$exit_code" 20 | else 21 | exit "$?" 22 | fi 23 | } 24 | -------------------------------------------------------------------------------- /src/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION="0.4.1" 4 | DATE="2020-12-06" 5 | NAME="devilbox-cli" 6 | DESCRIPTION="A simple and conveniant command line to manage devilbox from anywhere" 7 | LINK="https://github.com/louisgab/devilbox-cli" 8 | 9 | ENV_FILE=".env" 10 | 11 | PHP_CONFIG="PHP_SERVER=" 12 | APACHE_CONFIG="HTTPD_SERVER=apache-" 13 | MYSQL_CONFIG="MYSQL_SERVER=mysql-" 14 | DOCROOT_CONFIG="HTTPD_DOCROOT_DIR=" 15 | WWWPATH_CONFIG="HOST_PATH_HTTPD_DATADIR=" 16 | -------------------------------------------------------------------------------- /src/commands/open.sh: -------------------------------------------------------------------------------- 1 | open_http_intranet () { 2 | xdg-open "http://localhost/" 2> /dev/null >/dev/null 3 | } 4 | 5 | open_https_intranet () { 6 | xdg-open "https://localhost/" 2> /dev/null >/dev/null 7 | } 8 | 9 | open_command () { 10 | if ! is_running; then 11 | error "Devilbox containers are not running" 12 | return "$KO_CODE" 13 | fi 14 | if [[ $# -eq 0 ]] ; then 15 | open_https_intranet 16 | else 17 | for arg in "$@"; do 18 | case $arg in 19 | -h|--http) open_http_intranet; shift;; 20 | esac 21 | done 22 | fi 23 | } 24 | -------------------------------------------------------------------------------- /src/utils/prompt.sh: -------------------------------------------------------------------------------- 1 | ## Functions used for user interaction 2 | 3 | has_confirmed() { 4 | local response=$1 5 | case "$response" in 6 | [yY][eE][sS]|[yY]) return "$OK_CODE";; 7 | *) return "$KO_CODE";; 8 | esac 9 | } 10 | 11 | ask() { 12 | local question=$1 13 | local response 14 | read -r -p "$(question "${question} [y/N] ")" response 15 | printf '%s' "$response" 16 | return "$OK_CODE" 17 | } 18 | 19 | confirm() { 20 | local question=$1 21 | if has_confirmed "$(ask "$question")"; then 22 | return "$OK_CODE" 23 | else 24 | return "$KO_CODE" 25 | fi 26 | } 27 | -------------------------------------------------------------------------------- /src/commands/run.sh: -------------------------------------------------------------------------------- 1 | get_default_containers() { 2 | if [ -n "$DEVILBOX_CONTAINERS" ]; then 3 | printf %s "${DEVILBOX_CONTAINERS}" 4 | else 5 | printf %s "httpd php mysql" 6 | fi 7 | } 8 | 9 | run_containers () { 10 | docker-compose up $(get_default_containers) 11 | } 12 | 13 | run_containers_silent () { 14 | docker-compose up -d $(get_default_containers) 15 | } 16 | 17 | run_command () { 18 | if is_running; then 19 | error "Devilbox containers are already running" 20 | return "$KO_CODE" 21 | fi 22 | if [[ $# -eq 0 ]] ; then 23 | run_containers 24 | else 25 | for arg in "$@"; do 26 | case $arg in 27 | -s|--silent) run_containers_silent; shift;; 28 | esac 29 | done 30 | fi 31 | } 32 | -------------------------------------------------------------------------------- /src/utils/messages.sh: -------------------------------------------------------------------------------- 1 | ## Functions used for fancy output 2 | 3 | COLOR_DEFAULT=$(tput sgr0) 4 | COLOR_RED=$(tput setaf 1) 5 | COLOR_GREEN=$(tput setaf 2) 6 | COLOR_YELLOW=$(tput setaf 3) 7 | COLOR_BLUE=$(tput setaf 4) 8 | # COLOR_PURPLE=$(tput setaf 5) 9 | # COLOR_CYAN=$(tput setaf 6) 10 | COLOR_LIGHT_GRAY=$(tput setaf 7) 11 | COLOR_DARK_GRAY=$(tput setaf 0) 12 | 13 | error() { 14 | local message=$1 15 | printf "%s %s\n" "${COLOR_RED}[✘]" "${COLOR_DEFAULT}$message" >&2 16 | die "$KO_CODE" 17 | } 18 | 19 | success() { 20 | local message=$1 21 | printf "%s %s\n" "${COLOR_GREEN}[✔]" "${COLOR_DEFAULT}$message" 22 | } 23 | 24 | info() { 25 | local message=$1 26 | printf "%s %s\n" "${COLOR_YELLOW}[!]" "${COLOR_DEFAULT}$message" 27 | } 28 | 29 | question() { 30 | local message=$1 31 | printf "%s %s\n" "${COLOR_BLUE}[?]" "${COLOR_DEFAULT}$message" 32 | } 33 | -------------------------------------------------------------------------------- /src/devilbox-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################## 4 | # For test purposes only # 5 | ########################## 6 | 7 | source config.sh 8 | 9 | source utils/codes.sh 10 | source utils/messages.sh 11 | source utils/prompt.sh 12 | 13 | source commands/lib/choices.sh 14 | source commands/lib/config.sh 15 | source commands/lib/docker.sh 16 | 17 | source commands/config/apache.sh 18 | source commands/config/php.sh 19 | source commands/config/mysql.sh 20 | source commands/config/docroot.sh 21 | source commands/config/projects.sh 22 | 23 | source commands/check.sh 24 | source commands/config.sh 25 | source commands/enter.sh 26 | source commands/exec.sh 27 | source commands/help.sh 28 | source commands/mysql.sh 29 | source commands/open.sh 30 | source commands/restart.sh 31 | source commands/run.sh 32 | source commands/stop.sh 33 | source commands/update.sh 34 | source commands/version.sh 35 | 36 | source main.sh 37 | -------------------------------------------------------------------------------- /src/commands/config.sh: -------------------------------------------------------------------------------- 1 | config_command () { 2 | for arg in "$@"; do 3 | case $arg in 4 | -a=\*|--apache=\*) get_all_apache_versions; shift;; 5 | -a=*|--apache=*) set_apache_version "${arg#*=}"; shift;; 6 | -a|--apache) get_current_apache_version; shift;; 7 | -p=\*|--php=\*) get_all_php_versions; shift;; 8 | -p=*|--php=*) set_php_version "${arg#*=}"; shift;; 9 | -p|--php) get_current_php_version; shift;; 10 | -m=\*|--mysql=\*) get_all_mysql_versions; shift;; 11 | -m=*|--mysql=*) set_mysql_version "${arg#*=}"; shift;; 12 | -m|--mysql) get_current_mysql_version; shift;; 13 | -r=*|--root=*) set_document_root "${arg#*=}"; shift;; 14 | -r|--root) get_current_document_root; shift;; 15 | -w=*|--www=*) set_projects_path "${arg#*=}"; shift;; 16 | -w|--www) get_current_projects_path; shift;; 17 | esac 18 | done 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "devilbox-cli", 3 | "version": "0.4.1", 4 | "description": "A simple and conveniant command line to manage devilbox from anywhere", 5 | "author": "Louis Gabriel ", 6 | "license": "MIT", 7 | "bugs": { 8 | "url": "https://github.com/louisgab/devilbox-cli/issues" 9 | }, 10 | "homepage": "https://github.com/louisgab/devilbox-cli", 11 | "bin": { 12 | "devilbox": "./dist/devilbox-cli.sh" 13 | }, 14 | "scripts": { 15 | "clean": "./bin/clean.sh", 16 | "lint": "./bin/lint.sh", 17 | "build": "./bin/build.sh", 18 | "prepare": "npm run clean && npm run lint && npm run build" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/louisgab/devilbox-cli.git" 23 | }, 24 | "keywords": [ 25 | "devilbox", 26 | "docker", 27 | "lamp", 28 | "bash", 29 | "cli" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Louis-Gabriel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main.sh: -------------------------------------------------------------------------------- 1 | safe_cd() { 2 | local path=$1 3 | local error_msg=$2 4 | if [[ ! -d "$path" ]]; then 5 | error "$error_msg" 6 | fi 7 | cd "$path" >/dev/null || error "$error_msg" 8 | } 9 | 10 | get_devilbox_path() { 11 | if [ -n "$DEVILBOX_PATH" ]; then 12 | printf %s "${DEVILBOX_PATH}" 13 | else 14 | printf %s "$HOME/.devilbox" 15 | fi 16 | } 17 | 18 | main () { 19 | safe_cd "$(get_devilbox_path)" "Devilbox not found, please make sure it is installed in your home directory or use DEVILBOX_PATH in your profile." 20 | if [[ $# -eq 0 ]] ; then 21 | version_command 22 | help_command 23 | else 24 | case $1 in 25 | check) shift; check_command;; 26 | c|config) shift; config_command "$@";; 27 | e|enter) shift; enter_command;; 28 | x|exec) shift; exec_command "$@";; 29 | h|help|-h|--help) shift; help_command;; 30 | mysql) shift; mysql_command "$@";; 31 | o|open) shift; open_command "$@";; 32 | restart) shift; restart_command "$@";; 33 | r|run) shift; run_command "$@";; 34 | s|stop) shift; stop_command;; 35 | u|update) shift; update_command;; 36 | v|version|-v|--version) shift; version_command;; 37 | *) error "Unknown command $arg, see -h for help.";; 38 | esac 39 | fi 40 | } 41 | 42 | main "$@" 43 | -------------------------------------------------------------------------------- /src/commands/lib/config.sh: -------------------------------------------------------------------------------- 1 | ## Functions used to manipulate a config value in .env file 2 | 3 | get_config () { 4 | local config=$1 5 | local current 6 | current=$(grep -Eo "^$config+[[:alnum:][:punct:]]*" "$ENV_FILE" | sed "s/.*$config//g") 7 | if was_success && [ ! -z "$current" ] ;then 8 | printf "%s" "$current" 9 | return "$OK_CODE" 10 | else 11 | return "$KO_CODE" 12 | fi 13 | } 14 | 15 | set_config () { 16 | local config=$1 17 | local new=$2 18 | local current 19 | current="$(get_config "$config")" 20 | if was_error; then 21 | return "$KO_CODE" 22 | fi 23 | sed -i -e "s/\(^#*$config${current//\//\\\/}\).*/$config${new//\//\\\/}/" "$ENV_FILE" 24 | if was_error; then 25 | return "$KO_CODE" 26 | fi 27 | current="$(get_config "$config")" 28 | if was_success && [[ "$current" = "$new" ]]; then 29 | return "$OK_CODE" 30 | else 31 | return "$KO_CODE" 32 | fi 33 | } 34 | 35 | ### READABLE VERSIONS 36 | 37 | get_readable_current_config () { 38 | local type=$1 39 | local config=$2 40 | local current 41 | current=$(get_config "$config") 42 | if was_success; then 43 | info "$type current config is $current" 44 | return "$OK_CODE" 45 | else 46 | error "Couldnt retrieve current config of $type" 47 | return "$KO_CODE" 48 | fi 49 | } 50 | 51 | set_readable_config () { 52 | local type=$1 53 | local config=$2 54 | local new=$3 55 | if set_config "$config" "$new"; then 56 | success "$type config updated to $new" 57 | return "$OK_CODE" 58 | else 59 | error "$type config change failed" 60 | return "$KO_CODE" 61 | fi 62 | } 63 | -------------------------------------------------------------------------------- /src/commands/update.sh: -------------------------------------------------------------------------------- 1 | get_recent_devilbox_versions () { 2 | local versions 3 | versions=$(git fetch --tags && git describe --abbrev=0 --tags $(git rev-list --tags --max-count=10)) 4 | if was_success; then 5 | info "Devilbox available versions:" 6 | printf "%s\n" "$versions" 7 | return "$OK_CODE" 8 | else 9 | error "Couldnt retrive available versions of devilbox" 10 | return "$KO_CODE" 11 | fi 12 | } 13 | 14 | latest_version () { 15 | local latest 16 | latest=$(git fetch --tags && git describe --abbrev=0 --tags $(git rev-list --tags --max-count=1)) 17 | if was_success; then 18 | info "Devilbox latest version is $latest" 19 | return "$OK_CODE" 20 | else 21 | error "Couldnt retrieve latest version of devilbox" 22 | return "$KO_CODE" 23 | fi 24 | } 25 | 26 | set_devilbox_version () { 27 | local version=$1 28 | confirm "Did you backup your databases before?" 29 | if was_success ;then 30 | git fetch --tags && git checkout $version 31 | if was_success; then 32 | success "Devilbox updated to $version, please restart" 33 | return "$OK_CODE" 34 | else 35 | error "Couldnt update devilbox" 36 | return "$KO_CODE" 37 | fi 38 | fi 39 | } 40 | 41 | update_command () { 42 | if is_running; then 43 | error "Devilbox containers are running, please use devilbox stop" 44 | return "$KO_CODE" 45 | fi 46 | for arg in "$@"; do 47 | case $arg in 48 | -v=\*|--version=\*) get_recent_devilbox_versions; shift;; 49 | -v=*|--version=*) set_devilbox_version "${arg#*=}"; shift;; 50 | -v=latest|--version=latest) set_devilbox_version "$(latest_version)"; shift;; 51 | -d|--docker) sh update-docker.sh; shift;; 52 | esac 53 | done 54 | } 55 | -------------------------------------------------------------------------------- /bin/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT="devilbox-cli.sh" 4 | DIST_PATH="./dist/" 5 | SRC_PATH="./src/" 6 | BUILD="${DIST_PATH}${SCRIPT}" 7 | 8 | 9 | # Add files in same order as src 10 | cat "$SRC_PATH"config.sh > "$BUILD" && echo "" >> "$BUILD" 11 | 12 | cat "$SRC_PATH"utils/codes.sh >> "$BUILD" && echo "" >> "$BUILD" 13 | cat "$SRC_PATH"utils/messages.sh >> "$BUILD" && echo "" >> "$BUILD" 14 | cat "$SRC_PATH"utils/prompt.sh >> "$BUILD" && echo "" >> "$BUILD" 15 | 16 | cat "$SRC_PATH"commands/lib/choices.sh >> "$BUILD" && echo "" >> "$BUILD" 17 | cat "$SRC_PATH"commands/lib/config.sh >> "$BUILD" && echo "" >> "$BUILD" 18 | cat "$SRC_PATH"commands/lib/docker.sh >> "$BUILD" && echo "" >> "$BUILD" 19 | 20 | cat "$SRC_PATH"commands/config/apache.sh >> "$BUILD" && echo "" >> "$BUILD" 21 | cat "$SRC_PATH"commands/config/php.sh >> "$BUILD" && echo "" >> "$BUILD" 22 | cat "$SRC_PATH"commands/config/mysql.sh >> "$BUILD" && echo "" >> "$BUILD" 23 | cat "$SRC_PATH"commands/config/docroot.sh >> "$BUILD" && echo "" >> "$BUILD" 24 | cat "$SRC_PATH"commands/config/projects.sh >> "$BUILD" && echo "" >> "$BUILD" 25 | 26 | cat "$SRC_PATH"commands/check.sh >> "$BUILD" && echo "" >> "$BUILD" 27 | cat "$SRC_PATH"commands/config.sh >> "$BUILD" && echo "" >> "$BUILD" 28 | cat "$SRC_PATH"commands/enter.sh >> "$BUILD" && echo "" >> "$BUILD" 29 | cat "$SRC_PATH"commands/exec.sh >> "$BUILD" && echo "" >> "$BUILD" 30 | cat "$SRC_PATH"commands/help.sh >> "$BUILD" && echo "" >> "$BUILD" 31 | cat "$SRC_PATH"commands/mysql.sh >> "$BUILD" && echo "" >> "$BUILD" 32 | cat "$SRC_PATH"commands/open.sh >> "$BUILD" && echo "" >> "$BUILD" 33 | cat "$SRC_PATH"commands/restart.sh >> "$BUILD" && echo "" >> "$BUILD" 34 | cat "$SRC_PATH"commands/run.sh >> "$BUILD" && echo "" >> "$BUILD" 35 | cat "$SRC_PATH"commands/stop.sh >> "$BUILD" && echo "" >> "$BUILD" 36 | cat "$SRC_PATH"commands/update.sh >> "$BUILD" && echo "" >> "$BUILD" 37 | cat "$SRC_PATH"commands/version.sh >> "$BUILD" && echo "" >> "$BUILD" 38 | 39 | cat "$SRC_PATH"main.sh >> "$BUILD" && echo "" >> "$BUILD" 40 | 41 | chmod +x "$BUILD" 42 | 43 | echo "Done." 44 | exit 0 45 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [0.4.1] - 2020-12-06 8 | ### Fixed 9 | - add missing help an documentation for new commands 10 | 11 | ## [0.4.0] - 2020-12-06 12 | ### Added 13 | - "check" command that shortcuts to check-config.sh devilbox file 14 | - "exec" command that enables command execution without entering the container 15 | - "mysql" command that opens the mysql cli, and possibility to exec query directly 16 | 17 | ## [0.3.2] - 2020-05-23 18 | ### Changed 19 | - default command shows version and help (@llaville) 20 | 21 | ## [0.3.1] - 2020-05-23 22 | ### Fixed 23 | - help command documentation, thanks to @llaville 24 | - build process, thanks to @llaville 25 | 26 | ## [0.3.0] - 2020-01-17 27 | ### Added 28 | - Restart command, thanks to @thomasplevy 29 | ### Changed 30 | - Possibility to add services to docker-compose, thanks to @thomasplevy 31 | 32 | ## [0.2.3] - 2019-04-01 33 | ### Fixed 34 | - Failed build, clean it up 35 | 36 | ## [0.2.2] - 2019-04-01 37 | ### Fixed 38 | - Bin path in package.json 39 | 40 | ## [0.2.1] - 2019-04-01 41 | ### Changed 42 | - Updated README.md 43 | 44 | ## [0.2.0] - 2019-03-08 45 | ### Added 46 | - Published as npm package for easier install/update 47 | ### Removed 48 | - Database path from devilbox versions prior to 1.0.0 49 | 50 | ## [0.1.0] - 2019-03-08 51 | ### Added 52 | - Build script that concatenates all source files in one dist file 53 | - New commands: enter, config, open, run, stop, update 54 | - Possibility to change default devilbox path with DEVILBOX_PATH in profile source 55 | ### Changed 56 | - Restructure the whole project with separate files for clarity 57 | - Lot of good practices 58 | - Fancy messages output 59 | - Readme adapted to new usage 60 | 61 | ## [0.0.3] - 2019-03-08 62 | ### Changed 63 | - Sed regex compatibility with characters 64 | 65 | ## [0.0.2] - 2019-03-08 66 | ### Changed 67 | - Use short function declarations 68 | - Format helpers with colors 69 | 70 | ## [0.0.1] - 2019-03-08 71 | ### Added 72 | - First version: commands for php/mysql/apache and docroot/projects/databases paths. 73 | -------------------------------------------------------------------------------- /src/commands/help.sh: -------------------------------------------------------------------------------- 1 | add_usage_command () { 2 | local command=$1 3 | local description=$2 4 | printf '%-30s\t %s\n' "$command" "${COLOR_DARK_GRAY}$description${COLOR_DEFAULT}" 5 | } 6 | 7 | add_usage_arg () { 8 | local arg=$1 9 | local description=$2 10 | printf '%-30s\t %s\n' " ${COLOR_LIGHT_GRAY}$arg" "${COLOR_DARK_GRAY}$description${COLOR_DEFAULT}" 11 | } 12 | 13 | help_command () { 14 | printf "\n" 15 | printf "%s\n" "Usage: $0 [--args]... " 16 | printf "\n" 17 | add_usage_command "check" "Check your .env file for potential errors" 18 | add_usage_command "c,config" "Show / Edit the current config" 19 | add_usage_arg "-a=,--apache=" "Set a specific apache version" 20 | add_usage_arg "-a=*,--apache=*" "Get all available apache versions" 21 | add_usage_arg "-p=*,--php=*" "Get all available php versions" 22 | add_usage_arg "-m=*,--mysql=*" "Get all available mysql versions" 23 | add_usage_arg "-p,--php" "Get current php version" 24 | add_usage_arg "-a,--apache" "Get current apache version" 25 | add_usage_arg "-m,--mysql" "Get current mysql version" 26 | add_usage_arg "-r=,--root=" "Set the document root" 27 | add_usage_arg "-r,--root" "Get the current document root" 28 | add_usage_arg "-w=,--www=" "Set the path to projects" 29 | add_usage_arg "-w,--www" "Get the current path to projects" 30 | add_usage_arg "-d=,--database=" "Set the path to databases" 31 | add_usage_arg "-d,--database" "Get the current path to databases" 32 | add_usage_arg "-p=,--php=" "Set a specific php version" 33 | add_usage_arg "-m=,--mysql=" "Set a specific mysql version" 34 | add_usage_command "e,enter" "Enter the devilbox shell" 35 | add_usage_command "x, exec ''" "Execute a command inside the container without entering it" 36 | add_usage_command "h, help" "List all available commands" 37 | add_usage_command "mysql ['']" "Launch a preconnected mysql shell, with optional query" 38 | add_usage_command "o,open" "Open the devilbox intranet" 39 | add_usage_arg "-h,--http" "Use non-https url" 40 | add_usage_command "restart" "Restart the devilbox docker containers" 41 | add_usage_arg "-s,--silent" "Hide errors and run in background" 42 | add_usage_command "r,run" "Run the devilbox docker containers" 43 | add_usage_arg "-s,--silent" "Hide errors and run in background" 44 | add_usage_command "s,stop" "Stop devilbox and docker containers" 45 | add_usage_command "u,update" "Update devilbox and docker containers" 46 | add_usage_command "v, version" "Show version information" 47 | printf "\n" 48 | } 49 | -------------------------------------------------------------------------------- /src/commands/lib/choices.sh: -------------------------------------------------------------------------------- 1 | ## Functions used to manipulate choices values in .env file 2 | 3 | is_choice_existing () { 4 | local config=$1 5 | local choice=$2 6 | local search 7 | search=$(grep -Eo "^#*$config$choice" "$ENV_FILE") 8 | if was_success && [ ! -z "$search" ] ;then 9 | return "$OK_CODE" 10 | else 11 | return "$KO_CODE" 12 | fi 13 | } 14 | 15 | get_current_choice () { 16 | local config=$1 17 | local current 18 | current=$(grep -Eo "^$config+[.[:digit:]]*" "$ENV_FILE" | sed "s/.*$config//g") 19 | if was_success && [ ! -z "$current" ] ;then 20 | printf "%s" "$current" 21 | return "$OK_CODE" 22 | else 23 | return "$KO_CODE" 24 | fi 25 | } 26 | 27 | is_choice_available() { 28 | local config=$1 29 | local choice=$2 30 | local current 31 | current=$(get_current_choice "$config") 32 | if was_success && [ "$choice" != "$current" ] ;then 33 | return "$OK_CODE" 34 | else 35 | return "$KO_CODE" 36 | fi 37 | } 38 | 39 | get_all_choices () { 40 | local config=$1 41 | local all 42 | all=$(grep -Eo "^#*$config+[.[:digit:]]*" "$ENV_FILE" | sed "s/.*$config//g") 43 | if was_success && [ ! -z "$all" ] ;then 44 | printf "%s\n" "$all" 45 | return "$OK_CODE" 46 | else 47 | return "$KO_CODE" 48 | fi 49 | } 50 | 51 | set_choice () { 52 | local config=$1 53 | local new=$2 54 | local current 55 | if ! is_choice_existing "$config" "$new" || ! is_choice_available "$config" "$new"; then 56 | return "$KO_CODE" 57 | fi 58 | current=$(get_current_choice "$config") 59 | if was_error; then 60 | return "$KO_CODE" 61 | fi 62 | sed -i -e "s/\(^#*$config$current\).*/#$config$current/" "$ENV_FILE" 63 | if was_error; then 64 | return "$KO_CODE" 65 | fi 66 | sed -i -e "s/\(^#*$config$new\).*/$config$new/" "$ENV_FILE" 67 | if was_error; then 68 | return "$KO_CODE" 69 | fi 70 | current=$(get_current_choice "$config") 71 | if was_success && [[ "$current" = "$new" ]]; then 72 | return "$OK_CODE" 73 | else 74 | return "$KO_CODE" 75 | fi 76 | } 77 | 78 | ### READABLE VERSIONS 79 | 80 | is_readable_choice_existing () { 81 | local type=$1 82 | local config=$2 83 | local choice=$3 84 | if is_choice_existing "$config" "$choice"; then 85 | success "$type version $choice is existing" 86 | return "$OK_CODE" 87 | else 88 | error "$type version $choice does not exists" 89 | return "$K0_CODE" 90 | fi 91 | } 92 | 93 | get_readable_current_choice () { 94 | local type=$1 95 | local config=$2 96 | local current 97 | current=$(get_current_choice "$config") 98 | if was_success; then 99 | info "$type current version is $current" 100 | return "$OK_CODE" 101 | else 102 | error "Couldnt retrieve current version of $type" 103 | return "$KO_CODE" 104 | fi 105 | } 106 | 107 | is_readable_choice_available() { 108 | local config=$1 109 | local choice=$2 110 | local isavailable 111 | if is_choice_available "$config" "$choice"; then 112 | success "$type version $choice is available" 113 | return "$OK_CODE" 114 | else 115 | error "$type is already using version $choice" 116 | return "$K0_CODE" 117 | fi 118 | } 119 | 120 | get_readable_all_choices () { 121 | local type=$1 122 | local config=$2 123 | local all 124 | all=$(get_all_choices "$config") 125 | if was_success; then 126 | info "$type available versions:" 127 | printf "%s\n" "$all" 128 | return "$OK_CODE" 129 | else 130 | error "Couldnt retrive available versions of $type" 131 | return "$KO_CODE" 132 | fi 133 | } 134 | 135 | set_readable_choice () { 136 | local type=$1 137 | local config=$2 138 | local new=$3 139 | if ! is_readable_choice_existing "$type" "$config" "$new"; then 140 | return "$KO_CODE" 141 | fi 142 | if ! is_readable_choice_available "$config" "$new"; then 143 | return "$KO_CODE" 144 | fi 145 | if set_choice "$config" "$new"; then 146 | success "$type version updated to $new" 147 | return "$OK_CODE" 148 | else 149 | error "$type version change failed" 150 | return "$KO_CODE" 151 | fi 152 | } 153 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Devilbox CLI 2 | 3 | ![npm](https://img.shields.io/npm/v/devilbox-cli.svg?style=flat-square) 4 | ![npm](https://img.shields.io/npm/dt/devilbox-cli.svg?style=flat-square) 5 | ![GitHub file size in bytes](https://img.shields.io/github/size/louisgab/devilbox-cli/dist/devilbox-cli.sh.svg?style=flat-square) 6 | [![GitHub license](https://img.shields.io/github/license/louisgab/devilbox-cli.svg?style=flat-square)](https://github.com/louisgab/devilbox-cli/blob/master/LICENSE) 7 | 8 | > A simple and conveniant command line to manage devilbox from anywhere 9 | 10 | --- 11 | 12 | ## Getting Started 13 | 14 | ### Requirements 15 | 16 | You need [Devilbox](https://github.com/cytopia/devilbox#quick-start) to be installed somewhere on your computer. 17 | 18 | By default, the script will use the path `$HOME/.devilbox`. 19 | If you have cloned devilbox somewhere else, add the following to your profile and change `##PATH_TO_DEVILBOX##` accordingly: 20 | 21 | ```sh 22 | export DEVILBOX_PATH="$HOME/##PATH_TO_DEVILBOX##" 23 | ``` 24 | 25 | Then reload your terminal or run `source ~/.zshrc` if you use zsh. 26 | 27 | ### Install 28 | 29 | As simple as : 30 | 31 | ``` 32 | npm install -g devilbox-cli 33 | ``` 34 | 35 | If installed successfully, you should see something like this when you run `devilbox -v`: 36 | 37 | ```sh 38 | devilbox-cli v0.4.1 (2020-12-06) 39 | A simple and conveniant cli to manage devilbox from anywhere 40 | https://github.com/louisgab/devilbox-cli 41 | ``` 42 | 43 | #### Alternatives 44 | If you don't have npm or don't wan to use it, you can also download the script directly: 45 | ```sh 46 | curl -O https://raw.githubusercontent.com/louisgab/devilbox-cli/master/dist/devilbox-cli.sh 47 | chmod +x devilbox-cli.sh 48 | sudo mv devilbox-cli.sh /usr/local/bin/devilbox 49 | ``` 50 | This way you can call the script from anywhere, but you won't be able to download updates (that was the point of using npm). 51 | For a manual update, delete it first 52 | ```sh 53 | sudo rm /usr/local/bin/devilbox 54 | ``` 55 | Then re-download the script. 56 | 57 | ### Usage 58 | 59 | devilbox-cli provides all basic command to manage your installation: 60 | 61 | ```sh 62 | devilbox check # Check your .env 63 | devilbox config # Get and set variables on your .env 64 | devilbox enter # Enter the php container with shell.sh script 65 | devilbox exec # Execute a command in the container 66 | devilbox mysql # Execute a command in the container 67 | devilbox open # Open the devilbox intranet 68 | devilbox run # Start the containers 69 | devilbox stop # Stop all containers 70 | devilbox restart # Stop and rerun all containers 71 | devilbox update # Update to latest devilbox version 72 | ``` 73 | 74 | To see containers current versions defined in devilbox `.env` file, use the `config` command: 75 | 76 | ```sh 77 | devilbox config --apache --php --mysql 78 | # [!] Apache current version is 2.4 79 | # [!] PHP current version is 7.2 80 | # [!] MySql current version is 5.6 81 | ``` 82 | 83 | It can also list available versions of any container: 84 | 85 | ```sh 86 | devilbox config --mysql=* 87 | # [!] MySql available versions: 88 | # 5.5 89 | # 5.6 90 | # 5.7 91 | # 8.0 92 | ``` 93 | 94 | And of course, it can change any version: 95 | 96 | ```sh 97 | devilbox config --php=8.0 98 | # [✔] PHP version updated to 8.0 99 | ``` 100 | 101 | You can also point devilbox to your projects folder: 102 | 103 | ```sh 104 | devilbox config --www=../Documents/Projects/www 105 | # [✔] Projects path config updated to ../Documents/Projects/wwww 106 | ``` 107 | 108 | And if you dont remember a command, `devilbox help` is your best friend :) 109 | 110 | ### Optional Configuration 111 | 112 | By default, the `run` command will start the default LAMP stack containers `php httpd mysql`. The command can be customized by configuring your desired services via the `$DEVILBOX_CONTAINERS` variable. For example, if you'd like to also run the NOSQL stack, you would define the following: 113 | 114 | ```sh 115 | export DEVILBOX_CONTAINERS="php httpd mysql redis memcd mongo" 116 | ``` 117 | 118 | Then reload your terminal or run `source ~/.zshrc` if you use zsh. 119 | 120 | ### Important notes 121 | 122 | The script was tested on zsh and bash on linux. Use at your own risk on other platforms. 123 | 124 | ## Contributing 125 | 126 | Highly welcomed! The script only implements the basics I needed for myself (LAMP). It may be useful for others to add missing commands, test it on macOS and Windows, and test in on other shells. 127 | 128 | ## License 129 | 130 | [MIT License](LICENSE.md) 131 | -------------------------------------------------------------------------------- /dist/devilbox-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION="0.4.1" 4 | DATE="2020-12-06" 5 | NAME="devilbox-cli" 6 | DESCRIPTION="A simple and conveniant command line to manage devilbox from anywhere" 7 | LINK="https://github.com/louisgab/devilbox-cli" 8 | 9 | ENV_FILE=".env" 10 | 11 | PHP_CONFIG="PHP_SERVER=" 12 | APACHE_CONFIG="HTTPD_SERVER=apache-" 13 | MYSQL_CONFIG="MYSQL_SERVER=mysql-" 14 | DOCROOT_CONFIG="HTTPD_DOCROOT_DIR=" 15 | WWWPATH_CONFIG="HOST_PATH_HTTPD_DATADIR=" 16 | 17 | ## Basic wrappers around exit codes 18 | 19 | OK_CODE=0 20 | KO_CODE=1 21 | 22 | was_success() { 23 | local exit_code=$? 24 | [ "$exit_code" -eq "$OK_CODE" ] 25 | } 26 | 27 | was_error() { 28 | local exit_code=$? 29 | [ "$exit_code" -eq "$KO_CODE" ] 30 | } 31 | 32 | die () { 33 | local exit_code=$1 34 | if [ ! -z "$exit_code" ]; then 35 | exit "$exit_code" 36 | else 37 | exit "$?" 38 | fi 39 | } 40 | 41 | ## Functions used for fancy output 42 | 43 | COLOR_DEFAULT=$(tput sgr0) 44 | COLOR_RED=$(tput setaf 1) 45 | COLOR_GREEN=$(tput setaf 2) 46 | COLOR_YELLOW=$(tput setaf 3) 47 | COLOR_BLUE=$(tput setaf 4) 48 | # COLOR_PURPLE=$(tput setaf 5) 49 | # COLOR_CYAN=$(tput setaf 6) 50 | COLOR_LIGHT_GRAY=$(tput setaf 7) 51 | COLOR_DARK_GRAY=$(tput setaf 0) 52 | 53 | error() { 54 | local message=$1 55 | printf "%s %s\n" "${COLOR_RED}[✘]" "${COLOR_DEFAULT}$message" >&2 56 | die "$KO_CODE" 57 | } 58 | 59 | success() { 60 | local message=$1 61 | printf "%s %s\n" "${COLOR_GREEN}[✔]" "${COLOR_DEFAULT}$message" 62 | } 63 | 64 | info() { 65 | local message=$1 66 | printf "%s %s\n" "${COLOR_YELLOW}[!]" "${COLOR_DEFAULT}$message" 67 | } 68 | 69 | question() { 70 | local message=$1 71 | printf "%s %s\n" "${COLOR_BLUE}[?]" "${COLOR_DEFAULT}$message" 72 | } 73 | 74 | ## Functions used for user interaction 75 | 76 | has_confirmed() { 77 | local response=$1 78 | case "$response" in 79 | [yY][eE][sS]|[yY]) return "$OK_CODE";; 80 | *) return "$KO_CODE";; 81 | esac 82 | } 83 | 84 | ask() { 85 | local question=$1 86 | local response 87 | read -r -p "$(question "${question} [y/N] ")" response 88 | printf '%s' "$response" 89 | return "$OK_CODE" 90 | } 91 | 92 | confirm() { 93 | local question=$1 94 | if has_confirmed "$(ask "$question")"; then 95 | return "$OK_CODE" 96 | else 97 | return "$KO_CODE" 98 | fi 99 | } 100 | 101 | ## Functions used to manipulate choices values in .env file 102 | 103 | is_choice_existing () { 104 | local config=$1 105 | local choice=$2 106 | local search 107 | search=$(grep -Eo "^#*$config$choice" "$ENV_FILE") 108 | if was_success && [ ! -z "$search" ] ;then 109 | return "$OK_CODE" 110 | else 111 | return "$KO_CODE" 112 | fi 113 | } 114 | 115 | get_current_choice () { 116 | local config=$1 117 | local current 118 | current=$(grep -Eo "^$config+[.[:digit:]]*" "$ENV_FILE" | sed "s/.*$config//g") 119 | if was_success && [ ! -z "$current" ] ;then 120 | printf "%s" "$current" 121 | return "$OK_CODE" 122 | else 123 | return "$KO_CODE" 124 | fi 125 | } 126 | 127 | is_choice_available() { 128 | local config=$1 129 | local choice=$2 130 | local current 131 | current=$(get_current_choice "$config") 132 | if was_success && [ "$choice" != "$current" ] ;then 133 | return "$OK_CODE" 134 | else 135 | return "$KO_CODE" 136 | fi 137 | } 138 | 139 | get_all_choices () { 140 | local config=$1 141 | local all 142 | all=$(grep -Eo "^#*$config+[.[:digit:]]*" "$ENV_FILE" | sed "s/.*$config//g") 143 | if was_success && [ ! -z "$all" ] ;then 144 | printf "%s\n" "$all" 145 | return "$OK_CODE" 146 | else 147 | return "$KO_CODE" 148 | fi 149 | } 150 | 151 | set_choice () { 152 | local config=$1 153 | local new=$2 154 | local current 155 | if ! is_choice_existing "$config" "$new" || ! is_choice_available "$config" "$new"; then 156 | return "$KO_CODE" 157 | fi 158 | current=$(get_current_choice "$config") 159 | if was_error; then 160 | return "$KO_CODE" 161 | fi 162 | sed -i -e "s/\(^#*$config$current\).*/#$config$current/" "$ENV_FILE" 163 | if was_error; then 164 | return "$KO_CODE" 165 | fi 166 | sed -i -e "s/\(^#*$config$new\).*/$config$new/" "$ENV_FILE" 167 | if was_error; then 168 | return "$KO_CODE" 169 | fi 170 | current=$(get_current_choice "$config") 171 | if was_success && [[ "$current" = "$new" ]]; then 172 | return "$OK_CODE" 173 | else 174 | return "$KO_CODE" 175 | fi 176 | } 177 | 178 | ### READABLE VERSIONS 179 | 180 | is_readable_choice_existing () { 181 | local type=$1 182 | local config=$2 183 | local choice=$3 184 | if is_choice_existing "$config" "$choice"; then 185 | success "$type version $choice is existing" 186 | return "$OK_CODE" 187 | else 188 | error "$type version $choice does not exists" 189 | return "$K0_CODE" 190 | fi 191 | } 192 | 193 | get_readable_current_choice () { 194 | local type=$1 195 | local config=$2 196 | local current 197 | current=$(get_current_choice "$config") 198 | if was_success; then 199 | info "$type current version is $current" 200 | return "$OK_CODE" 201 | else 202 | error "Couldnt retrieve current version of $type" 203 | return "$KO_CODE" 204 | fi 205 | } 206 | 207 | is_readable_choice_available() { 208 | local config=$1 209 | local choice=$2 210 | local isavailable 211 | if is_choice_available "$config" "$choice"; then 212 | success "$type version $choice is available" 213 | return "$OK_CODE" 214 | else 215 | error "$type is already using version $choice" 216 | return "$K0_CODE" 217 | fi 218 | } 219 | 220 | get_readable_all_choices () { 221 | local type=$1 222 | local config=$2 223 | local all 224 | all=$(get_all_choices "$config") 225 | if was_success; then 226 | info "$type available versions:" 227 | printf "%s\n" "$all" 228 | return "$OK_CODE" 229 | else 230 | error "Couldnt retrive available versions of $type" 231 | return "$KO_CODE" 232 | fi 233 | } 234 | 235 | set_readable_choice () { 236 | local type=$1 237 | local config=$2 238 | local new=$3 239 | if ! is_readable_choice_existing "$type" "$config" "$new"; then 240 | return "$KO_CODE" 241 | fi 242 | if ! is_readable_choice_available "$config" "$new"; then 243 | return "$KO_CODE" 244 | fi 245 | if set_choice "$config" "$new"; then 246 | success "$type version updated to $new" 247 | return "$OK_CODE" 248 | else 249 | error "$type version change failed" 250 | return "$KO_CODE" 251 | fi 252 | } 253 | 254 | ## Functions used to manipulate a config value in .env file 255 | 256 | get_config () { 257 | local config=$1 258 | local current 259 | current=$(grep -Eo "^$config+[[:alnum:][:punct:]]*" "$ENV_FILE" | sed "s/.*$config//g") 260 | if was_success && [ ! -z "$current" ] ;then 261 | printf "%s" "$current" 262 | return "$OK_CODE" 263 | else 264 | return "$KO_CODE" 265 | fi 266 | } 267 | 268 | set_config () { 269 | local config=$1 270 | local new=$2 271 | local current 272 | current="$(get_config "$config")" 273 | if was_error; then 274 | return "$KO_CODE" 275 | fi 276 | sed -i -e "s/\(^#*$config${current//\//\\\/}\).*/$config${new//\//\\\/}/" "$ENV_FILE" 277 | if was_error; then 278 | return "$KO_CODE" 279 | fi 280 | current="$(get_config "$config")" 281 | if was_success && [[ "$current" = "$new" ]]; then 282 | return "$OK_CODE" 283 | else 284 | return "$KO_CODE" 285 | fi 286 | } 287 | 288 | ### READABLE VERSIONS 289 | 290 | get_readable_current_config () { 291 | local type=$1 292 | local config=$2 293 | local current 294 | current=$(get_config "$config") 295 | if was_success; then 296 | info "$type current config is $current" 297 | return "$OK_CODE" 298 | else 299 | error "Couldnt retrieve current config of $type" 300 | return "$KO_CODE" 301 | fi 302 | } 303 | 304 | set_readable_config () { 305 | local type=$1 306 | local config=$2 307 | local new=$3 308 | if set_config "$config" "$new"; then 309 | success "$type config updated to $new" 310 | return "$OK_CODE" 311 | else 312 | error "$type config change failed" 313 | return "$KO_CODE" 314 | fi 315 | } 316 | 317 | is_running () { 318 | local all 319 | all=$(docker-compose ps 2> /dev/null | grep "devilbox" | awk '{print $3}' | grep "Up") 320 | if was_success; then 321 | return "$OK_CODE"; 322 | else 323 | return "$KO_CODE"; 324 | fi 325 | } 326 | 327 | get_current_apache_version () { 328 | get_readable_current_choice "Apache" "$APACHE_CONFIG" 329 | } 330 | 331 | get_all_apache_versions () { 332 | get_readable_all_choices "Apache" "$APACHE_CONFIG" 333 | } 334 | 335 | set_apache_version () { 336 | local new=$1 337 | set_readable_choice "Apache" "$APACHE_CONFIG" "$new" 338 | } 339 | 340 | get_current_php_version () { 341 | get_readable_current_choice "PHP" "$PHP_CONFIG" 342 | } 343 | 344 | get_all_php_versions () { 345 | get_readable_all_choices "PHP" "$PHP_CONFIG" 346 | } 347 | 348 | set_php_version () { 349 | local new=$1 350 | set_readable_choice "PHP" "$PHP_CONFIG" "$new" 351 | } 352 | 353 | get_current_mysql_version () { 354 | get_readable_current_choice "MySql" "$MYSQL_CONFIG" 355 | } 356 | 357 | get_all_mysql_versions () { 358 | get_readable_all_choices "MySql" "$MYSQL_CONFIG" 359 | } 360 | 361 | set_mysql_version () { 362 | local new=$1 363 | set_readable_choice "MySql" "$MYSQL_CONFIG" "$new" 364 | } 365 | 366 | get_current_document_root () { 367 | get_readable_current_config "Document root" "$DOCROOT_CONFIG" 368 | } 369 | 370 | set_document_root () { 371 | local new=$1 372 | set_readable_config "Document root" "$DOCROOT_CONFIG" "$new" 373 | } 374 | 375 | get_current_projects_path () { 376 | get_readable_current_config "Projects path" "$WWWPATH_CONFIG" 377 | } 378 | 379 | set_projects_path () { 380 | local new=$1 381 | set_readable_config "Projects path" "$WWWPATH_CONFIG" "$new" 382 | } 383 | 384 | check_command () { 385 | ./check-config.sh 386 | } 387 | 388 | config_command () { 389 | for arg in "$@"; do 390 | case $arg in 391 | -a=\*|--apache=\*) get_all_apache_versions; shift;; 392 | -a=*|--apache=*) set_apache_version "${arg#*=}"; shift;; 393 | -a|--apache) get_current_apache_version; shift;; 394 | -p=\*|--php=\*) get_all_php_versions; shift;; 395 | -p=*|--php=*) set_php_version "${arg#*=}"; shift;; 396 | -p|--php) get_current_php_version; shift;; 397 | -m=\*|--mysql=\*) get_all_mysql_versions; shift;; 398 | -m=*|--mysql=*) set_mysql_version "${arg#*=}"; shift;; 399 | -m|--mysql) get_current_mysql_version; shift;; 400 | -r=*|--root=*) set_document_root "${arg#*=}"; shift;; 401 | -r|--root) get_current_document_root; shift;; 402 | -w=*|--www=*) set_projects_path "${arg#*=}"; shift;; 403 | -w|--www) get_current_projects_path; shift;; 404 | esac 405 | done 406 | } 407 | 408 | enter_command () { 409 | if ! is_running; then 410 | error "Devilbox containers are not running" 411 | return "$KO_CODE" 412 | fi 413 | ./shell.sh 414 | } 415 | 416 | exec_command() { 417 | if ! is_running; then 418 | error "Devilbox containers are not running" 419 | return "$KO_CODE" 420 | fi 421 | 422 | docker-compose exec -u devilbox php bash -c "$@" 423 | } 424 | 425 | add_usage_command () { 426 | local command=$1 427 | local description=$2 428 | printf '%-30s\t %s\n' "$command" "${COLOR_DARK_GRAY}$description${COLOR_DEFAULT}" 429 | } 430 | 431 | add_usage_arg () { 432 | local arg=$1 433 | local description=$2 434 | printf '%-30s\t %s\n' " ${COLOR_LIGHT_GRAY}$arg" "${COLOR_DARK_GRAY}$description${COLOR_DEFAULT}" 435 | } 436 | 437 | help_command () { 438 | printf "\n" 439 | printf "%s\n" "Usage: $0 [--args]... " 440 | printf "\n" 441 | add_usage_command "check" "Check your .env file for potential errors" 442 | add_usage_command "c,config" "Show / Edit the current config" 443 | add_usage_arg "-a=,--apache=" "Set a specific apache version" 444 | add_usage_arg "-a=*,--apache=*" "Get all available apache versions" 445 | add_usage_arg "-p=*,--php=*" "Get all available php versions" 446 | add_usage_arg "-m=*,--mysql=*" "Get all available mysql versions" 447 | add_usage_arg "-p,--php" "Get current php version" 448 | add_usage_arg "-a,--apache" "Get current apache version" 449 | add_usage_arg "-m,--mysql" "Get current mysql version" 450 | add_usage_arg "-r=,--root=" "Set the document root" 451 | add_usage_arg "-r,--root" "Get the current document root" 452 | add_usage_arg "-w=,--www=" "Set the path to projects" 453 | add_usage_arg "-w,--www" "Get the current path to projects" 454 | add_usage_arg "-d=,--database=" "Set the path to databases" 455 | add_usage_arg "-d,--database" "Get the current path to databases" 456 | add_usage_arg "-p=,--php=" "Set a specific php version" 457 | add_usage_arg "-m=,--mysql=" "Set a specific mysql version" 458 | add_usage_command "e,enter" "Enter the devilbox shell" 459 | add_usage_command "x, exec ''" "Execute a command inside the container without entering it" 460 | add_usage_command "h, help" "List all available commands" 461 | add_usage_command "mysql ['']" "Launch a preconnected mysql shell, with optional query" 462 | add_usage_command "o,open" "Open the devilbox intranet" 463 | add_usage_arg "-h,--http" "Use non-https url" 464 | add_usage_command "restart" "Restart the devilbox docker containers" 465 | add_usage_arg "-s,--silent" "Hide errors and run in background" 466 | add_usage_command "r,run" "Run the devilbox docker containers" 467 | add_usage_arg "-s,--silent" "Hide errors and run in background" 468 | add_usage_command "s,stop" "Stop devilbox and docker containers" 469 | add_usage_command "u,update" "Update devilbox and docker containers" 470 | add_usage_command "v, version" "Show version information" 471 | printf "\n" 472 | } 473 | 474 | mysql_command() { 475 | if ! is_running; then 476 | error "Devilbox containers are not running" 477 | return "$KO_CODE" 478 | fi 479 | 480 | if [ -z "$1" ]; then 481 | exec_command 'mysql -hmysql -uroot' 482 | else 483 | exec_command "mysql -hmysql -uroot -e '$1'" 484 | fi 485 | } 486 | 487 | open_http_intranet () { 488 | xdg-open "http://localhost/" 2> /dev/null >/dev/null 489 | } 490 | 491 | open_https_intranet () { 492 | xdg-open "https://localhost/" 2> /dev/null >/dev/null 493 | } 494 | 495 | open_command () { 496 | if ! is_running; then 497 | error "Devilbox containers are not running" 498 | return "$KO_CODE" 499 | fi 500 | if [[ $# -eq 0 ]] ; then 501 | open_https_intranet 502 | else 503 | for arg in "$@"; do 504 | case $arg in 505 | -h|--http) open_http_intranet; shift;; 506 | esac 507 | done 508 | fi 509 | } 510 | 511 | restart_command() { 512 | stop_command 513 | run_command "$@" 514 | } 515 | 516 | get_default_containers() { 517 | if [ -n "$DEVILBOX_CONTAINERS" ]; then 518 | printf %s "${DEVILBOX_CONTAINERS}" 519 | else 520 | printf %s "httpd php mysql" 521 | fi 522 | } 523 | 524 | run_containers () { 525 | docker-compose up $(get_default_containers) 526 | } 527 | 528 | run_containers_silent () { 529 | docker-compose up -d $(get_default_containers) 530 | } 531 | 532 | run_command () { 533 | if is_running; then 534 | error "Devilbox containers are already running" 535 | return "$KO_CODE" 536 | fi 537 | if [[ $# -eq 0 ]] ; then 538 | run_containers 539 | else 540 | for arg in "$@"; do 541 | case $arg in 542 | -s|--silent) run_containers_silent; shift;; 543 | esac 544 | done 545 | fi 546 | } 547 | 548 | stop_command () { 549 | if ! is_running; then 550 | error "Devilbox containers are not running" 551 | return "$KO_CODE" 552 | fi 553 | docker-compose stop 554 | docker-compose rm -f 555 | } 556 | 557 | get_recent_devilbox_versions () { 558 | local versions 559 | versions=$(git fetch --tags && git describe --abbrev=0 --tags $(git rev-list --tags --max-count=10)) 560 | if was_success; then 561 | info "Devilbox available versions:" 562 | printf "%s\n" "$versions" 563 | return "$OK_CODE" 564 | else 565 | error "Couldnt retrive available versions of devilbox" 566 | return "$KO_CODE" 567 | fi 568 | } 569 | 570 | latest_version () { 571 | local latest 572 | latest=$(git fetch --tags && git describe --abbrev=0 --tags $(git rev-list --tags --max-count=1)) 573 | if was_success; then 574 | info "Devilbox latest version is $latest" 575 | return "$OK_CODE" 576 | else 577 | error "Couldnt retrieve latest version of devilbox" 578 | return "$KO_CODE" 579 | fi 580 | } 581 | 582 | set_devilbox_version () { 583 | local version=$1 584 | confirm "Did you backup your databases before?" 585 | if was_success ;then 586 | git fetch --tags && git checkout $version 587 | if was_success; then 588 | success "Devilbox updated to $version, please restart" 589 | return "$OK_CODE" 590 | else 591 | error "Couldnt update devilbox" 592 | return "$KO_CODE" 593 | fi 594 | fi 595 | } 596 | 597 | update_command () { 598 | if is_running; then 599 | error "Devilbox containers are running, please use devilbox stop" 600 | return "$KO_CODE" 601 | fi 602 | for arg in "$@"; do 603 | case $arg in 604 | -v=\*|--version=\*) get_recent_devilbox_versions; shift;; 605 | -v=*|--version=*) set_devilbox_version "${arg#*=}"; shift;; 606 | -v=latest|--version=latest) set_devilbox_version "$(latest_version)"; shift;; 607 | -d|--docker) sh update-docker.sh; shift;; 608 | esac 609 | done 610 | } 611 | 612 | version_command() { 613 | printf "\n" 614 | printf "%s\n" "$NAME v$VERSION ($DATE)" 615 | printf "%s\n" "${COLOR_LIGHT_GRAY}$DESCRIPTION${COLOR_DEFAULT}" 616 | printf "%s\n" "${COLOR_LIGHT_GRAY}$LINK${COLOR_DEFAULT}" 617 | printf "\n" 618 | } 619 | 620 | safe_cd() { 621 | local path=$1 622 | local error_msg=$2 623 | if [[ ! -d "$path" ]]; then 624 | error "$error_msg" 625 | fi 626 | cd "$path" >/dev/null || error "$error_msg" 627 | } 628 | 629 | get_devilbox_path() { 630 | if [ -n "$DEVILBOX_PATH" ]; then 631 | printf %s "${DEVILBOX_PATH}" 632 | else 633 | printf %s "$HOME/.devilbox" 634 | fi 635 | } 636 | 637 | main () { 638 | safe_cd "$(get_devilbox_path)" "Devilbox not found, please make sure it is installed in your home directory or use DEVILBOX_PATH in your profile." 639 | if [[ $# -eq 0 ]] ; then 640 | version_command 641 | help_command 642 | else 643 | case $1 in 644 | check) shift; check_command;; 645 | c|config) shift; config_command "$@";; 646 | e|enter) shift; enter_command;; 647 | x|exec) shift; exec_command "$@";; 648 | h|help|-h|--help) shift; help_command;; 649 | mysql) shift; mysql_command "$@";; 650 | o|open) shift; open_command "$@";; 651 | restart) shift; restart_command "$@";; 652 | r|run) shift; run_command "$@";; 653 | s|stop) shift; stop_command;; 654 | u|update) shift; update_command;; 655 | v|version|-v|--version) shift; version_command;; 656 | *) error "Unknown command $arg, see -h for help.";; 657 | esac 658 | fi 659 | } 660 | 661 | main "$@" 662 | 663 | --------------------------------------------------------------------------------