Files
lsky-pro-docker/tools/diff-vs-upstream.sh
T
mole404 8137ee1e04 fix(install): 安装向导默认数据库类型改为 SQLite;README 挂载路径改用 $PWD
两件事:
1) 安装向导(src/resources/views/install.blade.php)
   · 数据库类型的选项顺序:SQLite 提到第一个(= 浏览器默认选中),MySQL/PostgreSQL/SQL Server 保持原序。
     镜像自带 pdo_sqlite,开箱即用;README 第 55 行本来就写着「默认 SQLite」,这次把代码对齐文档。
   · 页面加载时主动触发一次 change:那个 change 处理器同时负责「按类型显示/隐藏连接字段」,
     不触发的话默认选中的 SQLite 旁边还挂着 MySQL 那套字段(127.0.0.1 / 3306 / root)与端口,
     看着像选错了,SQLite 的说明文字也不会出现。
   · tools/diff-vs-upstream.sh 的 KNOWN_DEVIATIONS 里该文件的理由补上这一条(文件本来就在清单里)。

2) README(只改文档,不动任何 compose 文件)
   · 挂载卷路径 /root/lsky-pro/data → $PWD/data(compose 片段)与 "$PWD/data:/var/www/html"(docker run 片段);
     仓库自带的 docker-compose.yaml 本来就用 $PWD/web 这套写法,风格统一。
   · 补一句提醒:compose 文件里别写 ~(不经过 shell 不会展开)。
2026-10-02 19:18:56 +08:00

