From e754932ba3cdf03061f47d0c0fce2980684a6988 Mon Sep 17 00:00:00 2001 From: shenmo Date: Tue, 21 Oct 2025 20:45:57 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BD=AC=E6=8D=A2=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apm-convert.sh | 234 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 apm-convert.sh diff --git a/apm-convert.sh b/apm-convert.sh new file mode 100644 index 0000000..d16f838 --- /dev/null +++ b/apm-convert.sh @@ -0,0 +1,234 @@ +#!/bin/bash + +# APM软件包生成器 +# 用法: apm-convert-deb --basename [--pkgname <包名>] [--version <版本号>] + + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# 显示用法信息 +usage() { + echo "用法: $0 --basename [--pkgname <包名>] [--version <版本号>]" + echo "示例: $0 --basename deepin-wine /path/to/package.deb --pkgname my-package --version 1.0.0-1" + exit 1 +} + +# 显示带颜色的消息 +info() { echo -e "${GREEN}[INFO]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# 清理函数 +cleanup() { + info "正在清理..." + + # 卸载挂载点 + if mountpoint -q "${CRAFT_DIR}/mergedir" ; then + sudo umount "${CRAFT_DIR}/mergedir" || warn "卸载 ${CRAFT_DIR}/ace-env 失败" + fi + + # 删除临时目录 + if [[ -d "${CRAFT_DIR}" ]]; then + rm -rf "${CRAFT_DIR}" || warn "删除临时目录失败: ${CRAFT_DIR}" + fi + + # 删除工作目录 + if [[ -d "${WORK_DIR}" ]]; then + rm -rf "${WORK_DIR}" || warn "删除工作目录失败: ${WORK_DIR}" + fi +} + +# 信号处理 +trap cleanup EXIT INT TERM + +# 参数解析 +BASENAME="" +DEB_PATH="" +PKGNAME="" +VERSION="" + +# 解析参数 +while [[ $# -gt 0 ]]; do + case $1 in + --basename) + BASENAME="$2" + shift 2 + ;; + --pkgname) + PKGNAME="$2" + shift 2 + ;; + --version) + VERSION="$2" + shift 2 + ;; + -*) + error "未知选项: $1" + usage + ;; + *) + if [[ -z "$DEB_PATH" ]]; then + DEB_PATH="$1" + shift + else + error "多余的参数: $1" + usage + fi + ;; + esac +done + +# 验证必要参数 +if [[ -z "$BASENAME" || -z "$DEB_PATH" ]]; then + error "缺少必要参数" + usage +fi + +if [[ ! -f "$DEB_PATH" ]]; then + error "DEB文件不存在: $DEB_PATH" + exit 1 +fi + +info "开始处理 DEB 文件: $DEB_PATH" +info "基础环境: $BASENAME" +# 1. 创建临时目录结构 +CRAFT_DIR=$(mktemp -d ~/apm-craft.XXXXXX) +info "创建临时目录: $CRAFT_DIR" + +mkdir -p "${CRAFT_DIR}/core" "${CRAFT_DIR}/work" "${CRAFT_DIR}/mergedir" +export CRAFT_DIR + +# 2. 融合挂载 +ACE_ENV_PATH="/var/lib/apm/apm/files/ace-env/var/lib/apm/${BASENAME}/files/ace-env" +if [[ ! -d "$ACE_ENV_PATH" ]]; then + error "基础环境不存在: $ACE_ENV_PATH" + exit 1 +fi + +info "正在挂载融合文件系统..." +sudo mount -t overlay overlay \ + -o "lowerdir=${ACE_ENV_PATH},upperdir=${CRAFT_DIR}/core/,workdir=${CRAFT_DIR}/work/" \ + "${CRAFT_DIR}/mergedir" +# 3. 安装DEB包到融合环境 +info "正在安装DEB包到融合环境..." +export chrootEnvPath="${CRAFT_DIR}/mergedir" +sudo -E /var/lib/apm/apm/files/ace-run-pkg apt install "$DEB_PATH" -y + +# 4. 检查DEB文件信息 +info "正在分析DEB包信息..." +ORIG_PKGNAME=$(dpkg -f "$DEB_PATH" Package) +ORIG_VERSION=$(dpkg -f "$DEB_PATH" Version) + +# 设置新包名和版本 +NEW_PKGNAME="${PKGNAME:-$ORIG_PKGNAME}" +NEW_VERSION="${VERSION:-${ORIG_VERSION}-1}" + +info "原包名: $ORIG_PKGNAME, 原版本: $ORIG_VERSION" +info "新包名: $NEW_PKGNAME, 新版本: $NEW_VERSION" + +# 5. 创建新的DEB包结构 +WORK_DIR=$(mktemp -d ~/apm-work.XXXXXX) +info "创建工作目录: $WORK_DIR" + +DEB_ROOT="${WORK_DIR}/${NEW_PKGNAME}_${NEW_VERSION}_amd64" +mkdir -p "${DEB_ROOT}/DEBIAN" +mkdir -p "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}" +mkdir -p "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/entries" +mkdir -p "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/files" + +# 创建postinst脚本 +cat > "${DEB_ROOT}/DEBIAN/postinst" << 'EOF' +#!/bin/bash +PACKAGE_NAME="$DPKG_MAINTSCRIPT_PACKAGE" + +if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then + echo "清理卸载残留" + rm -rf "/var/lib/apm/$PACKAGE_NAME" +else + echo "非卸载,跳过清理" +fi +EOF +chmod 755 "${DEB_ROOT}/DEBIAN/postinst" + +# 创建info文件 +echo "$BASENAME" > "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/info" + +# 处理.desktop文件 +info "正在处理桌面文件..." +DESKTOP_FILES=$(dpkg -L "$ORIG_PKGNAME" | grep "^/usr/share/" 2>/dev/null || true) + +for desktop_file in $DESKTOP_FILES; do + if sudo -E /var/lib/apm/apm/files/ace-run-pkg test -f "$desktop_file"; then + info "处理桌面文件: $desktop_file" + + # 修改Exec和TryExec行 + sudo -E /var/lib/apm/apm/files/ace-run-pkg sed -i \ + -e "s/^Exec=\(.*\)$/Exec=apm run $NEW_PKGNAME \1/" \ + -e "s/^TryExec=\(.*\)$/TryExec=apm run $NEW_PKGNAME \1/" \ + "$desktop_file" + fi +done + +# 复制/usr/share/下的文件 +info "正在复制/usr/share/文件..." +SHARE_FILES=$(dpkg -L "$ORIG_PKGNAME" | grep "^/usr/share/" || true) +for file in $SHARE_FILES; do + rel_path="${file#/usr/share/}" + if sudo -E /var/lib/apm/apm/files/ace-run-pkg test -e "/usr/share/$rel_path"; then + dest_dir="${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/entries/usr/share/$(dirname "$rel_path")" + mkdir -p "$dest_dir" + sudo cp -a "${CRAFT_DIR}/mergedir/usr/share/$rel_path" "$dest_dir/" 2>/dev/null || true + fi +done + +# 复制/opt/apps/下的文件 +info "正在复制/opt/apps/文件..." +OPT_FILES=$(dpkg -L "$ORIG_PKGNAME" | grep "^/opt/apps/${ORIG_PKGNAME}/entries/" || true) +for file in $OPT_FILES; do + rel_path="${file#/opt/apps/${ORIG_PKGNAME}/entries/}" + if sudo -E /var/lib/apm/apm/files/ace-run-pkg test -e "$file"; then + dest_dir="${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/entries/$(dirname "$rel_path")" + mkdir -p "$dest_dir" + sudo cp -a "${CRAFT_DIR}/mergedir/$file" "$dest_dir/" 2>/dev/null || true + fi +done + +# 复制core和work目录到files +info "正在复制核心文件..." +sudo chown -R $(id -u):$(id -g) "${CRAFT_DIR}/core" "${CRAFT_DIR}/work" +chmod -R 755 "${CRAFT_DIR}/work" "${CRAFT_DIR}/core" +cp -a "${CRAFT_DIR}/core" "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/files/" +cp -a "${CRAFT_DIR}/work" "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/files/" + +# 设置文件权限 +sudo chown -R $(id -u):$(id -g) "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/files" +chmod -R 755 "${DEB_ROOT}/var/lib/apm/${NEW_PKGNAME}/files" + +# 创建control文件 +cat > "${DEB_ROOT}/DEBIAN/control" << EOF +Package: $NEW_PKGNAME +Version: $NEW_VERSION +Architecture: amd64 +Maintainer: APM Converter +Description: APM converted package from $ORIG_PKGNAME + Converted from original package: $ORIG_PKGNAME +Depends: $BASENAME +EOF + +# 6. 解除挂载 +info "正在解除挂载..." +sudo umount "${CRAFT_DIR}/mergedir" + +# 7. 打包DEB +info "正在打包DEB文件..." +fakeroot dpkg-deb --build "${DEB_ROOT}" "${NEW_PKGNAME}_${NEW_VERSION}_amd64.apm.deb" + +info "APM包生成完成: ${NEW_PKGNAME}_${NEW_VERSION}_amd64.apm.deb" + +# 8. 清理工作目录 +sudo rm -rf "$WORK_DIR" +info "清理完成" \ No newline at end of file