commit df1999fd4f21320ac304922baf9feafe5dd815af Author: Manuel Manhart Date: Mon Mar 25 10:20:47 2024 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7773828 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dist/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..121b2f8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Manuel Manhart + +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. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d21702 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Bash Script Compiler 0.1 + +A helper / compiler to maintain bigger bash script projects where you develop in multiple files, one file per function, so everything should be better maintainable. + +You can create new stub projects with this so you do not need to take care about the boilerplate code, just implement your neccessary functions, help, code completion. + +On executing this script merges everything together into a file in a dist folder in the project. + +## Getting started + +Execute + +```bash +bash-script-compiler new +``` + +and answer the questions to create a new bash script project. + +## Main idea + +TODO explain the directory structure +src/ +src/functions +scr/help +src/intro.sh +src/main.sh +src/xyz-completion +LICENSE +README.md +VERSION + +## Split + +1. Put the main part of your project into the [./src/main.sh](./src/main.sh) file. It will be the entrypoint for your script; +2. Move all your function declarations into the modules under the `./lib` directory +([./lib/print_bar.sh](./lib/print_bar.sh) and [./lib/print_foo.sh](./lib/print_foo.sh) in this example); +3. Copy the content of the [Makefile](Makefile) to the root of your project; + +## Build + +1. Replace the value of the variable `TARGET_FILE` in the `Makefile` +(wich is `target.sh` by default) with the name that your prefer; +2. Run `make` from your project directory; +3. The content of your `main.sh` file will be wrapped into the `main` function and will be invoked at the end of the +script, so all of the functions defined in modules under the `lib` directory will be available in it; + +## Changelog + +__0.1__ + +* Created the initial script +* Split it up so it will compile itself (this therefor serves as example project) + +## Sources + +* [Initial project we forked](https://github.com/zinovyev/bash-project) +* [How to use return values in functions](https://www.linuxjournal.com/content/return-values-bash-functions) diff --git a/bash-script-compiler b/bash-script-compiler new file mode 100755 index 0000000..dfd8bf3 --- /dev/null +++ b/bash-script-compiler @@ -0,0 +1,175 @@ +#!/usr/bin/env bash + +# +# This script is generated. Please do checkout the source code for editing! +# +# This is a tool for creating big bash script projects in smaller files / chunks. +# Source Code: https://code.manhart.space/mmit/bash-script-compiler.git +# Maintainer: Manuel Manhart +# Company: Manuel Manhart IT e.U. +# License: MIT +# Created by bash-script-compiler version BASH_SCRIPT_COMPILER_VERSION + +# set default constants / variables +SCRIPT_VERSION="0.1" + +CONFIG_FILE_NAME=BASH_SCRIPT_COMPILER_SCRIPT_NAME.config +CONFIG_PATH=${HOME}/.config/mmit +CONFIG_FILE=${CONFIG_PATH}/${CONFIG_FILE_NAME} +ACTION=${1:-"help"} + +TARGET_DIR_NAME="dist" +SRC_DIR_NAME="src" +MAIN_FUNC_FILE_NAME="main.sh" +INTRO_FILE_NAME="intro.sh" +PARSE_ARGS_PREFIX="parseArgs_" + +# TODO (minor) we do not want to print every command which is executed, only our specific "echo"s +# TODO (medium) implement support for PRJ_HELP (for loop can only be in one line it seems) + +function main() { + local action=${1:-"help"} + local parseArgsFunc="${PARSE_ARGS_PREFIX}${action}" + local isParseArgsDefined=$(type -t $parseArgsFunc) + if [ "function" == "$isParseArgsDefined" ]; then + "$parseArgsFunc" "${@:2}" + fi + "$action" "${@:2}" +} + +compile_addFunctions() { + PRJ_FUNC=$(ls -d ./functions/*) + for filename in ${PRJ_FUNC[*]}; do + cat ${filename} >> ${TARGET_FILE} + echo "" >> ${TARGET_FILE} + done +} + +compile_copyCompletionFile() { + cp *-completion ../${TARGET_DIR_NAME} +} + +compile_defineMainFunction() { + touch ${TARGET_FILE} + if [ ! -f "${INTRO_FILE_NAME}" ]; then + echo "WARN: Could not find intro file '${INTRO_FILE_NAME}' in ${PRJ_DIR}" + else + cat "${INTRO_FILE_NAME}" > ${TARGET_FILE} + echo "" >> ${TARGET_FILE} + fi + if [ ! -f "${MAIN_FUNC_FILE_NAME}" ]; then + echo "ERROR: Could not find main function file '${MAIN_FUNC_FILE_NAME}' in ${PRJ_DIR}" + help + exit + else + echo -e "function main() {" >> ${TARGET_FILE} + cat "${MAIN_FUNC_FILE_NAME}" | sed -e 's/^/ /g' >> ${TARGET_FILE} + echo -e "\n}\n" >> ${TARGET_FILE} + fi +} + +compile_invokeMainFunction() { + echo "main \"\$@\"" >> ${TARGET_FILE} +} + +compile_setTargetFile() { + local bashScriptName=$(basename "$(pwd)") + if [ ! -d "${TARGET_DIR_NAME}" ]; then + echo "Creating output dir '${TARGET_DIR_NAME}'" + mkdir -p ${TARGET_DIR_NAME} + fi + TARGET_FILE=../${TARGET_DIR_NAME}/$bashScriptName + cd $SRC_DIR_NAME +} + +compile() { + pushd $PRJ_DIR >/dev/null 2>&1 + compile_setTargetFile + compile_defineMainFunction + compile_addFunctions + compile_invokeMainFunction + compile_copyCompletionFile + echo "Compiled successfully" + popd +} + +help() { + local progName=$(echo "$0" | rev | cut -d'/' -f1 | rev) + + cat <<-END +$progName is a tool for creating big bash script projects in smaller files / chunks. + +Usage: + $progName [options] + +The options are: + need a param (you can combine like ubd) + config init ... for creating a config file (if none exists yet - automatically checked) + config print ... for printing the config file content + + compile PRJ_PATH ... compiles the bash project in the given path (./ compiles itself) + new ... initializes a new bash project + + help ... show this page + +Version: $SCRIPT_VERSION + END + + exit +} + +new_InitProject() { + echo "Not yet implemented" + # TODO implement copying from ./init to project name +} + +new_ReadProjectData() { + local year=$(date +'%Y') + local author=$USER + echo "Creating a new bash project" + echo "Project name:" + echo "Author name ($author):" + echo "Year ($year):" + echo "Is it MIT License (Y/n)?" +# echo "Create sample data" # not sure if we should really ask that + # TODO read the data into global variables +} + +new() { + new_ReadProjectData + new_InitProject + replaceFileNames + replaceVariablesInFiles + echo "Project created successfully" +} + +parseArgs_compile() { + if [ -z $1 ]; then + echo "Please give a directory to the bash script to compile" + help + fi + if [ ! -d $1 ]; then + echo "$1 is not a directory" + help + else + PRJ_DIR=$1 + fi +} + +parseArgs() { + if [ -z $1 ]; then + help + fi +} + +replaceFileNames() { + echo "Not yet implemented" + # TODO implement replacing the file names beginning with BASH_SCRIPT_COMPILER_SCRIPT_NAME +} + +replaceVariablesInFiles() { + echo "Not yet implemented" + # TODO implement replacing the file content variables BASH_SCRIPT_COMPILER_* +} + +main "$@" diff --git a/init/.gitignore b/init/.gitignore new file mode 100644 index 0000000..7773828 --- /dev/null +++ b/init/.gitignore @@ -0,0 +1 @@ +dist/ \ No newline at end of file diff --git a/init/LICENSE b/init/LICENSE new file mode 100644 index 0000000..efc183f --- /dev/null +++ b/init/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) BASH_SCRIPT_COMPILER_YEAR BASH_SCRIPT_COMPILER_AUTHOR + +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. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/init/README.md b/init/README.md new file mode 100644 index 0000000..e03ff63 --- /dev/null +++ b/init/README.md @@ -0,0 +1,15 @@ +# gt bash script 0.1 + +A helper for git functions I really miss, like merging the lastest develop / main branch into my current branch, showing what I (or someone else) has checked in over the time, etc. + +## Changelog + +__0.1__ + +* Created the initial bash script +* Added config functions (for future use) +* Added commands pull, tag, mine, pullAndMerge + +## Sources + +- \ No newline at end of file diff --git a/init/VERSION b/init/VERSION new file mode 100644 index 0000000..ceab6e1 --- /dev/null +++ b/init/VERSION @@ -0,0 +1 @@ +0.1 \ No newline at end of file diff --git a/init/src/BASH_SCRIPT_COMPILER_SCRIPT_NAME-completion b/init/src/BASH_SCRIPT_COMPILER_SCRIPT_NAME-completion new file mode 100644 index 0000000..cf73596 --- /dev/null +++ b/init/src/BASH_SCRIPT_COMPILER_SCRIPT_NAME-completion @@ -0,0 +1,54 @@ +_BASH_SCRIPT_COMPILER_SCRIPT_NAME-completion() +{ + local cur prev opts tag help + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + prevPrev="${COMP_WORDS[COMP_CWORD-2]}" + opts="mind pullAndMerge help config" + config="print set init" + + # TODO check if this is still the most efficient way to list help options + HELP_PATH=${BASH_SOURCE%/*}/gt-help + help=${opts} + #help=`ls $HELP_PATH` + + if [[ ${cur} == "help" ]] ; then + createFromString "${help}" + return 0 + elif [[ $COMP_CWORD -gt 1 ]]; then + if [ "$prev" == "tag" ]; then + # no suggestions for tags + return 0 + elif [ "$prev" == "config" ]; then + createFromString "$config" + elif [ "$prevPrev" == "config" ]; then + # no suggestions after config xyz + return 0 + elif [ "$prev" == "--path" ] || [ "$prev" == "-p" ]; then + createFromDirectory "$DOCKER_SERVICES_HOME" + elif [[ $COMP_CWORD -gt 1 ]] && [ "$prev" == "-p" ]; then + createFromDirectory "$DOCKER_SERVICES_HOME" +# elif [[ $COMP_CWORD -gt 1 ]] && [ "$prev" != "desc" ] && [ "$prev" != "year" ]; then +# createFromString "${twoPlus}" + else + createFromString "${opts}" + fi + return 0 + elif [[ $COMP_CWORD -eq 1 ]]; then + createFromString "${opts}" + return 0 + fi +} + +createFromString() { + COMPREPLY=( $(compgen -W "${1}" -- ${cur}) ) +} + +createFromDirectory() { + pushd $1 >/dev/null + COMPREPLY=( $(compgen -o plusdirs -- $cur) ) + popd >/dev/null +} + +complete -F _BASH_SCRIPT_COMPILER_SCRIPT_NAME-completion BASH_SCRIPT_COMPILER_SCRIPT_NAME diff --git a/init/src/functions/configInit.sh b/init/src/functions/configInit.sh new file mode 100644 index 0000000..c784541 --- /dev/null +++ b/init/src/functions/configInit.sh @@ -0,0 +1,28 @@ +configInit() { + if [ ! -f "${DEV_CONFIG_FILE}" ]; then + echo Could not find any config file, creating a file for you to fill in the values in ${DEV_CONFIG_FILE} + if [ ! -d "${DEV_CONFIG_FILE_PATH}" ]; then + echo "Config directory '${DEV_CONFIG_FILE_PATH}' does not exist yet, creating..." + mkdir -p ${DEV_CONFIG_FILE_PATH} + fi + if [ -f "/IMAGE_NAME" ]; then + # || [ `whoami` = 'dev' ]; then + MODE=devcontainer + GRADLE_DEFAULT=wrapper + else + MODE=host + GRADLE_DEFAULT=normal + fi + + cat <${DEV_CONFIG_FILE} +# this file was created by dev script by Manuel Manhart +# it is now in your hands and will not be changed by scripts anymore + +MODE=$MODE +LIFERAY_DOCKER=( + "TODO" # change this to the real path +) +END + + fi +} diff --git a/init/src/functions/configPrint.sh b/init/src/functions/configPrint.sh new file mode 100644 index 0000000..c4ba1ef --- /dev/null +++ b/init/src/functions/configPrint.sh @@ -0,0 +1,11 @@ +# reads the configuration file where the docker container names are saved +configPrint() { + echo "" + echo "Configuration file:" + cat ${DEV_CONFIG_FILE} | while read line + do + echo "$line" + done + echo "" + echo "Version: $SCRIPT_VERSION" +} diff --git a/init/src/functions/configRead.sh b/init/src/functions/configRead.sh new file mode 100644 index 0000000..d9a57b1 --- /dev/null +++ b/init/src/functions/configRead.sh @@ -0,0 +1,23 @@ +# reads the configuration file where the docker container names are saved +configRead() { + if [ -f "${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME}" ]; then + echo found config file in ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME} + source ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME} + + # Read common vars from the config file + # the incantation here ensures (by env) that only key=value pairs are present + # then declare-ing the result puts those vars in our environment +# declare $(env -i `cat ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME}` >/dev/null 2>&1) >/dev/null 2>&1 + +# IFS=$'\n' read -d '' -r -a LIFERAY_DOCKER < ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME} + fi + # as fallback search in script home directory + SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + if [ -f "${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME}" ]; then + echo found config file in ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME} + + declare $(env -i `cat ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME}` >/dev/null 2>&1) +# source ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME} +# IFS=$'\n' read -d '' -r -a LIFERAY_DOCKER < ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME} + fi +} diff --git a/init/src/functions/gitPull.sh b/init/src/functions/gitPull.sh new file mode 100644 index 0000000..9aa3301 --- /dev/null +++ b/init/src/functions/gitPull.sh @@ -0,0 +1,7 @@ +gitPull() { + if [ -f ".git" ]; then + git pull + else + echo "Seems not to be a git repo" + fi +} diff --git a/init/src/functions/gitTag.sh b/init/src/functions/gitTag.sh new file mode 100644 index 0000000..e6955d6 --- /dev/null +++ b/init/src/functions/gitTag.sh @@ -0,0 +1,17 @@ +gitTag() { + if [ -n "$2" ]; then + git pull >/dev/null + local message="" + if [ -n "$3" ]; then + message="-m $3" + fi + git tag -a $2 $message + git push --tags + else + git fetch origin >/dev/null + echo "Existing tags" + git tag + echo "" + echo "If you want to create a new tag, just provide a tag version" + fi +} diff --git a/init/src/functions/help.sh b/init/src/functions/help.sh new file mode 100644 index 0000000..e93c457 --- /dev/null +++ b/init/src/functions/help.sh @@ -0,0 +1,27 @@ +help() { + local progName=$(echo "$0" | rev | cut -d'/' -f1 | rev) + + cat <<-END +$progName is a tool for makeing git easier to use. + +Usage: + $progName [options] + +The options are: + need a param (you can combine like ubd) + config init ... for creating a config file (if none exists yet - automatically checked) + config print ... for printing the config file content + + mine [USER] ... fetches the log of either the given user or the one defined in git config + pullAndMerge BRANCH ... pulls the given branch and merges it into the current one (updating to latest develop / main) + pull ... for pulling from git (not working?) + tag NAME [MESSAGE] ... creates and pushes a new tag + branch NAME ... creates a new branch (TODO) + + help ... show this page + +Version: $SCRIPT_VERSION + END + + exit +} diff --git a/init/src/functions/mine.sh b/init/src/functions/mine.sh new file mode 100644 index 0000000..32e2a8a --- /dev/null +++ b/init/src/functions/mine.sh @@ -0,0 +1,13 @@ +mine() { + # fetch user from args + local gitUser=$GIT_USER + # Get the user defined in the local config + if [ -z "$gitUser" ]; then + gitUser=$(git config --get user.name) + echo "Fetching user from git config: $gitUser" + fi + echo "Git user: $gitUser" + + # get my commits + git log --author="$gitUser" +} diff --git a/init/src/functions/parseArgs.sh b/init/src/functions/parseArgs.sh new file mode 100644 index 0000000..0cd7012 --- /dev/null +++ b/init/src/functions/parseArgs.sh @@ -0,0 +1,36 @@ +parseArgs() { + if [ -z "$1" ]; then + help + fi + local setVariable=0 + local variableName="" + + #echo "parsing args" + for var in "$@" + do + #echo "DEBUG - arg[i]: '$var' - setVariable: $setVariable" + if [ "$setVariable" == 0 ]; then + variableName="" + fi + + if [ "$var" == "-h" ] || [ "$var" == "--help" ]; then + help + elif [ $setVariable -gt 0 ]; then + #echo "Setting variables..." + setVariable="$(($setVariable - 1))" + if [ "$variableName" == "tag" ]; then + TAG=$var + #echo "DEBUG - Setting tag to '$var'" + elif [ "$variableName" == "path" ]; then + SOURCE_PATH=$var + #echo "DEBUG - Setting source path to '$var'" + fi + elif [ "$var" == "-p" ] || [ "$var" == "--path" ]; then + setVariable=1 + variableName="path" + elif [ "$var" == "tag" ]; then + setVariable=1 + variableName="tag" + fi + done +} diff --git a/init/src/functions/parseArgs_mine.sh b/init/src/functions/parseArgs_mine.sh new file mode 100644 index 0000000..3aec7e8 --- /dev/null +++ b/init/src/functions/parseArgs_mine.sh @@ -0,0 +1,6 @@ +parseArgs_mine() { + echo "Fetching user: $1" + if [ -n "$1" ]; then + GIT_USER=$1 + fi +} diff --git a/init/src/functions/parseArgs_pullAndMerge.sh b/init/src/functions/parseArgs_pullAndMerge.sh new file mode 100644 index 0000000..a287317 --- /dev/null +++ b/init/src/functions/parseArgs_pullAndMerge.sh @@ -0,0 +1,9 @@ +parseArgs_pullAndMerge() { + echo "Pulling and merging branch $1 into current one" + if [ -z "$1" ]; then + echo "ERROR: Argument BRANCH is missing" + help pullAndMerge + else + GIT_BRANCH=$1 + fi +} diff --git a/init/src/functions/preset.sh b/init/src/functions/preset.sh new file mode 100644 index 0000000..87fcf14 --- /dev/null +++ b/init/src/functions/preset.sh @@ -0,0 +1,19 @@ +preset() { + # not yet working + # FIXME properties file not correctly read + # FIXME how do we set multiple values in a simple properties file + # TODO think about a better mechanism + utilIsReadPropertiesFile ./.dev-presets presetOptions presetValues + printf "presetOptions %s\n" "${presetOptions[@]}" + printf "presetValues %s\n" "${presetValues[@]}" + echo 'Please enter your choice: ' + local index=0 + for item in "${presetOptions[@]}" + do + echo ${index}. ${item} + index="$((index + 1))" + done + read n + echo "opt: $n" + echo "presetValue: ${presetValues[$n]}" +} diff --git a/init/src/functions/pullAndMerge.sh b/init/src/functions/pullAndMerge.sh new file mode 100644 index 0000000..566db86 --- /dev/null +++ b/init/src/functions/pullAndMerge.sh @@ -0,0 +1,12 @@ +pullAndMerge() { + # fetch user from args + local gitBranch=$GIT_BRANCH + local currentBranch=$(git rev-parse --abbrev-ref HEAD) + echo "current branch: $currentBranch" + + # Update the current branch to the latest of the given branch + git checkout $gitBranch + git pull + git checkout $currentBranch + echo DEBUG: git merge $gitBranch +} diff --git a/init/src/functions/runScript.sh b/init/src/functions/runScript.sh new file mode 100644 index 0000000..32dc975 --- /dev/null +++ b/init/src/functions/runScript.sh @@ -0,0 +1,34 @@ +runScript() { + # go to source path (if neccessary) + pushd $SOURCE_PATH >/dev/null 2>&1 + local runFunctions=${@// /|} + #echo "DEBUG - runFunctions: $runFunctions" + + # in the execution there are in- and dependent tasks, this file ensures that everything + # will be executed in a helpful way + + if [[ "$runFunctions" = *"help"* ]]; then + help + fi + # run config functions + if [[ "$runFunctions" = *"config"* ]]; then + if [[ "$runFunctions" = *"config init"* ]]; then + configInit + elif [[ "$runFunctions" = *"config print"* ]]; then + configPrint + exit + elif [[ "$runFunctions" = *"config set"* ]]; then + echo "Setting configurations is not yet supported" + fi + fi + + local parseArgsFunc="parseArgs_$ACTION" + local isParseArgsDefined=$(type -t $parseArgsFunc) + if [ "function" == "$isParseArgsDefined" ]; then + "$parseArgsFunc" "${@:2}" + fi + "$ACTION" "${@:2}" + + # return to initial path (if neccessary) + popd >/dev/null 2>&1 +} diff --git a/init/src/functions/utilIsExistingFile.sh b/init/src/functions/utilIsExistingFile.sh new file mode 100644 index 0000000..9c83a52 --- /dev/null +++ b/init/src/functions/utilIsExistingFile.sh @@ -0,0 +1,7 @@ +utilIsExistingFile() { + if ls $1 1> /dev/null 2>&1; then + return 0 + else + return 1 + fi +} diff --git a/init/src/functions/utilIsReadPropertiesFile.sh b/init/src/functions/utilIsReadPropertiesFile.sh new file mode 100644 index 0000000..539b564 --- /dev/null +++ b/init/src/functions/utilIsReadPropertiesFile.sh @@ -0,0 +1,21 @@ +utilIsReadPropertiesFile() { + local fileName=$1 + local keysName=$2 + local valuesName=$3 + local keys=() + local values=() + echo "reading properties file $1 into $2 and $3" + if [ -n "$fileName" ]; then + while IFS='=' read -r key value + do + key=$(echo $key | tr '.' '_') + keys+=("$key") + values+=("$value") +# eval ${key}=\${value} + done < "$fileName" + fi + echo "keys: $keys" + echo "values: $values" + eval $keysName="'$keys'" + eval $valuesName="'$values'" +} diff --git a/init/src/intro.sh b/init/src/intro.sh new file mode 100644 index 0000000..ac9cb92 --- /dev/null +++ b/init/src/intro.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# +# This script is generated. Please do checkout the source code for editing! +# +# REPLACE with a short description what the script does +# Source Code: REPLACE with your git URL +# Maintainer: Manuel Manhart +# Company: Manuel Manhart IT e.U. +# License: REPLACE with the license +# Created by bash-script-compiler version BASH_SCRIPT_COMPILER_VERSION + +# set default constants / variables +SCRIPT_VERSION="0.1" + +# define your global variables here +CONFIG_FILE_NAME=BASH_SCRIPT_COMPILER_SCRIPT_NAME.config +CONFIG_PATH=${HOME}/.config/mmit +CONFIG_FILE=${CONFIG_PATH}/${CONFIG_FILE_NAME} +ACTION=${1:-"help"} diff --git a/init/src/main.sh b/init/src/main.sh new file mode 100644 index 0000000..94b4a2a --- /dev/null +++ b/init/src/main.sh @@ -0,0 +1,12 @@ + +# main +# import colors +if [ -f ${BASH_SOURCE%/*}/define-colors ]; then +. ${BASH_SOURCE%/*}/define-colors "" +fi +# read configuration (if any) +configRead +# parse the arguments +parseArgs "$@" +# run the script +runScript "$@" diff --git a/src/bash-script-compiler-completion b/src/bash-script-compiler-completion new file mode 100644 index 0000000..1da22db --- /dev/null +++ b/src/bash-script-compiler-completion @@ -0,0 +1,47 @@ +_bash-script-compiler-completion() +{ + local cur prev opts tag help + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + prevPrev="${COMP_WORDS[COMP_CWORD-2]}" + opts="compile new help config" + config="print set init" + + # TODO check if this is still the most efficient way to list help options + HELP_PATH=${BASH_SOURCE%/*}/gt-help + help=${opts} + #help=`ls $HELP_PATH` + + if [[ ${cur} == "help" ]] ; then + createFromString "${help}" + return 0 + elif [[ $COMP_CWORD -gt 1 ]]; then + if [ "$prev" == "config" ]; then + createFromString "$config" + elif [ "$prevPrev" == "config" ]; then + # no suggestions after config xyz + return 0 + elif [ "$prev" == "compile" ] || [ "$prev" == "-c" ]; then + createFromDirectory "." + else + createFromString "${opts}" + fi + return 0 + elif [[ $COMP_CWORD -eq 1 ]]; then + createFromString "${opts}" + return 0 + fi +} + +createFromString() { + COMPREPLY=( $(compgen -W "${1}" -- ${cur}) ) +} + +createFromDirectory() { + pushd $1 >/dev/null + COMPREPLY=( $(compgen -o plusdirs -- $cur) ) + popd >/dev/null +} + +complete -F _bash-script-compiler-completion bash-script-compiler diff --git a/src/functions/compile.sh b/src/functions/compile.sh new file mode 100644 index 0000000..136ada1 --- /dev/null +++ b/src/functions/compile.sh @@ -0,0 +1,10 @@ +compile() { + pushd $PRJ_DIR >/dev/null 2>&1 + compile_setTargetFile + compile_defineMainFunction + compile_addFunctions + compile_invokeMainFunction + compile_copyCompletionFile + echo "Compiled successfully" + popd +} \ No newline at end of file diff --git a/src/functions/compile_addFunctions.sh b/src/functions/compile_addFunctions.sh new file mode 100644 index 0000000..3475069 --- /dev/null +++ b/src/functions/compile_addFunctions.sh @@ -0,0 +1,7 @@ +compile_addFunctions() { + PRJ_FUNC=$(ls -d ./functions/*) + for filename in ${PRJ_FUNC[*]}; do + cat ${filename} >> ${TARGET_FILE} + echo "" >> ${TARGET_FILE} + done +} diff --git a/src/functions/compile_copyCompletionFile.sh b/src/functions/compile_copyCompletionFile.sh new file mode 100644 index 0000000..eab625c --- /dev/null +++ b/src/functions/compile_copyCompletionFile.sh @@ -0,0 +1,3 @@ +compile_copyCompletionFile() { + cp *-completion ../${TARGET_DIR_NAME} +} diff --git a/src/functions/compile_defineMainFunction.sh b/src/functions/compile_defineMainFunction.sh new file mode 100644 index 0000000..5ea1a7e --- /dev/null +++ b/src/functions/compile_defineMainFunction.sh @@ -0,0 +1,18 @@ +compile_defineMainFunction() { + touch ${TARGET_FILE} + if [ ! -f "${INTRO_FILE_NAME}" ]; then + echo "WARN: Could not find intro file '${INTRO_FILE_NAME}' in ${PRJ_DIR}" + else + cat "${INTRO_FILE_NAME}" > ${TARGET_FILE} + echo "" >> ${TARGET_FILE} + fi + if [ ! -f "${MAIN_FUNC_FILE_NAME}" ]; then + echo "ERROR: Could not find main function file '${MAIN_FUNC_FILE_NAME}' in ${PRJ_DIR}" + help + exit + else + echo -e "function main() {" >> ${TARGET_FILE} + cat "${MAIN_FUNC_FILE_NAME}" | sed -e 's/^/ /g' >> ${TARGET_FILE} + echo -e "\n}\n" >> ${TARGET_FILE} + fi +} diff --git a/src/functions/compile_invokeMainFunction.sh b/src/functions/compile_invokeMainFunction.sh new file mode 100644 index 0000000..756e049 --- /dev/null +++ b/src/functions/compile_invokeMainFunction.sh @@ -0,0 +1,3 @@ +compile_invokeMainFunction() { + echo "main \"\$@\"" >> ${TARGET_FILE} +} diff --git a/src/functions/compile_setTargetFile.sh b/src/functions/compile_setTargetFile.sh new file mode 100644 index 0000000..820d2c6 --- /dev/null +++ b/src/functions/compile_setTargetFile.sh @@ -0,0 +1,9 @@ +compile_setTargetFile() { + local bashScriptName=$(basename "$(pwd)") + if [ ! -d "${TARGET_DIR_NAME}" ]; then + echo "Creating output dir '${TARGET_DIR_NAME}'" + mkdir -p ${TARGET_DIR_NAME} + fi + TARGET_FILE=../${TARGET_DIR_NAME}/$bashScriptName + cd $SRC_DIR_NAME +} diff --git a/src/functions/configInit.sh b/src/functions/configInit.sh new file mode 100644 index 0000000..c784541 --- /dev/null +++ b/src/functions/configInit.sh @@ -0,0 +1,28 @@ +configInit() { + if [ ! -f "${DEV_CONFIG_FILE}" ]; then + echo Could not find any config file, creating a file for you to fill in the values in ${DEV_CONFIG_FILE} + if [ ! -d "${DEV_CONFIG_FILE_PATH}" ]; then + echo "Config directory '${DEV_CONFIG_FILE_PATH}' does not exist yet, creating..." + mkdir -p ${DEV_CONFIG_FILE_PATH} + fi + if [ -f "/IMAGE_NAME" ]; then + # || [ `whoami` = 'dev' ]; then + MODE=devcontainer + GRADLE_DEFAULT=wrapper + else + MODE=host + GRADLE_DEFAULT=normal + fi + + cat <${DEV_CONFIG_FILE} +# this file was created by dev script by Manuel Manhart +# it is now in your hands and will not be changed by scripts anymore + +MODE=$MODE +LIFERAY_DOCKER=( + "TODO" # change this to the real path +) +END + + fi +} diff --git a/src/functions/configPrint.sh b/src/functions/configPrint.sh new file mode 100644 index 0000000..c4ba1ef --- /dev/null +++ b/src/functions/configPrint.sh @@ -0,0 +1,11 @@ +# reads the configuration file where the docker container names are saved +configPrint() { + echo "" + echo "Configuration file:" + cat ${DEV_CONFIG_FILE} | while read line + do + echo "$line" + done + echo "" + echo "Version: $SCRIPT_VERSION" +} diff --git a/src/functions/configRead.sh b/src/functions/configRead.sh new file mode 100644 index 0000000..d9a57b1 --- /dev/null +++ b/src/functions/configRead.sh @@ -0,0 +1,23 @@ +# reads the configuration file where the docker container names are saved +configRead() { + if [ -f "${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME}" ]; then + echo found config file in ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME} + source ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME} + + # Read common vars from the config file + # the incantation here ensures (by env) that only key=value pairs are present + # then declare-ing the result puts those vars in our environment +# declare $(env -i `cat ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME}` >/dev/null 2>&1) >/dev/null 2>&1 + +# IFS=$'\n' read -d '' -r -a LIFERAY_DOCKER < ${DEV_CONFIG_FILE_PATH}/${DEV_CONFIG_FILE_NAME} + fi + # as fallback search in script home directory + SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + if [ -f "${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME}" ]; then + echo found config file in ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME} + + declare $(env -i `cat ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME}` >/dev/null 2>&1) +# source ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME} +# IFS=$'\n' read -d '' -r -a LIFERAY_DOCKER < ${SCRIPTPATH}/${DEV_CONFIG_FILE_NAME} + fi +} diff --git a/src/functions/help.sh b/src/functions/help.sh new file mode 100644 index 0000000..83ed7c0 --- /dev/null +++ b/src/functions/help.sh @@ -0,0 +1,24 @@ +help() { + local progName=$(echo "$0" | rev | cut -d'/' -f1 | rev) + + cat <<-END +$progName is a tool for creating big bash script projects in smaller files / chunks. + +Usage: + $progName [options] + +The options are: + need a param (you can combine like ubd) + config init ... for creating a config file (if none exists yet - automatically checked) + config print ... for printing the config file content + + compile PRJ_PATH ... compiles the bash project in the given path (./ compiles itself) + new ... initializes a new bash project + + help ... show this page + +Version: $SCRIPT_VERSION + END + + exit +} diff --git a/src/functions/new.sh b/src/functions/new.sh new file mode 100644 index 0000000..7b4ec1b --- /dev/null +++ b/src/functions/new.sh @@ -0,0 +1,7 @@ +new() { + new_ReadProjectData + new_InitProject + replaceFileNames + replaceVariablesInFiles + echo "Project created successfully" +} diff --git a/src/functions/new_InitProject.sh b/src/functions/new_InitProject.sh new file mode 100644 index 0000000..797fa88 --- /dev/null +++ b/src/functions/new_InitProject.sh @@ -0,0 +1,4 @@ +new_InitProject() { + echo "Not yet implemented" + # TODO implement copying from ./init to project name +} diff --git a/src/functions/new_ReadProjectData.sh b/src/functions/new_ReadProjectData.sh new file mode 100644 index 0000000..dd3487d --- /dev/null +++ b/src/functions/new_ReadProjectData.sh @@ -0,0 +1,11 @@ +new_ReadProjectData() { + local year=$(date +'%Y') + local author=$USER + echo "Creating a new bash project" + echo "Project name:" + echo "Author name ($author):" + echo "Year ($year):" + echo "Is it MIT License (Y/n)?" +# echo "Create sample data" # not sure if we should really ask that + # TODO read the data into global variables +} diff --git a/src/functions/parseArgs.sh b/src/functions/parseArgs.sh new file mode 100644 index 0000000..eb5752f --- /dev/null +++ b/src/functions/parseArgs.sh @@ -0,0 +1,5 @@ +parseArgs() { + if [ -z $1 ]; then + help + fi +} diff --git a/src/functions/parseArgs_compile.sh b/src/functions/parseArgs_compile.sh new file mode 100644 index 0000000..9c816b0 --- /dev/null +++ b/src/functions/parseArgs_compile.sh @@ -0,0 +1,12 @@ +parseArgs_compile() { + if [ -z $1 ]; then + echo "Please give a directory to the bash script to compile" + help + fi + if [ ! -d $1 ]; then + echo "$1 is not a directory" + help + else + PRJ_DIR=$1 + fi +} diff --git a/src/functions/replaceFileNames.sh b/src/functions/replaceFileNames.sh new file mode 100644 index 0000000..f9a48f0 --- /dev/null +++ b/src/functions/replaceFileNames.sh @@ -0,0 +1,4 @@ +replaceFileNames() { + echo "Not yet implemented" + # TODO implement replacing the file names beginning with BASH_SCRIPT_COMPILER_SCRIPT_NAME +} diff --git a/src/functions/replaceVariablesInFiles.sh b/src/functions/replaceVariablesInFiles.sh new file mode 100644 index 0000000..86fb4b8 --- /dev/null +++ b/src/functions/replaceVariablesInFiles.sh @@ -0,0 +1,4 @@ +replaceVariablesInFiles() { + echo "Not yet implemented" + # TODO implement replacing the file content variables BASH_SCRIPT_COMPILER_* +} diff --git a/src/intro.sh b/src/intro.sh new file mode 100644 index 0000000..dcff5a7 --- /dev/null +++ b/src/intro.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# +# This script is generated. Please do checkout the source code for editing! +# +# This is a tool for creating big bash script projects in smaller files / chunks. +# Source Code: https://code.manhart.space/mmit/bash-script-compiler.git +# Maintainer: Manuel Manhart +# Company: Manuel Manhart IT e.U. +# License: MIT +# Created by bash-script-compiler version BASH_SCRIPT_COMPILER_VERSION + +# set default constants / variables +SCRIPT_VERSION="0.1" + +CONFIG_FILE_NAME=BASH_SCRIPT_COMPILER_SCRIPT_NAME.config +CONFIG_PATH=${HOME}/.config/mmit +CONFIG_FILE=${CONFIG_PATH}/${CONFIG_FILE_NAME} +ACTION=${1:-"help"} + +TARGET_DIR_NAME="dist" +SRC_DIR_NAME="src" +MAIN_FUNC_FILE_NAME="main.sh" +INTRO_FILE_NAME="intro.sh" +PARSE_ARGS_PREFIX="parseArgs_" + +# TODO (minor) we do not want to print every command which is executed, only our specific "echo"s +# TODO (medium) implement support for PRJ_HELP (for loop can only be in one line it seems) diff --git a/src/main.sh b/src/main.sh new file mode 100644 index 0000000..de9c5ab --- /dev/null +++ b/src/main.sh @@ -0,0 +1,7 @@ +local action=${1:-"help"} +local parseArgsFunc="${PARSE_ARGS_PREFIX}${action}" +local isParseArgsDefined=$(type -t $parseArgsFunc) +if [ "function" == "$isParseArgsDefined" ]; then + "$parseArgsFunc" "${@:2}" +fi +"$action" "${@:2}" \ No newline at end of file