#!/usr/bin/env bash ############################################################################## # DESCRIPTION: Library of methods specifically for the project. # Include using source .whales/.lib.sh ############################################################################## source scripts/.lib.globals.sh; source scripts/.lib.utils.sh; ############################################################################## # GLOBAL VARIABLES ############################################################################## env_from ".env" import REQUIREMENTS_GO as PATH_REQ_GO; env_from ".env" import REQUIREMENTS_PY as PATH_REQ_PY; env_from ".env" import NAME_OF_APP; env_from ".env" import TEST_TIMEOUT; export CONFIGENV="data/.env"; export PATH_PROJECT_PY="code/python"; export PATH_PROJECT_GO="code/golang"; export PATH_GO_ASSETS_GRAMMAR="assets/grammars"; export PATH_GO_INTERNAL_GRAMMAR="internal/tokenisers/grammars"; export PYTHON_APP_PREFIX=\ '''#!/usr/bin/env python3 # -*- coding: utf-8 -*-''' export USE_VENV=false; export UNITTEST_SCHEMA_PY="test_*.py"; ############################################################################## # AUXILIARY METHODS: Zip ############################################################################## function create_zip_archive() { zip -r $@; } ############################################################################## # AUXILIARY METHODS: Go ############################################################################## function call_go() { go $@; } function install_requirements_go() { local path="$1"; local cwd="$PWD"; local has_problems=false; local problem_packages=(); pushd $PATH_PROJECT_GO >> $VERBOSE; # go mod tidy; # <- use to detect unused packages in project remove_file "go.sum"; _log_info "Add go requirements"; dos_to_unix "$cwd/$path"; local line; while read line; do line="$( _trim_trailing_comments "$line" )"; [ "$line" == "" ] && continue; _log_info "Run \033[92;1mGO GET\033[0m to install \033[93;1m$line\033[0m."; ( call_go get "$line" 2> $VERBOSE ) && continue; has_problems=true; problem_packages+=( "$line" ); done <<< "$( cat "$cwd/$path" )"; popd >> $VERBOSE ( $has_problems ) && _log_fail "Something went wrong whilst using \033[92;1mGO\033[0m to install: {\033[93;1m${problem_packages[*]}\033[0m}."; } function compile_go() { local force="$1"; local path="$2"; local cwd="$PWD"; _log_info "Compile \033[1mmain.go\033[0m with \033[1mgolang\033[0m"; remove_file "dist/$NAME_OF_APP"; pushd "$path" >> $VERBOSE; call_go build -o "$cwd/dist/$NAME_OF_APP" "main.go"; popd >> $VERBOSE; ! [ -f "dist/$NAME_OF_APP" ] && return 1; return 0; } ############################################################################## # AUXILIARY METHODS: Python ############################################################################## function use_python_venv_true() { USE_VENV=true; } function use_python_venv_false() { USE_VENV=false; } function create_python_venv() { ! ( $USE_VENV ) && return; _log_info "Create VENV"; ! [ -d build ] && mkdir build; pushd build >> $VERBOSE; call_python -m venv env; popd >> $VERBOSE; } function activate_python_venv() { ! ( $USE_VENV ) && return; if ( is_linux ); then source build/env/bin/activate; else source build/env/Scripts/activate; fi } function deactivate_python_venv() { ! ( $USE_VENV ) && return; if ( is_linux ); then source build/env/bin/deactivate; else source build/env/Scripts/deactivate; fi } function call_python() { if ( is_linux ); then python3 $@; else py -3 $@; fi } function call_v_python() { activate_python_venv && call_python $@; } function call_utest() { call_python -m unittest discover $@; } function call_v_utest() { activate_python_venv && call_utest $@; } function call_pipinstall() { # Do not use --user flag with venv DISPLAY= && call_python -m pip install $@; } function install_requirements_python() { local path="$1"; local has_problems=false; local problem_packages=(); dos_to_unix "$path"; local line; while read line; do line="$( _trim_trailing_comments "$line" )"; [ "$line" == "" ] && continue; _log_info "Run \033[92;1mPIP\033[0m to install \033[93;1m$line\033[0m."; ( call_pipinstall "$line" >> $VERBOSE ) && continue; has_problems=true; problem_packages+=( "$line" ); done <<< "$( cat "$path" )"; ( $has_problems ) && _log_fail "Something went wrong whilst using \033[92;1mPIP\033[0m to install: {\033[93;1m${problem_packages[*]}\033[0m}."; } function install_requirements_v_python() { activate_python_venv && install_requirements_python $@; } ############################################################################## # AUXILIARY METHODS: CLEANING ############################################################################## function garbage_collection_misc() { clean_all_folders_of_pattern ".DS_Store"; } function garbage_collection_python() { clean_folder_contents "$PATH_PROJECT_PY/build"; local path; for path in "$PATH_PROJECT_PY"; do pushd "$path" >> $VERBOSE; # clean_all_files_of_pattern "*\.pyo"; clean_all_folders_of_pattern "__pycache__"; popd >> $VERBOSE; done } function garbage_collection_go { _log_info "(There are no go files to clean.)"; } function garbage_collection_dist() { remove_file "dist/$NAME_OF_APP"; } ############################################################################## # MAIN METHODS: PROCESSES ############################################################################## function run_setup() { _log_info "RUN SETUP"; local current_dir="$PWD"; pushd $PATH_PROJECT_PY >> $VERBOSE; create_python_venv; _log_info "Check and install missing requirements"; install_requirements_v_python "$current_dir/$PATH_REQ_PY"; popd >> $VERBOSE; } function run_setup_go() { install_requirements_go "$PATH_REQ_GO"; } function run_create_artefact() { local current_dir="$PWD"; local success; ## create temp artefacts: local _temp="$( create_temporary_dir "dist" )"; mkdir "$_temp/src" cp -r "$PATH_PROJECT_PY/src/." "$_temp/src"; copy_file file="VERSION" from="dist" to="${_temp}/src/setup"; mv "${_temp}/src/__main__.py" "$_temp"; ## zip source files to single file and make executable: pushd "$_temp" >> $VERBOSE; ( create_zip_archive -o "$current_dir/dist/app.zip" * -x '*__pycache__/*' -x '*.DS_Store' ); success=$? popd >> $VERBOSE; if [ $success -eq 0 ]; then echo "$PYTHON_APP_PREFIX" | cat - dist/app.zip > dist/$NAME_OF_APP; chmod +x "dist/$NAME_OF_APP"; fi ## remove temp artefacts: remove_dir "$_temp"; remove_file "dist/app.zip"; ! [ $success -eq 0 ] && return 1; _log_info "Python artefact successfully created."; return 0; } function run_create_artefact_go() { local current_dir="$PWD"; local success; ## create temp artefacts: local _temp="$( create_temporary_dir "dist" )"; cp -r "$PATH_PROJECT_GO/." "$_temp"; copy_file file="VERSION" from="dist" to="${_temp}/assets"; ( compile_go true "$_temp" ); success=$?; ## remove temp artefacts: remove_dir "$_temp"; ! [ $success -eq 0 ] && return 1; return 0; } function run_main() { pushd $PATH_PROJECT_PY >> $VERBOSE; call_v_python src/main.py $@; popd >> $VERBOSE; } function run_main_go() { compile_go false "$PATH_PROJECT_GO"; ./dist/$NAME_OF_APP $@; } function run_test_unit() { local asverbose=$1; local verboseoption="-v"; local success=0; ! ( $asverbose ) && verboseoption=""; _log_info "RUN UNITTESTS"; pushd $PATH_PROJECT_PY >> $VERBOSE; ( call_v_utest \ $verboseoption \ --top-level-directory "test" \ --start-directory "test" \ --pattern "${UNITTEST_SCHEMA_PY}" 2>&1 \ ); success=$?; popd >> $VERBOSE; [ $success -eq 1 ] && _log_fail "Unit tests failed!"; _log_info "Unit tests successful!"; return 0; } function run_test_unit_go() { local asverbose="$1"; local verboseoption="-v"; local success; _log_info "RUN UNITTESTS"; ! ( $asverbose ) && verboseoption="" pushd $PATH_PROJECT_GO >> $VERBOSE; ( call_go test $verboseoption -timeout $TEST_TIMEOUT -count 1 -run "^Test[A-Z].*" "$NAME_OF_APP" "./..." ); success=$?; popd >> $VERBOSE [ $success -eq 1 ] && _log_fail "Unit tests failed!"; _log_info "Unit tests successful!"; return 0; } function run_clean_artefacts() { _log_info "CLEAN ARTEFACTS"; garbage_collection_misc; garbage_collection_python; garbage_collection_go; garbage_collection_dist; }