diff options
author | cbdev <cb@cbcdn.com> | 2021-06-30 03:03:48 +0200 |
---|---|---|
committer | cbdev <cb@cbcdn.com> | 2021-06-30 03:03:48 +0200 |
commit | bc3d80e9e6c038c87a64432586670c663a23e53d (patch) | |
tree | 5a28b0004a7f3492455316f34bb2c783e670f944 /assets/ci.sh | |
parent | 8a0a413f1dd5593189dd6b651babcff9b2495451 (diff) | |
parent | f16f7db86662fcdbf45b6373257c90c824b0b4b0 (diff) | |
download | midimonster-bc3d80e9e6c038c87a64432586670c663a23e53d.tar.gz midimonster-bc3d80e9e6c038c87a64432586670c663a23e53d.tar.bz2 midimonster-bc3d80e9e6c038c87a64432586670c663a23e53d.zip |
Merge branch 'master' into debian/master
Diffstat (limited to 'assets/ci.sh')
-rwxr-xr-x | assets/ci.sh | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/assets/ci.sh b/assets/ci.sh new file mode 100755 index 0000000..94b8bed --- /dev/null +++ b/assets/ci.sh @@ -0,0 +1,313 @@ +#!/bin/bash +# shellcheck disable=SC2001,SC2181 + +################################################ SETUP ################################################ +dep_build_core=( + libasound2-dev + libevdev-dev + liblua5.3-dev + libola-dev + libjack-jackd2-dev + python3-dev + libssl-dev + build-essential + pkg-config + git +) + +dep_build_win=( + mingw-w64 +) + +dep_build_debian=( + git-buildpackage + debhelper +) + +exitcode="0" + +############################################## FUNCTIONS ############################################## + +ARGS(){ + for i in "$@"; do + case "$i" in + --target=*|-t=*) + TARGETS="${i#*=}" + ;; + --deploy) + deploy="1" + ;; + --deps) + install_deps="1" + ;; + -v|--verbose) + verbose="1" + ;; + -af|--allow-failure) + allow_failure="1" + ;; + -h|--help|*) + print_help + exit "0" + ;; + esac + shift + done + [[ -z $TARGETS ]] && print_help && printf "\nNo target specified!\n" && exit "1" # If no target(s) are specified exit. +} + +print_help() { + printf "Usage: %s [OPTIONS]\n\n" "$0" + printf -- "-t=<argument>, <argument>\t--target=<argument>, <argument>\n\n" + printf -- "--deploy\tPackage release/nightly versions to the ./deployment/\$target directory.\n" + printf -- "--deps\t\tCheck and install all dependencies needed for the specified target without the need to manualy run the dependency install targets/s.\n" + printf -- "-af, --allow-failure\tAlways exit with code 0.\n" + printf -- "-v, --verbose\tEnables detailed log output.\n\n" + printf "Valid test targets are: \t\"check-spelling\" - \"1\", \"check-codespelling\" - \"2\", \"analyze-complexity\" - \"3\", \"analyze-shellscript\" - \"4\", \"stats\" - \"5\".\n" + printf "Valid build targets are: \t\"build-linux\" - \"10\", \"build-windows\" - \"11\", \"build-debian\" - \"12\".\n" + printf "Valid dependency install targets are: \t\"deps-linux\", \"deps-windows\", \"deps-debian\", \"deps-osx\" \"deps-tests\", \"deps-all\".\n\n" +} + +install_dependencies(){ + start_apt update -y -qq > /dev/null || error_handler "There was an error doing apt update." + for dependency in "$@"; do + if [ "$(dpkg-query -W -f='${Status}' "$dependency" 2>/dev/null | grep -c "ok installed")" -eq 0 ]; then + deps+=("$dependency") # Add not installed dependency to the "to be installed array". + else + [[ -n $verbose ]] && printf "%s already installed!\n" "$dependency" # If the dependency is already installed print it. + fi + done + +if [ ! "${#deps[@]}" -ge "1" ]; then # If nothing needs to get installed don't start apt. + [[ -n $verbose ]] && echo "All dependencies are fulfilled." # Dependency array empty! Not running apt! +else + [[ -z $verbose ]] && echo "Starting dependency installation." + [[ -n $verbose ]] && echo "Then following dependencies are going to be installed:" # Dependency array contains items. Running apt. + [[ -n $verbose ]] && echo "${deps[@]}" | sed 's/ /, /g' + start_apt install -y -qq --no-install-suggests --no-install-recommends "${deps[@]}" > /dev/null || error_handler "There was an error doing dependency installation!" +fi + [[ -n $verbose ]] && printf "\n" +} + +start_apt(){ + i="0" + if command -v fuser &> /dev/null; then + while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + [ "$i" -eq "0" ] && printf "\nWaiting for other software managers to finish" + [ "$i" -le "16" ] && printf "." # Print a max of 16 dots if waiting. + ((i=i+1)) + sleep "1s" + done + [ "$i" -ge "1" ] && printf "ready!\n" + fi + DEBIAN_FRONTEND=noninteractive apt-get "$@" +} + +# Build targets and corresponding deployment. + +build-linux(){ + [[ -n $install_deps ]] && install_dependencies "${dep_build_core[@]}" + make full +} + +build-linux-deploy(){ + #printf "\nLinux Deployment started..\n" + mkdir -p ./deployment/linux/backends + mkdir -p ./deployment/linux/docs + cp ./midimonster ./deployment/linux/ + cp ./backends/*.so ./deployment/linux/backends/ + cp ./monster.cfg ./deployment/linux/monster.cfg + cp ./backends/*.md ./deployment/linux/docs/ + cp -r ./configs ./deployment/linux/ + cd ./deployment/linux || error_handler "Error doing cd to ./deployment" + filename="midimonster-$(git describe)-$OS.tgz" + touch "$filename" && tar --exclude=*.tgz -czf "$filename" "./" + find . ! -iname "*.zip" ! -iname "*.tgz" -delete +} + +build-windows(){ + [[ -n $install_deps ]] && install_dependencies "${dep_build_core[@]}" "${dep_build_win[@]}" + make windows +} + +build-windows-deploy(){ + #printf "\nWindows Deployment started..\n" + mkdir -p ./deployment/windows/backends + mkdir -p ./deployment/windows/docs + strip midimonster.exe backends/*.dll # Strip the Windows binaries as they become huge quickly. + cp ./midimonster.exe ./deployment/windows/ + cp ./backends/*.dll ./deployment/windows/backends/ + cp ./backends/*.dll.disabled ./deployment/windows/backends/ + cp ./monster.cfg ./deployment/windows/monster.cfg + cp ./backends/*.md ./deployment/windows/docs/ + cp -r ./configs ./deployment/windows/ + cd ./deployment/windows || error_handler "Error doing cd to ./deployment/windows" + zip -r "./midimonster-$(git describe)-windows.zip" "./" + find . ! -iname "*.zip" ! -iname "*.tgz" -delete +} + +build-debian(){ + [[ -n $install_deps ]] && install_dependencies "${dep_build_core[@]}" "${dep_build_debian[@]}" + git checkout debian/master + gbp buildpackage +} + +build-debian-deploy(){ + #printf "\nDebian Package Deployment started..\n" + mkdir -p ./deployment/debian/ + cp ./*.deb ./deployment/debian/ +} + +# Tests + +ckeck-spelling(){ # Check spelling. + [[ -n $install_deps ]] && install_dependencies "lintian" + spellcheck_files=$(find . -type f | grep -v ".git/") # Create list of files to be spellchecked. + sl_results=$(xargs spellintian 2>&1 <<< "$spellcheck_files") # Run spellintian to find spelling errors + sl_errors=$(wc -l <<< "$sl_results") + sl_errors_dups=$( (grep -c "\(duplicate word\)") <<< "$sl_results") + sl_errors_nodups=$( (grep -cv "\(duplicate word\)") <<< "$sl_results") + + if [ "$sl_errors" -gt "1" ]; then + printf "Spellintian found %s errors (%s spelling, %s duplicate words):\n\n" "$sl_errors" "$sl_errors_nodups" "$sl_errors_dups" + printf "%s\n\n" "$sl_results" + exitcode=1 + else + printf "Spellintian reports no errors\n" + fi +} + +check-codespelling(){ # Check code for common misspellings. + [[ -n $install_deps ]] && install_dependencies "codespell" + spellcheck_files=$(find . -type f | grep -v ".git/") # Create list of files to be spellchecked. + cs_results=$(xargs codespell --quiet 2 <<< "$spellcheck_files" 2>&1) + cs_errors=$(wc -l <<< "$cs_results") + if [ "$cs_errors" -gt "1" ]; then + printf "Codespell found %s errors:\n\n" "$cs_errors" + printf "%s\n\n" "$cs_results" + exitcode=1 + else + printf "Codespell reports no errors\n" + fi +} + +analyze-complexity(){ # code complexity analyser. + [[ -n $install_deps ]] && install_dependencies "python3" "python3-pip" + if [ -z "$(which ~/.local/bin/lizard)" ]; then + printf "Installing lizard...\n" + pip3 install lizard >/dev/null + fi + printf "Running lizard for code complexity analysis\n" + ~/.local/bin/lizard ./ + if [ "$?" -ne "0" ]; then + exitcode=1 + fi +} + +analyze-shellscript(){ # Shellscript analysis tool. + [[ -n $install_deps ]] && install_dependencies "shellcheck" + printf "Running shellcheck:\n" + shell_files="$(find . -type f -iname \*.sh)" + xargs shellcheck -Cnever -s bash <<< "$shell_files" + if [ "$?" -ne "0" ]; then + exitcode=1 + fi +} + +stats(){ # Code statistics. + [[ -n $install_deps ]] && install_dependencies "cloc" + printf "Code statistics:\n" + cloc ./ +} + +target_queue(){ + printf "\n" + IFS=',|.' read -ra Queue <<< "$TARGETS" + for i in "${Queue[@]}"; do + case "$i" in + check-spelling|1) + ckeck-spelling + ;; + check-codespelling|2) + check-codespelling + ;; + analyze-complexity|3) + analyze-complexity + ;; + analyze-shellscript|4) + analyze-shellscript + ;; + stats|5) + stats + ;; + build-linux|10) + OS="linux" + build-linux + [[ -n $deploy ]] && build-linux-deploy # Deploy build artifacts if the deploy flag is set. + ;; + build-windows|build-win|11) + build-windows + [[ -n $deploy ]] && build-windows-deploy # Deploy build artifacts if the deploy flag is set. + ;; + build-debian|build-deb|12) + build-debian + [[ -n $deploy ]] && build-debian-deploy # Deploy build artifacts if the deploy flag is set. + ;; + build-osx|13) + OS="osx" + printf "\nNot implemented yet!\n" + #build-linux + #[[ -n $deploy ]] && build-linux-deploy # Deploy build artifacts if the deploy flag is set. + ;; + deps-linux) + # Target to install all needed dependencies for linux builds. + install_dependencies "${dep_build_core[@]}" + ;; + deps-windows|deps-win) + # Target to install all needed dependencies for windows builds. + install_dependencies "${dep_build_core[@]}" "${dep_build_win[@]}" + ;; + deps-debian|deps-deb) + # Target to install all needed dependencies for debian packaging. + install_dependencies "${dep_build_core[@]}" "${dep_build_debian[@]}" + ;; + deps-osx) + # Target to install all needed dependencies for osx. + printf "\nNot implemented yet!\n" + ;; + deps-tests) + install_dependencies "lintian" "codespell" "python3" "python3-pip" "shellcheck" "cloc" + # Install lizard if not found. + if [ -z "$(which ~/.local/bin/lizard)" ]; then + pip3 install lizard >/dev/null + fi + ;; + deps-all) + # Target to install all needed dependencies for this ci script. + install_dependencies "${dep_build_core[@]}" "${dep_build_win[@]}" "${dep_build_debian[@]}" "lintian" "codespell" "python3" "python3-pip" "shellcheck" "cloc" + ;; + *) + printf "Target '%s' not valid!\n" "$i" + ;; + esac + printf "\n" + done +} + +error_handler(){ + [[ -n $1 ]] && printf "\n%s\n" "$1" + printf "\nAborting" + for i in {1..3}; do sleep 0.3s && printf "." && sleep 0.2s; done + printf "\n" + exit "1" +} + +################################################ Main ################################################# +trap error_handler SIGINT SIGTERM + +ARGS "$@" # Parse arguments. +target_queue # Start requestet targets. + +# Allow failure handler. +[[ -z $allow_failure ]] && exit "$exitcode" +exit "0"
\ No newline at end of file |