#!/bin/bash # title :appimage-builder.sh # description :Script for building AppImage # author :Alexander Zhirov # date :20240522 # version :0.2.0 # usage :bash appimage-builder.sh --help #=============================================================================== # Пакеты AppImageTool # https://github.com/AppImage/appimagetool/releases # Среда выполнения # https://github.com/AppImage/type2-runtime/releases set -e version="0.2.0" # Определения по умолчанию # Приложение для сборки AppImage appimage_tool="" # Среда выполнения appimage_runtime="" # Output appimage_output="" # Директория с рецептами appimage_input="$(dirname $(realpath ${0}))/apps" # Директория с кэшем appimage_cache="" # Список приложений для сборки appimage_apps=() # Дополнительные необходимые утилиты rpm2cpio_tool=$(which rpm2cpio 2>/dev/null) cpio_tool=$(which cpio 2>/dev/null) if [ ! -x "${rpm2cpio_tool}" ]; then echo "Отсутствует утилита rpm2cpio" exit 1 fi if [ ! -x "${cpio_tool}" ]; then echo "Отсутствует утилита cpio" exit 1 fi extrpm() { local rpm="${1}" local destination_path="${2}" ${rpm2cpio_tool} ${rpm} | ${cpio_tool} -idmvD ${destination_path} } build_appimage() { local pkg="${1}" local name=$(basename ${pkg}) local build="${pkg}/build.sh" local sources="${pkg}/sources" local files="${pkg}/files" local cache="${appimage_cache}/${name}" # Временные директории для сборки local tmp="/tmp/appimage_${name}_$(date "+%Y%m%d%H%M%S")" local src="${tmp}/src" local app="${tmp}/app" if [ ! -f ${sources} ]; then echo "${name}: не найдено исходных файлов для упаковки" return 1 fi if [ ! -s ${sources} ]; then echo "${name}: не найдено ни одного источника" return 1 fi if [ ! -d ${files} ]; then echo "${files}: не найдена директория с файлами" return 1 fi if ! [ "$(ls -A ${files})" ]; then echo "${files}: отсутствуют файлы для сборки AppImage" return 1 fi # Создание директорий для сборки AppImage mkdir -pv ${src} ${app} ${cache} # Список файлов для скачивания local source_files="$(cat ${sources} | grep -v "^#")" for source_file in ${source_files}; do wget -N -P ${cache} ${source_file} done # Извлечение из rpm пакетов внутренностей for rpm in $(find ${cache} -name "*.rpm"); do extrpm ${rpm} ${app} done # Извлечение из deb пакетов внутренности data.tar.* архивов for deb in $(find ${cache} -name "*.deb"); do local tar_name=$(ar t ${deb} | grep data) local tar_archive="${src}/${tar_name}" ar xv ${deb} ${tar_name} --output ${src} tar xvf ${tar_archive} -C ${app} rm -v ${tar_archive} done # Перенос необходмых файлов для сборки AppImage в директорию сборки cp -rv ${files}/* ${app} # Запуск внутреннего скрипта сборки (если имеется) if [ -f ${build} ]; then export current_path=$(dirname ${build}) export app_path=${app} ${build} unset ${current_path} unset ${app_path} fi local name_appimage=$(grep "Name" ${files}/*.desktop | sed 's/Name=//' | tr ' ' '_')-x86_64.AppImage ${appimage_tool} -v --runtime-file ${appimage_runtime} ${app} ${appimage_output}/${name_appimage} rm -rvf ${tmp} return 0 } help_scritp() { echo -e "\n" \ "Использование: $(basename ${0}) [ОПЦИИ]... [СПИСОК ПАКЕТОВ ДЛЯ СБОРКИ]\n" \ "Основные опции:\n" \ "\t-t\t--appimage-tool\t\tИнструмент сборки AppImage\n" \ "\t-r\t--appimage-runtime\tИнструмент времени выполнения\n" \ "\t-i\t--input-path\t\tДиректория с пакетами исходных файлов\n" \ "\t-o\t--output-path\t\tДиректория сохранения собранных AppImage\n" \ "\t-c\t--cache-path\t\tДиректория кеша для пакетов sources\n" \ "\t-l\t--log-path\t\tДиректория для сохранения журнала сборки\n" \ "Дополнительно:\n" \ "\t-h\t--help\t\t\tПоказать справку\n" \ "\t-v\t--version\t\tВерсия скрипта\n" } main() { while [[ $# -gt 0 ]]; do key="${1}" value="${2}" case "${key}" in -t|--appimage-tool) appimage_tool="${value}" shift ;; -r|--appimage-runtime) appimage_runtime="${value}" shift ;; -i|--input-path) appimage_input="${value}" shift ;; -o|--output-path) appimage_output="${value}" shift ;; -c|--cache-path) appimage_cache="${value}" shift ;; -l|--log-path) appimage_log="${value}" shift ;; -h|--help) help_scritp exit 0 ;; -v|--version) echo "Версия скрипта: ${version}" exit 0 ;; *) appimage_apps+=("${key}") ;; esac shift done if [ -z "${appimage_tool}" ] ; then appimage_tool=$(which appimagetool-x86_64.AppImage 2>/dev/null) fi if [ ! -f "${appimage_tool}" ]; then echo "Отсутствует инструмент сборки: https://github.com/AppImage/appimagetool" exit 1 fi if [ ! -x "${appimage_tool}" ]; then echo "Инструмент сборки $(basename ${appimage_tool}) должен быть исполняемым" exit 1 fi if [ -z "${appimage_runtime}" ] ; then appimage_runtime=$(which runtime-x86_64 2>/dev/null) fi if [ ! -f "${appimage_runtime}" ]; then echo "Отсутствует инструмент времени выполнения: https://github.com/AppImage/type2-runtime" exit 1 fi if [ ! -x "${appimage_runtime}" ]; then echo "Инструмент времени выполнения $(basename ${appimage_runtime}) должен быть исполняемым" exit 1 fi if [ ! -d "${appimage_input}" ]; then echo "Не установлена директория исхоных файлов для сборки AppImage" exit 1 fi if [ "$(find ${appimage_input} -maxdepth 1 -type d | wc -l)" -eq 1 ]; then echo "Директория не содержит исхоных файлов для сборки AppImage: ${appimage_input}" exit 1 fi if [ ! -d "${appimage_output}" ]; then appimage_output="${HOME}/AppImages" mkdir -p "${appimage_output}" echo "Не установлена директория для сохранения AppImage. Будет использована директория по умолчанию: ${appimage_output}" fi if [ ! -d "${appimage_cache}" ]; then appimage_cache="/tmp/appimage_cache" mkdir -p "${appimage_cache}" echo "Не определена директория для кеша. Будет использована директория по умолчанию: ${appimage_cache}" fi if [ ! -d "${appimage_log}" ]; then appimage_log="${appimage_output}" echo "Не определена директория для журнала. Будет использована директория по умолчанию: ${appimage_output}" fi echo "Инструмент сборки: ${appimage_tool}" echo "Инструмент времени выполнения: ${appimage_runtime}" echo "Директория исходных файлов: ${appimage_input}" echo "Директория для сохранения AppImage: ${appimage_output}" echo "Директория для кеша: ${appimage_cache}" echo "Список собираемых пакетов: ${appimage_apps[@]}" local pkgs=$(printf "%s\n" "${appimage_apps[@]}" | xargs -I {} find ${appimage_input} -name {} -mindepth 1 -maxdepth 1 -type d) for pkg in ${pkgs}; do if build_appimage ${pkg} > "${appimage_log}/appimage_build.log" 2>&1 ; then echo "AppImage $(basename ${pkg}) был собран" else echo "AppImage $(basename ${pkg}) не был собран" fi done } main "${@}"