348 lines
18 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# 用途:把本仓库 src/ 与上游官方快照做**全树对比**,回答两个问题:
# 1) 我们相对上游到底改了哪几个文件、改了什么(默认就打印这个)
# 2) src/ 里有没有「手滑改动」—— 只要出现**已知偏离清单**之外的文件与上游不同就报警
#
# 依赖:git(需要能访问 github.com;上游已停更,平时不需要跑这个脚本)
# 用法:bash tools/diff-vs-upstream.sh [commit] # 默认用 Dockerfile 里的 LSKY_COMMIT
#
# 维护:有意改了 src/ 里的上游文件后,把该文件登记进下面的 KNOWN_DEVIATIONS(附一句理由),
# 否则脚本会把它当成「手滑改动」而 exit 1。反过来说:只要它不报错,src/ 相对上游
# 的改动就**恰好**是清单里这些 —— 这也正是 CI / 人工复核想看到的不变量。
# ---------------------------------------------------------------------------
set -euo pipefail
cd "$(dirname "$0")/.."
COMMIT="${1:-$(grep -oE '^ARG LSKY_COMMIT=[0-9a-f]+' Dockerfile | cut -d= -f2)}"
if [ -z "$COMMIT" ]; then
echo "用法:bash tools/diff-vs-upstream.sh <上游 commit>" >&2
exit 2
fi
# ===========================================================================
# 已知偏离清单(KNOWN DEVIATIONS)—— 本 fork **有意**相对上游修改的上游文件。
# 判据:diff 出来的「内容不同」清单必须**恰好**落在下面这些行内(顺序无关)。
# 不在清单里的文件一旦与上游不同 = 手滑改动 / 未登记的改动 → 报警 + exit 1。
#
# 每行是 `src/<路径>`;它上方最近的 `# [n ...]` 注释就是「这个文件为什么偏离上游」的理由。
# 新增/删除条目时「理由」必须跟着改 —— 这份清单本身就是「我们和上游差在哪」的权威记录。
#
# 注意:这里只登记「内容不同」(两边都存在、内容不一样)的文件。
# “只在一边存在”(我们新增的 theme.js / public/static 等、上游有而我们删掉的
# Gallery/Upgrade 文件)只做信息展示,不参与报警 —— src/ 里还混着 node_modules /
# vendor / storage 这类构建或运行期产物,用「新增文件」报警会全是噪音。
# ===========================================================================
KNOWN_RAW=$(cat <<'EOF'
# [1 补丁产物:iOS Safari 长按弹菜单 + 菜单交互修复]
# src/resources/js/context-js.js
src/resources/js/context-js.js
# src/public/js/context-js/context-js.js
src/public/js/context-js/context-js.js
# src/resources/views/user/images.blade.php
src/resources/views/user/images.blade.php
# # (两份 JS 内容必须逐字节一致;blade 只改了引入脚本那一行的资源版本串。完整 diff:patches/ios-longpress.patch)
# (两份 JS 内容必须逐字节一致;blade 只改了引入脚本那一行的资源版本串。完整 diff:patches/ios-longpress.patch)
# [2 功能移除:画廊(Gallery)与系统升级;登录态访问首页改跳「我的图片」]
# src/app/Enums/ConfigKey.php
src/app/Enums/ConfigKey.php
# src/app/Http/Controllers/Admin/SettingController.php
src/app/Http/Controllers/Admin/SettingController.php
# src/config/app.php
src/config/app.php
# src/config/convention.php
src/config/convention.php
# src/routes/web.php
src/routes/web.php
# src/resources/views/admin/setting/index.blade.php
src/resources/views/admin/setting/index.blade.php
# [3 安全:彻底移除 SVG 上传(读取侧硬过滤 + 只可能因 svg 命中的死代码清理)]
# src/app/Http/Controllers/Controller.php
src/app/Http/Controllers/Controller.php
# src/app/Http/Requests/Admin/GroupRequest.php
src/app/Http/Requests/Admin/GroupRequest.php
# src/app/Models/Group.php
src/app/Models/Group.php
# src/app/Models/Image.php
src/app/Models/Image.php
# src/app/Services/ImageService.php
src/app/Services/ImageService.php
# [4 依赖安全升级:composer.lock 升到同大版本线内的安全版本
# (laravel/framework 9.52.22、symfony/* 6.4 LTS、guzzle、phpseclib、commonmark 等一批 CVE 修复)]
# src/composer.lock
src/composer.lock
# [5 前端源码:全站前端换新(清爽极简 + 亮/暗/跟随系统)及后续 UI/交互迭代
# (菜单/弹窗/侧栏/图片页…;app/Utils.php 是配套加的「资源版本串 / 本地默认头像」助手方法)]
# src/app/Utils.php
src/app/Utils.php
# src/package.json
src/package.json
# src/package-lock.json(前端依赖升级:sweetalert2 11.4.6 → 11.22.4,修掉它的 3 条 npm 公告
# —— 见 osv-scanner.toml「test/package-lock.json 侧」;锁里只有 sweetalert2 一处
# version/resolved/integrity/赞助链接变化,其余与上游锁逐字节一致)
src/package-lock.json
# src/resources/css/app.css
src/resources/css/app.css
# src/resources/css/common.less
src/resources/css/common.less
# src/resources/css/context-js.less
src/resources/css/context-js.less
# src/resources/css/gallery.less
src/resources/css/gallery.less
# src/resources/js/app.js
src/resources/js/app.js
# src/resources/js/stores/sidebar.js
src/resources/js/stores/sidebar.js
# src/resources/views/admin/console/index.blade.php
src/resources/views/admin/console/index.blade.php
# src/resources/views/admin/group/add.blade.php
src/resources/views/admin/group/add.blade.php
# src/resources/views/admin/group/edit.blade.php
src/resources/views/admin/group/edit.blade.php
# src/resources/views/admin/group/index.blade.php
src/resources/views/admin/group/index.blade.php
# src/resources/views/admin/group/rules.blade.php
src/resources/views/admin/group/rules.blade.php
# src/resources/views/admin/image/index.blade.php
src/resources/views/admin/image/index.blade.php
# src/resources/views/admin/strategy/add.blade.php
src/resources/views/admin/strategy/add.blade.php
# src/resources/views/admin/strategy/edit.blade.php
src/resources/views/admin/strategy/edit.blade.php
# src/resources/views/admin/strategy/index.blade.php
src/resources/views/admin/strategy/index.blade.php
# src/resources/views/admin/strategy/tips.blade.php
src/resources/views/admin/strategy/tips.blade.php
# src/resources/views/admin/user/edit.blade.php
src/resources/views/admin/user/edit.blade.php
# src/resources/views/admin/user/index.blade.php
src/resources/views/admin/user/index.blade.php
# src/resources/views/auth/confirm-password.blade.php
src/resources/views/auth/confirm-password.blade.php
# src/resources/views/auth/forgot-password.blade.php
src/resources/views/auth/forgot-password.blade.php
# src/resources/views/auth/login.blade.php
src/resources/views/auth/login.blade.php
# src/resources/views/auth/register.blade.php
src/resources/views/auth/register.blade.php
# src/resources/views/auth/reset-password.blade.php
src/resources/views/auth/reset-password.blade.php
# src/resources/views/auth/verify-email.blade.php
src/resources/views/auth/verify-email.blade.php
# src/resources/views/common/api.blade.php
src/resources/views/common/api.blade.php
# src/resources/views/components/auth-card.blade.php
src/resources/views/components/auth-card.blade.php
# src/resources/views/components/auth-validation-errors.blade.php
src/resources/views/components/auth-validation-errors.blade.php
# src/resources/views/components/box.blade.php
src/resources/views/components/box.blade.php
# src/resources/views/components/button.blade.php
src/resources/views/components/button.blade.php
# src/resources/views/components/code.blade.php
src/resources/views/components/code.blade.php
# src/resources/views/components/container.blade.php
src/resources/views/components/container.blade.php
# src/resources/views/components/default-avatar.blade.php
src/resources/views/components/default-avatar.blade.php
# src/resources/views/components/dropdown-link.blade.php
src/resources/views/components/dropdown-link.blade.php
# src/resources/views/components/dropdown.blade.php
src/resources/views/components/dropdown.blade.php
# src/resources/views/components/fieldset-checkbox.blade.php
src/resources/views/components/fieldset-checkbox.blade.php
# src/resources/views/components/fieldset-radio.blade.php
src/resources/views/components/fieldset-radio.blade.php
# src/resources/views/components/fieldset.blade.php
src/resources/views/components/fieldset.blade.php
# src/resources/views/components/input.blade.php
src/resources/views/components/input.blade.php
# src/resources/views/components/label.blade.php
src/resources/views/components/label.blade.php
# src/resources/views/components/loading-spin.blade.php
src/resources/views/components/loading-spin.blade.php
# src/resources/views/components/modal.blade.php
src/resources/views/components/modal.blade.php
# src/resources/views/components/nav-link.blade.php
src/resources/views/components/nav-link.blade.php
# src/resources/views/components/no-data.blade.php
src/resources/views/components/no-data.blade.php
# src/resources/views/components/select.blade.php
src/resources/views/components/select.blade.php
# src/resources/views/components/table.blade.php
src/resources/views/components/table.blade.php
# src/resources/views/components/textarea.blade.php
src/resources/views/components/textarea.blade.php
# src/resources/views/components/upload.blade.php
src/resources/views/components/upload.blade.php
# src/resources/views/install.blade.php(安装向导:默认数据库类型改成 SQLite + 加载时联动一次;成功页加本 fork 仓库链接)
src/resources/views/install.blade.php
# src/resources/views/layouts/app.blade.php
src/resources/views/layouts/app.blade.php
# src/resources/views/layouts/guest.blade.php
src/resources/views/layouts/guest.blade.php
# src/resources/views/layouts/header.blade.php
src/resources/views/layouts/header.blade.php
# src/resources/views/layouts/notice.blade.php
src/resources/views/layouts/notice.blade.php
# src/resources/views/layouts/sidebar.blade.php
src/resources/views/layouts/sidebar.blade.php
# src/resources/views/layouts/strategies.blade.php
src/resources/views/layouts/strategies.blade.php
# src/resources/views/layouts/user-nav.blade.php
src/resources/views/layouts/user-nav.blade.php
# src/resources/views/user/dashboard.blade.php
src/resources/views/user/dashboard.blade.php
# src/resources/views/user/settings.blade.php
src/resources/views/user/settings.blade.php
# src/resources/views/welcome.blade.php
src/resources/views/welcome.blade.php
# src/tailwind.config.js
src/tailwind.config.js
# src/webpack.mix.js
src/webpack.mix.js
# [6 前端构建产物:由 [5] 的源码经 webpack(npm run prod)重建得到,与上游那份旧产物逐字节不同]
# src/public/css/app.css
src/public/css/app.css
# src/public/css/common.css
src/public/css/common.css
# src/public/css/context-js/context-js.css
src/public/css/context-js/context-js.css
# src/public/css/gallery.css
src/public/css/gallery.css
# src/public/css/fontawesome.css
src/public/css/fontawesome.css
# src/public/js/app.js
src/public/js/app.js
# src/public/js/app.js.LICENSE.txt
src/public/js/app.js.LICENSE.txt
# src/public/js/blueimp-file-upload/jquery.fileupload.js
src/public/js/blueimp-file-upload/jquery.fileupload.js
# src/public/js/blueimp-load-image/load-image.all.min.js
src/public/js/blueimp-load-image/load-image.all.min.js
# src/public/js/clipboard/clipboard.min.js
src/public/js/clipboard/clipboard.min.js
# src/public/js/dragselect/ds.min.js
src/public/js/dragselect/ds.min.js
# src/public/js/echarts/echarts.min.js
src/public/js/echarts/echarts.min.js
# src/public/js/masonry/masonry.pkgd.min.js
src/public/js/masonry/masonry.pkgd.min.js
# src/public/js/viewer-js/viewer.min.js
src/public/js/viewer-js/viewer.min.js
# src/public/mix-manifest.json
src/public/mix-manifest.json
#
# [7 SQLite 并发参数(B9):连接建立时把 journal_mode 设成 WAL + 用 PDO::ATTR_TIMEOUT 设 busy_timeout,
# 避免并发读写偶发 'database is locked'。Laravel 9.52 的 sqlite 驱动不认 journal_mode/busy_timeout
# 这两个 config 键,所以 journal_mode 只能 PRAGMA(放在 AppServiceProvider)]
# src/app/Providers/AppServiceProvider.php
src/app/Providers/AppServiceProvider.php
# src/config/database.php
src/config/database.php
# [8 安全加固(F23):认证类 POST 端点加路由级节流 —— login / register / forgot-password /
# confirm-password 各加 throttle(防爆破、防同 IP 批量撒网/邮箱枚举、防邮件轰炸)。
# 应用里 Breeze 自带的 RateLimiter 只按 (邮箱|IP) 计数,挡不住换邮箱或换 IP 的批量请求]
# src/routes/auth.php
src/routes/auth.php
# [9 安全:收窄信任代理 —— TrustProxies 的 $proxies 从 '*' 改成只信任私有网段。
# 上游默认 '*' 等于信任所有转发头,而外层 nginx 用的是 $proxy_add_x_forwarded_for
# (追加而不是覆盖),客户端自己带的 X-Forwarded-For 会排在列表最前面被采信 ——
# 于是所有按 IP 限流的地方(登录失败计数、throttle 中间件)都能靠伪造一个头无限重置。
# 实测:写 '*' 时应用解析出的客户端 IP 就是伪造值;改成私有网段后解析出真实客户端,
# 且 HTTPS 判定不受影响(正常用户解析结果与改动前完全一致)。]
# src/app/Http/Middleware/TrustProxies.php
src/app/Http/Middleware/TrustProxies.php
# [10 fork 标签功能(按用户隔离的图片标签)+ 原「图片权限」界面临口下线]
# 标签:新增 tags / image_tag 两张表与 Tag 模型、Image/User 的关联、GET|POST|PUT|DELETE
# user/tags 与 PUT user/images/tags 五个端点,图片列表新增 tags[] 多值 AND 筛选;
# 界面侧原「图片权限」口径整体下线(图库页的权限按钮/筛选/详情行换成标签、
# 用户设置页不再有「图片默认权限」这一项、后台图片页与接口文档的相关行删除),
# 连带把 UserSettingRequest 里 configs.default_permission 从 required 放宽成 nullable
# (表单不再提交这一项,不放宽则「保存设置」直接 422)。permission 列与后端接口按产品决策保留。
# src/app/Http/Controllers/User/ImageController.php
src/app/Http/Controllers/User/ImageController.php
# src/app/Models/User.php
src/app/Models/User.php
# src/app/Http/Requests/UserSettingRequest.php
src/app/Http/Requests/UserSettingRequest.php
# src/app/Http/Controllers/Admin/ImageController.php
# (后台搜索的 'is:public' / 'is:private' 两条语法随「图片权限」口径下线一起删除;
# ImagePermission 的引用同时摘掉,其余搜索语法原样保留)
src/app/Http/Controllers/Admin/ImageController.php
# src/app/Services/UserService.php
# src/app/Http/Controllers/Admin/UserController.php
# (删图片 / 删用户时显式清理 image_tag 与 tags —— 本仓 SQLite 未启用 PRAGMA foreign_keys,
# 迁移注释声明的「关联行由应用代码显式删除」必须在应用层落实,否则残留行无声累积。
# 自检脚本:tools/check-tag-integrity.php)
src/app/Services/UserService.php
src/app/Http/Controllers/Admin/UserController.php
EOF
)
# 去掉注释/空行/行尾空白,得到排序后的文件清单
KNOWN="$(printf '%s\n' "$KNOWN_RAW" | sed -e 's/#.*//' -e 's/[[:space:]]*$//' -e '/^[[:space:]]*$/d' | sort)"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
echo "[1/3] 拉取上游快照 ${COMMIT:0:9} …"
git init -q "$TMP/up"
git -C "$TMP/up" remote add origin https://github.com/lsky-org/lsky-pro.git
git -C "$TMP/up" fetch -q --depth 1 origin "$COMMIT"
git -C "$TMP/up" checkout -q FETCH_HEAD
echo "[2/3] 全树对比(只列有差异的文件)…"
# 排除构建/运行期产物:它们不在上游仓库里,也不属于「源码有没有被改」的判据
diff -rq --exclude=.git --exclude=node_modules --exclude=vendor --exclude=storage \
--exclude=cache --exclude=.env "$TMP/up" src > "$TMP/raw.txt" 2>&1 || true
# 分类:内容不同 / 只在 src(我们新增)/ 只在上游(我们删了)
DIFFERS=$(grep -oE '^Files .* and src/.* differ$' "$TMP/raw.txt" | sed -E 's#^Files .* and (src/.*) differ$#\1#' | sort || true)
ONLY_SRC=$(grep -oE "^Only in src.*: .*$" "$TMP/raw.txt" | sed -E 's#^Only in (src[^:]*): (.*)$#\1/\2#' | sed 's#^\./##' | sort || true)
ONLY_UP=$(grep -oE "^Only in .*lsky-pro.*: .*$" "$TMP/raw.txt" | grep -v 'Only in src' | sed -E 's#^Only in [^:]*: (.*)$#\1#' | sort || true)
# 空字符串要变成「零行」(不能变成一行空行,否则 comm 会误判)
lines() { [ -n "${1:-}" ] && printf '%s\n' "$1" || true; }
echo
echo "=== 内容不同的文件(应恰好落在「已知偏离清单」内)==="
if [ -n "$DIFFERS" ]; then echo "$DIFFERS"; else echo "(无)"; fi
if [ -n "$ONLY_SRC" ] || [ -n "$ONLY_UP" ]; then
echo
echo "=== 只在一边存在的文件(信息展示,不参与报警)==="
[ -n "$ONLY_SRC" ] && echo "$ONLY_SRC" | sed 's/^/ 只在 src\/:/'
[ -n "$ONLY_UP" ] && echo "$ONLY_UP" | sed 's/^/ 只在上游:/'
fi
echo
echo "=== 每个文件的详细 diff ==="
for f in $DIFFERS; do
echo "---- $f"
diff -u "$TMP/up/${f#src/}" "$f" || true
done
echo
echo "[3/3] 已知偏离清单校验:"
UNEXPECTED="$(comm -23 <(lines "$DIFFERS") <(lines "$KNOWN") || true)"
STALE="$(comm -13 <(lines "$DIFFERS") <(lines "$KNOWN") || true)"
if [ -n "$UNEXPECTED" ]; then
echo " ❌ 有清单之外的改动(要么是有意的、请登记进 KNOWN_DEVIATIONS 并写一句理由,要么是手滑):"
printf '%s\n' "$UNEXPECTED" | sed 's/^/ /'
exit 1
fi
echo " ✅ src/ 相对上游的改动全部落在已知偏离清单内(清单 $(printf '%s\n' "$KNOWN" | wc -l | tr -d ' ') 项,实际不同 $(printf '%s\n' "$(lines "$DIFFERS")" | grep -c . || true) 项)"
if [ -n "$STALE" ]; then
echo " ⚠️ 清单里登记了、但实际已与上游一致(条目可清理):"
printf '%s\n' "$STALE" | sed 's/^/ /'
fi
echo
echo "提示:把上面的 diff 存进 patches/ios-longpress.patch 即可(patch 文件只是「给上下级看」的存档,不参与构建)。"