common.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. #!/usr/bin/env bash
  2. # ============================================================================
  3. # Gemeinsame Funktionen fuer make_installer_*.sh
  4. # ============================================================================
  5. set -euo pipefail
  6. # Verzeichnisse
  7. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  8. SOURCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
  9. EXCLUDE_FILE="${SCRIPT_DIR}/exclude_patterns.txt"
  10. INSTALLER_DIR="${SCRIPT_DIR}/installer"
  11. BUILD_CONF="${SCRIPT_DIR}/build.conf"
  12. # --- build.conf laden ---
  13. load_build_conf() {
  14. # Defaults
  15. INCLUDE_AUDIO_ASSETS=true
  16. INCLUDE_MUSIC_ASSETS=false
  17. INCLUDE_MORPHER_ASSETS=true
  18. INCLUDE_WAKEWORD_MODELS=true
  19. INCLUDE_PIPER_MODELS=false
  20. INCLUDE_SYMSPELL=true
  21. INCLUDE_LLM_MODELS=false
  22. INCLUDE_PLUGIN_MODELS=false
  23. INCLUDE_TRAINER_SOURCE=true
  24. INCLUDE_TRAINING_DATA=false
  25. INCLUDE_DOCS=true
  26. INCLUDE_BASH_SCRIPTS=true
  27. if [[ -f "${BUILD_CONF}" ]]; then
  28. # Nur KEY=value Zeilen laden (keine Kommentare, keine leeren Zeilen)
  29. while IFS='=' read -r key value; do
  30. key=$(echo "${key}" | xargs) # Whitespace trimmen
  31. value=$(echo "${value}" | xargs)
  32. [[ -z "${key}" || "${key}" == \#* ]] && continue
  33. declare -g "${key}=${value}"
  34. done < "${BUILD_CONF}"
  35. echo " build.conf geladen"
  36. else
  37. echo " WARNUNG: ${BUILD_CONF} nicht gefunden — verwende Defaults"
  38. fi
  39. }
  40. # --- Dynamische Excludes aus build.conf generieren ---
  41. build_conf_excludes() {
  42. local mode="$1"
  43. local excludes=""
  44. # Assets
  45. if [[ "${INCLUDE_AUDIO_ASSETS}" != "true" ]]; then
  46. excludes+=" assets/default/audio"
  47. fi
  48. if [[ "${INCLUDE_MUSIC_ASSETS}" != "true" ]]; then
  49. excludes+=" assets/default/music"
  50. fi
  51. if [[ "${INCLUDE_MORPHER_ASSETS}" != "true" ]]; then
  52. excludes+=" assets/default/audio_morpher"
  53. fi
  54. # Modelle
  55. if [[ "${INCLUDE_WAKEWORD_MODELS}" != "true" ]]; then
  56. excludes+=" models/wakeword/*/*.onnx"
  57. fi
  58. if [[ "${INCLUDE_PIPER_MODELS}" != "true" ]]; then
  59. excludes+=" models/piper/*.onnx models/piper/.cache"
  60. fi
  61. if [[ "${INCLUDE_SYMSPELL}" != "true" ]]; then
  62. excludes+=" models/symspell"
  63. fi
  64. if [[ "${INCLUDE_LLM_MODELS}" != "true" ]]; then
  65. excludes+=" models/nlp/*.gguf"
  66. fi
  67. if [[ "${INCLUDE_PLUGIN_MODELS}" != "true" ]]; then
  68. excludes+=" plugins/*/models"
  69. fi
  70. # Trainer
  71. if [[ "${INCLUDE_TRAINER_SOURCE}" != "true" ]]; then
  72. excludes+=" trainer"
  73. fi
  74. if [[ "${INCLUDE_TRAINING_DATA}" != "true" ]]; then
  75. excludes+=" trainer/data/raw trainer/data/processed trainer/assets trainer/cache trainer/processed"
  76. fi
  77. # Sonstiges
  78. if [[ "${INCLUDE_DOCS}" != "true" ]]; then
  79. excludes+=" docs"
  80. fi
  81. if [[ "${INCLUDE_BASH_SCRIPTS}" != "true" ]]; then
  82. excludes+=" bash"
  83. fi
  84. echo "${excludes}"
  85. }
  86. # --- Version aus trixy_core/utils/version.py parsen ---
  87. parse_version() {
  88. local version_file="${SOURCE_DIR}/trixy_core/utils/version.py"
  89. if [[ ! -f "${version_file}" ]]; then
  90. echo "FEHLER: ${version_file} nicht gefunden" >&2
  91. exit 1
  92. fi
  93. local major minor revision
  94. major=$(grep -E '^MAJOR:\s*int\s*=' "${version_file}" | grep -oE '[0-9]+')
  95. minor=$(grep -E '^MINOR:\s*int\s*=' "${version_file}" | grep -oE '[0-9]+')
  96. revision=$(grep -E '^REVISION:\s*int\s*=' "${version_file}" | grep -oE '[0-9]+')
  97. echo "${major}.${minor}.${revision}"
  98. }
  99. # --- Release-Verzeichnis erstellen ---
  100. prepare_release_dir() {
  101. local version="$1"
  102. local mode="$2"
  103. local release_dir="${SCRIPT_DIR}/Release/${version}-${mode}"
  104. mkdir -p "${release_dir}"
  105. echo "${release_dir}"
  106. }
  107. # --- build.conf Einstellungen anzeigen ---
  108. print_build_conf() {
  109. local mode="$1"
  110. echo " Build-Konfiguration:"
  111. echo " Audio-Assets: ${INCLUDE_AUDIO_ASSETS}"
  112. echo " Musik-Assets: ${INCLUDE_MUSIC_ASSETS}"
  113. echo " Morpher-Assets: ${INCLUDE_MORPHER_ASSETS}"
  114. echo " Wakeword-Modelle: ${INCLUDE_WAKEWORD_MODELS}"
  115. echo " Piper-Modelle: ${INCLUDE_PIPER_MODELS}"
  116. echo " SymSpell: ${INCLUDE_SYMSPELL}"
  117. echo " LLM-Modelle: ${INCLUDE_LLM_MODELS}"
  118. echo " Plugin-Modelle: ${INCLUDE_PLUGIN_MODELS}"
  119. echo " Trainer-Source: ${INCLUDE_TRAINER_SOURCE}"
  120. echo " Trainings-Daten: ${INCLUDE_TRAINING_DATA}"
  121. echo " Dokumentation: ${INCLUDE_DOCS}"
  122. echo " Bash-Skripte: ${INCLUDE_BASH_SCRIPTS}"
  123. echo ""
  124. }
  125. # --- Source-tar erstellen ---
  126. create_source_tar() {
  127. local mode="$1"
  128. local version="$2"
  129. local release_dir="$3"
  130. local extra_excludes="$4" # Zusaetzliche Exclude-Patterns (Leerzeichen-getrennt)
  131. local tar_name="trixy-${mode}-${version}.tar.gz"
  132. local tar_path="${release_dir}/${tar_name}"
  133. echo " Erstelle ${tar_name}..."
  134. # Basis-Excludes aus exclude_patterns.txt
  135. local exclude_opts=()
  136. while IFS= read -r pattern; do
  137. [[ -z "${pattern}" || "${pattern}" == \#* ]] && continue
  138. exclude_opts+=("--exclude=${pattern}")
  139. done < "${EXCLUDE_FILE}"
  140. # build.conf-basierte Excludes
  141. local conf_excludes
  142. conf_excludes=$(build_conf_excludes "${mode}")
  143. for pattern in ${conf_excludes}; do
  144. exclude_opts+=("--exclude=${pattern}")
  145. done
  146. # Modus-spezifische Excludes
  147. for pattern in ${extra_excludes}; do
  148. exclude_opts+=("--exclude=${pattern}")
  149. done
  150. # tar in temporaere Datei schreiben, dann verschieben
  151. local tmp_tar
  152. tmp_tar="$(mktemp)"
  153. local prefix="trixy-${mode}-${version}"
  154. tar czf "${tmp_tar}" \
  155. -C "${SOURCE_DIR}" \
  156. "${exclude_opts[@]}" \
  157. --exclude='make_installer/Release' \
  158. --transform="s,^\\.,${prefix}," \
  159. .
  160. mv "${tmp_tar}" "${tar_path}"
  161. echo " -> ${tar_name} ($(du -h "${tar_path}" | cut -f1))"
  162. }
  163. # --- Installer-tar erstellen ---
  164. create_installer_tar() {
  165. local mode="$1"
  166. local version="$2"
  167. local release_dir="$3"
  168. local tar_name="trixy-installer-${mode}-${version}.tar.gz"
  169. local tar_path="${release_dir}/${tar_name}"
  170. echo " Erstelle ${tar_name}..."
  171. tar czf "${tar_path}" \
  172. -C "${INSTALLER_DIR}/.." \
  173. --transform='s,^installer,trixy_installer,' \
  174. --exclude='__pycache__' \
  175. --exclude='*.pyc' \
  176. installer/
  177. echo " -> ${tar_name} ($(du -h "${tar_path}" | cut -f1))"
  178. }
  179. # --- install.sh generieren ---
  180. generate_install_sh() {
  181. local mode="$1"
  182. local version="$2"
  183. local release_dir="$3"
  184. local install_sh="${release_dir}/install-${mode}.sh"
  185. local source_tar="trixy-${mode}-${version}.tar.gz"
  186. local installer_tar="trixy-installer-${mode}-${version}.tar.gz"
  187. echo " Generiere install-${mode}.sh..."
  188. cat > "${install_sh}" << 'INSTALL_HEADER'
  189. #!/usr/bin/env bash
  190. # ============================================================================
  191. # Trixy Installer — Bootstrap-Script
  192. #
  193. # Entpackt den Installer, erstellt ein temporaeres venv und startet die TUI.
  194. # ============================================================================
  195. set -euo pipefail
  196. INSTALL_HEADER
  197. cat >> "${install_sh}" << INSTALL_VARS
  198. # --- Eingebettete Werte ---
  199. MODE="${mode}"
  200. VERSION="${version}"
  201. SOURCE_TAR="${source_tar}"
  202. INSTALLER_TAR="${installer_tar}"
  203. INSTALL_VARS
  204. cat >> "${install_sh}" << 'INSTALL_BODY'
  205. # --- Farben ---
  206. RED='\033[0;31m'
  207. GREEN='\033[0;32m'
  208. YELLOW='\033[1;33m'
  209. NC='\033[0m'
  210. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  211. TEMP_DIR=""
  212. cleanup() {
  213. if [[ -n "${TEMP_DIR}" && -d "${TEMP_DIR}" ]]; then
  214. echo -e "${YELLOW}Raeume auf...${NC}"
  215. rm -rf "${TEMP_DIR}"
  216. fi
  217. }
  218. trap cleanup EXIT
  219. echo ""
  220. echo -e "${GREEN}========================================"
  221. echo " Trixy Installer v${VERSION} [${MODE}]"
  222. echo -e "========================================${NC}"
  223. echo ""
  224. # 1. Pruefe ob tar-Dateien vorhanden
  225. if [[ ! -f "${SCRIPT_DIR}/${SOURCE_TAR}" ]]; then
  226. echo -e "${RED}FEHLER: ${SOURCE_TAR} nicht gefunden${NC}"
  227. exit 1
  228. fi
  229. if [[ ! -f "${SCRIPT_DIR}/${INSTALLER_TAR}" ]]; then
  230. echo -e "${RED}FEHLER: ${INSTALLER_TAR} nicht gefunden${NC}"
  231. exit 1
  232. fi
  233. # 2. Python >= 3.10 sicherstellen
  234. echo "Pruefe Python-Version..."
  235. PYTHON_BIN=""
  236. for py in python3.12 python3.11 python3.10 python3; do
  237. if command -v "${py}" >/dev/null 2>&1; then
  238. py_minor=$("${py}" -c "import sys; print(sys.version_info.minor)")
  239. if [[ "${py_minor}" -ge 10 ]]; then
  240. PYTHON_BIN="${py}"
  241. break
  242. fi
  243. fi
  244. done
  245. if [[ -z "${PYTHON_BIN}" ]]; then
  246. echo -e "${YELLOW}Python >= 3.10 nicht gefunden. Versuche Installation...${NC}"
  247. if command -v apt-get >/dev/null 2>&1; then
  248. sudo apt-get update -qq
  249. sudo apt-get install -y -qq python3 python3-venv python3-pip
  250. PYTHON_BIN="python3"
  251. else
  252. echo -e "${RED}FEHLER: Python >= 3.10 wird benoetigt${NC}"
  253. exit 1
  254. fi
  255. fi
  256. echo " Verwende: ${PYTHON_BIN} ($(${PYTHON_BIN} --version 2>&1))"
  257. # 3. Installer-tar in temp-Verzeichnis entpacken
  258. TEMP_DIR="$(mktemp -d)"
  259. echo "Entpacke Installer nach ${TEMP_DIR}..."
  260. tar xzf "${SCRIPT_DIR}/${INSTALLER_TAR}" -C "${TEMP_DIR}"
  261. # 4. Installer-venv erstellen
  262. INST_VENV="${TEMP_DIR}/installer-venv"
  263. echo "Erstelle Installer-venv..."
  264. "${PYTHON_BIN}" -m venv "${INST_VENV}"
  265. "${INST_VENV}/bin/pip" install --upgrade pip -q 2>/dev/null
  266. "${INST_VENV}/bin/pip" install -r "${TEMP_DIR}/trixy_installer/requirements.txt" -q
  267. # 5. TUI starten
  268. echo ""
  269. echo -e "${GREEN}Starte Installer-TUI...${NC}"
  270. echo ""
  271. PYTHONPATH="${TEMP_DIR}" "${INST_VENV}/bin/python" -m trixy_installer \
  272. --mode "${MODE}" \
  273. --version "${VERSION}" \
  274. --source-archive "${SCRIPT_DIR}/${SOURCE_TAR}"
  275. echo ""
  276. echo -e "${GREEN}Installer beendet.${NC}"
  277. INSTALL_BODY
  278. chmod +x "${install_sh}"
  279. echo " -> install-${mode}.sh generiert"
  280. }
  281. # --- Build zusammenfassen ---
  282. print_summary() {
  283. local mode="$1"
  284. local version="$2"
  285. local release_dir="$3"
  286. echo ""
  287. echo "========================================"
  288. echo " Build abgeschlossen: ${mode} v${version}"
  289. echo "========================================"
  290. echo ""
  291. echo " Release-Verzeichnis: ${release_dir}"
  292. echo ""
  293. ls -lh "${release_dir}/"
  294. echo ""
  295. echo " Deployment:"
  296. echo " 1. Release-Verzeichnis auf Zielgeraet kopieren"
  297. echo " 2. chmod +x install-${mode}.sh"
  298. echo " 3. ./install-${mode}.sh"
  299. echo ""
  300. }