#!/bin/bash # tools/check_lgpl_release.sh — 发布前合规校验闸(只读,不改任何产物)。 # # 用法(在 reader_app 目录外也可): # ./tools/check_lgpl_release.sh [--skip-net] # # 校验项(对齐 devdocs/plan/FUTURE_LIBMOBI.md §4-④ P0): # 1) os.meow.reader.mpk 必含 resources/licenses/{NOTICE,GPL-3.0.txt,LGPL-3.0.txt,FTL.txt} # 2) build_reader.sh 锁定的 libmobi commit 与 NOTICE「Locked version」一致(防锁定值漂移) # 3) [联网] codeload tarball sha256 与 NOTICE 记录指纹一致(未记录则报告,属 P1 补强,不判失败) # 4) [联网] 主仓 git ls-remote 公开可读(LGPL §4(d) 应用源码可达性) # # 退出码:0 = 通过;1 = 硬失败(缺许可证文件 / commit 漂移 / tarball 漂移 / 主仓不可达)。 set -u cd "$(dirname "$0")/.." # 切到 reader_app 根(build_reader.sh/NOTICE/mpk 都在此) SKIP_NET=0 [ "${1:-}" = "--skip-net" ] && SKIP_NET=1 MPK="os.meow.reader.mpk" NOTICE="NOTICE" BUILD="build_reader.sh" LIC="resources/licenses" MAIN_REPO="https://git.yeij.top/AskaEth/MeowOS-For-R3P2.git" fail=0 say() { printf '%s\n' "$*"; } hard() { printf 'FAIL %s\n' "$*"; fail=1; } ok() { printf 'ok %s\n' "$*"; } warn() { printf 'warn %s\n' "$*"; } say "== 合规校验(reader_app) ==" # ---------- 1) 包内许可证文件 ---------- if [ ! -f "$MPK" ]; then hard "找不到 $MPK —— 请先 ./build_reader.sh 再 ./pack_reader_mpk.sh" else for f in NOTICE GPL-3.0.txt LGPL-3.0.txt FTL.txt; do if tar tzf "$MPK" 2>/dev/null | grep -qx "resources/licenses/$f"; then ok "包内含 resources/licenses/$f" else hard "包内缺 resources/licenses/$f" fi done fi # ---------- 2) libmobi 锁定 commit 一致性 ---------- LM_URL="$(sed -n 's/^LM_URL="\([^"]*\)"/\1/p' "$BUILD" | head -1)" LM_COMMIT="$(printf '%s' "$LM_URL" | sed 's#.*/##')" NOTICE_COMMIT="$(sed -n 's/^[[:space:]]*\([0-9a-f]\{40\}\).*/\1/p' "$NOTICE" | head -1)" if [ -z "$LM_COMMIT" ]; then hard "build_reader.sh 未解析到 LM_URL 锁定 commit" elif [ "$LM_COMMIT" != "$NOTICE_COMMIT" ]; then hard "libmobi 锁定 commit 漂移:build=$LM_COMMIT NOTICE=$NOTICE_COMMIT" else ok "libmobi 锁定 commit 一致 ($LM_COMMIT)" fi # ---------- 3) [联网] tarball sha256 ---------- NOTICE_SHA="$(sed -n 's/^[[:space:]]*Tarball sha256[^:]*:[[:space:]]*\([0-9a-f]\{64\}\).*/\1/p' "$NOTICE" | head -1)" LIVE_SHA="" if [ "$SKIP_NET" = 1 ]; then warn "跳过在线 tarball 校验 (--skip-net)" if [ -n "$NOTICE_SHA" ]; then ok "NOTICE 已记录 tarball sha256 ($NOTICE_SHA)"; else warn "NOTICE 未记录 tarball sha256(P1 补强项)"; fi else if command -v curl >/dev/null 2>&1 && command -v sha256sum >/dev/null 2>&1 && [ -n "$LM_URL" ]; then LIVE_SHA="$(curl -fsSL "$LM_URL" 2>/dev/null | sha256sum | awk '{print $1}')" if [ -z "$LIVE_SHA" ]; then warn "在线取 tarball 失败(网络不可用)—— 未校验 sha256" elif [ -n "$NOTICE_SHA" ]; then if [ "$LIVE_SHA" = "$NOTICE_SHA" ]; then ok "tarball sha256 与 NOTICE 一致 ($LIVE_SHA)"; else hard "tarball sha256 漂移:live=$LIVE_SHA NOTICE=$NOTICE_SHA"; fi else say "info tarball sha256=$LIVE_SHA (NOTICE 未记录指纹,属 P1 补强项,不判失败)" fi else warn "无 curl/sha256sum 或未解析 LM_URL —— 跳过在线 tarball 校验" fi fi # ---------- 4) [联网] 主仓公开可读 ---------- if [ "$SKIP_NET" = 1 ]; then warn "跳过主仓可读性校验 (--skip-net)" else if command -v git >/dev/null 2>&1; then if git ls-remote "$MAIN_REPO" HEAD >/dev/null 2>&1; then ok "主仓公开可读 (git ls-remote HEAD)" else hard "主仓 git ls-remote 失败(LGPL §4(d) 应用源码可达性)" fi else warn "无 git —— 跳过主仓可读性校验" fi fi # ---------- 5) 合规清单 ---------- say "== 合规清单 ==" say "libmobi commit : ${LM_COMMIT:-?}" say "libmobi tarball : ${LIVE_SHA:-${NOTICE_SHA:-未校验}}" say "包内许可证 :" if [ -f "$MPK" ]; then tar tzf "$MPK" 2>/dev/null | grep 'resources/licenses/' || true; fi if [ "$fail" = 1 ]; then say "结果:FAIL"; exit 1; fi say "结果:PASS"