#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" fail() { echo "FAIL: $*" >&2 exit 1 } assert_file_contains() { local file="$1" local pattern="$2" grep -qE "$pattern" "$file" || fail "$file does not contain pattern: $pattern" } assert_file_not_contains() { local file="$1" local pattern="$2" if grep -qE "$pattern" "$file"; then fail "$file contains forbidden pattern: $pattern" fi } assert_bash_syntax() { local file="$1" bash -n "$file" || fail "$file has invalid bash syntax" } assert_archive_clean_for_linux_tar() { local archive="$1" local metadata_entries local xattr_entries metadata_entries="$(tar -tzf "$archive" | grep -E '(^|/)\._|(^|/)\.DS_Store$|(^|/)__MACOSX(/|$)' || true)" if [[ -n "$metadata_entries" ]]; then fail "$archive contains macOS metadata files" fi xattr_entries="$(gzip -dc "$archive" | strings | grep -E 'LIBARCHIVE\.xattr|SCHILY\.xattr|com\.apple' || true)" if [[ -n "$xattr_entries" ]]; then fail "$archive contains macOS extended attributes" fi } assert_gzip_tar_contains() { local archive="$1" local path="$2" tar -tzf "$archive" | grep -qx "$path" || fail "$archive does not contain $path" } assert_plain_tar_archive_clean_for_linux_tar() { local archive="$1" local metadata_entries local xattr_entries metadata_entries="$(tar -tf "$archive" | grep -E '(^|/)\._|(^|/)\.DS_Store$|(^|/)__MACOSX(/|$)' || true)" if [[ -n "$metadata_entries" ]]; then fail "$archive contains macOS metadata files" fi xattr_entries="$(tar -xOf "$archive" 2>/dev/null | strings | grep -E 'LIBARCHIVE\.xattr|SCHILY\.xattr|com\.apple' || true)" if [[ -n "$xattr_entries" ]]; then fail "$archive contains macOS extended attributes" fi } assert_bash_syntax "$ROOT_DIR/dapostinstall.sh" assert_bash_syntax "$ROOT_DIR/da_cli.sh" assert_bash_syntax "$ROOT_DIR/daupdate.sh" php -l "$ROOT_DIR/lang_pl.php" >/dev/null || fail "lang_pl.php has invalid PHP syntax" assert_archive_clean_for_linux_tar "$ROOT_DIR/spolszczenie_enhanced.tar.gz" [[ -f "$ROOT_DIR/branding/da_templates.tar" ]] || fail "missing local da_templates archive" [[ -f "$ROOT_DIR/branding/da-branding-hitme.tar.gz" ]] || fail "missing local DA branding archive" assert_plain_tar_archive_clean_for_linux_tar "$ROOT_DIR/branding/da_templates.tar" assert_archive_clean_for_linux_tar "$ROOT_DIR/branding/da-branding-hitme.tar.gz" [[ -f "$ROOT_DIR/plugins/borg-restore.tar.gz" ]] || fail "missing borg-restore plugin archive" [[ -f "$ROOT_DIR/plugins/db-manager.tar.gz" ]] || fail "missing db-manager plugin archive" [[ -f "$ROOT_DIR/plugins/redis-manager.tar.gz" ]] || fail "missing redis-manager plugin archive" assert_archive_clean_for_linux_tar "$ROOT_DIR/plugins/borg-restore.tar.gz" assert_archive_clean_for_linux_tar "$ROOT_DIR/plugins/db-manager.tar.gz" assert_archive_clean_for_linux_tar "$ROOT_DIR/plugins/redis-manager.tar.gz" assert_gzip_tar_contains "$ROOT_DIR/plugins/borg-restore.tar.gz" './install.sh' assert_gzip_tar_contains "$ROOT_DIR/plugins/db-manager.tar.gz" './install.sh' assert_gzip_tar_contains "$ROOT_DIR/plugins/redis-manager.tar.gz" './install.sh' assert_gzip_tar_contains "$ROOT_DIR/plugins/redis-manager.tar.gz" './scripts/redis_migrate.sh' assert_file_contains "$ROOT_DIR/da_cli.sh" '^DEFAULTPACKAGE=NO-LIMIT$' assert_file_not_contains "$ROOT_DIR/da_cli.sh" '^eparated list of IP addresses$' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'c\\ns1=' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'c\\ns2=' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns1"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns2"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^DEFAULT_NS1=dns3\.hitme\.net\.pl$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^DEFAULT_NS2=dns4\.hitme\.net\.pl$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^REDIS_VERSION=8$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^PLUGIN_ARCHIVE_DIR="\$DAPOSTINSTALL_DIR/plugins"$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^BRANDING_DIR="\$DAPOSTINSTALL_DIR/branding"$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^DA_TEMPLATES_ARCHIVE="\$BRANDING_DIR/da_templates\.tar"$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^DA_BRANDING_ARCHIVE="\$BRANDING_DIR/da-branding-hitme\.tar\.gz"$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^php1_release=' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^php2_release=' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^php9_release=' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^ioncube=yes$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^zend=yes$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^opcache=yes$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^imap=yes$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^imagick=yes$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^SETUP_TXT="\$DADIR/conf/setup\.txt"$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^update_daupdate_tools\(\) \{$' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '/opt/daupdate\.sh update' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'require_file "\$SETUP_TXT"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'require_file "\$DA_TEMPLATES_ARCHIVE"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'require_file "\$DA_BRANDING_ARCHIVE"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'require_dir "\$PLUGIN_ARCHIVE_DIR"' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'https://cdn\.hitme\.pl/da_templates\.tar' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'https://cdn\.hitme\.pl/da_files/da-branding-hitme\.tar\.gz' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'tar -xf "\$DA_TEMPLATES_ARCHIVE" -C "\$templates_tmp"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'tar -xzf "\$DA_BRANDING_ARCHIVE" -C /' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'index-hitme\.html' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'DA_ADMINPASS=\$\(get_key_value "\$SETUP_TXT" "adminpass"\)' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns1" "\$DEFAULT_NS1"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns2" "\$DEFAULT_NS2"' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'MIN_PASSWORD_LENGTH' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'MAX_PASSWORD_LENGTH' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'ITERATION_LIMIT' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '/dev/urandom' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'changeuserpass admin' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^configure_custombuild_php\(\) \{$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'release_var="php\$\{idx\}_release"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'release="\$\{!release_var\}"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build set "php\$\{idx\}_release" "\$release"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build set "php\$\{idx\}_mode" "php-fpm"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build php' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build rewrite_confs' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'eximconf_release' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '\./build' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '^[[:space:]]*\$CBDIR/build' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build set eximconf yes' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build exim_conf' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$ioncube" "ioncube" "ioncube"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$zend" "zend" "zend"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$opcache" "opcache" "opcache"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$imap" "php_imap" "php_imap"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$imagick" "imagick" "imagick"' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'sed -i .*imagick=no' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'sed -i .*imap=no' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'yum -y install redis redis-devel' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '\./php-extension\.sh install redis' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'ln -s /etc/redis/redis\.conf /etc/redis\.conf' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" "sed -i 's/DA_.*mail_powitalny.txt" assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'mv mail_powitalny.txt /root' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'DA_PHP_LIST=\$\(get_php_release_list "\$DA_OPTIONSCONF"\)' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'render_template "\$DAPOSTINSTALL_DIR/mail_powitalny.txt" "/root/mail_powitalny.txt"' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'PS3=' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '^select opt in' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '"Niestandardowa"\)' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Czy instalowac' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Czy aktywowac' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Podaj adres NS' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Jaka skorke ustawic' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Wybierz tryb instalacji' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" "s/evolution/enhanced" assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'Skorka evolution zostala ustawiona jako domyslna' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^install_local_plugin_archive\(\) \{$' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'local found=0' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'for archive in "\$PLUGIN_ARCHIVE_DIR"/\*\.tar\.gz; do' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'found=1' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'Brak paczek pluginów w \$PLUGIN_ARCHIVE_DIR' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'plugin_name="\$\(basename "\$archive" \.tar\.gz\)"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'mkdir -p "\$plugin_dir"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'tar -zxf "\$archive" -C "\$plugin_dir"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'chmod 755 "\$plugin_dir/install\.sh"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'cd "\$plugin_dir"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '\./install\.sh' assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'chmod 755 "\$DADIR/plugins/redis-manager/scripts/redis_migrate\.sh"' assert_file_contains "$ROOT_DIR/dapostinstall.sh" '"\$DADIR/plugins/redis-manager/scripts/redis_migrate\.sh" "\$REDIS_VERSION"' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'redis_install\.sh' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'redis_management\.tar\.gz' assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'plugins/redis_management' assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_HOSTNAME\}\}' assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_HASLO\}\}' assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_PHP_LIST\}\}' assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_NS1\}\}' assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_NS2\}\}' assert_file_not_contains "$ROOT_DIR/mail_powitalny.txt" 'DA_PHP1' COMMON_SH="$ROOT_DIR/lib/common.sh" [[ -f "$COMMON_SH" ]] || fail "missing lib/common.sh" # shellcheck source=/dev/null source "$COMMON_SH" tmp_dir="$(mktemp -d)" trap 'rm -rf "$tmp_dir"' EXIT kv_file="$tmp_dir/example.conf" printf 'ns1=old.example\nother=value\n' > "$kv_file" set_key_value "$kv_file" "ns1" "dns3.hitme.net.pl" set_key_value "$kv_file" "ns2" "dns4.hitme.net.pl" grep -qx 'ns1=dns3.hitme.net.pl' "$kv_file" || fail "set_key_value did not replace ns1" grep -qx 'ns2=dns4.hitme.net.pl' "$kv_file" || fail "set_key_value did not append ns2" [[ "$(grep -c '^ns1=' "$kv_file")" -eq 1 ]] || fail "set_key_value duplicated ns1" setup_file="$tmp_dir/setup.txt" printf 'hostname=server.example\nadminpass=hG7KZfTPq1z8f4KC3N5J4\n' > "$setup_file" [[ "$(get_key_value "$setup_file" "adminpass")" == "hG7KZfTPq1z8f4KC3N5J4" ]] || fail "get_key_value did not read adminpass" php_options="$tmp_dir/options.conf" printf 'php1_release=8.3\nphp2_release=8.2\nphp3_release=no\nphp9_release=7.4\n' > "$php_options" expected_php=$'PHP 8.3 (domyślna)\nPHP 8.2\nPHP 7.4' [[ "$(get_php_release_list "$php_options")" == "$expected_php" ]] || fail "get_php_release_list returned unexpected output" php1_release=8.3 php2_release=8.2 php3_release=8.1 php4_release=7.4 php5_release=no php6_release=no php7_release=no php8_release=no php9_release=5.6 php_commands="$tmp_dir/php_commands.log" for idx in 1 2 3 4 5 6 7 8 9; do release_var="php${idx}_release" release="${!release_var}" printf 'da build set php%s_release %s\n' "$idx" "$release" >> "$php_commands" done grep -qx 'da build set php1_release 8.3' "$php_commands" || fail "php1_release command is wrong" grep -qx 'da build set php2_release 8.2' "$php_commands" || fail "php2_release command is wrong" grep -qx 'da build set php9_release 5.6' "$php_commands" || fail "php9_release command is wrong" [[ "$(cut -d' ' -f5 "$php_commands" | sort -u | wc -l | tr -d ' ')" -gt 2 ]] || fail "php release commands appear to reuse a single value" template_file="$tmp_dir/template.txt" output_file="$tmp_dir/output.txt" printf 'Host: {{DA_HOSTNAME}}\nPass: {{DA_HASLO}}\nPHP:\n{{DA_PHP_LIST}}\n' > "$template_file" export DA_HOSTNAME='server.example' export DA_HASLO='abc/123&xyz' export DA_PHP_LIST="$expected_php" render_template "$template_file" "$output_file" grep -qx 'Host: server.example' "$output_file" || fail "render_template did not replace hostname" grep -qx 'Pass: abc/123&xyz' "$output_file" || fail "render_template did not safely replace password" grep -qx 'PHP 8.3 (domyślna)' "$output_file" || fail "render_template did not replace multiline PHP list" echo "quality checks passed"