refactor: 迁移至 bashly CLI 与功能域模块结构
- CLI 定义迁移至 src/bashly.yml(bashly 1.4 生成参数解析),入口收敛为 src/root_command.sh - 源码按功能域重组:config/storage/integrate/media/pipeline,消除扁平散落 - 新增零依赖测试框架 tests/(123 用例)与 CI 流水线(lint + test + build + 产物一致性) - build.sh 支持版本单一来源注入与 --check 产物校验;新增 lint.sh(bash -n + shellcheck 零容忍) - 删除旧单文件 media_organizer.sh 与旧扁平模块
This commit is contained in:
1 parent
d978a13a83
commit
0df07ad0ae
48 files changed
+5813
-6812
No files matched your search
@@ -1,106 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================================
|
||||
# 构建脚本:将 src/ 下的模块拼接为单个自包含分发脚本 media_organizer.sh
|
||||
# 构建脚本:bashly generate → 单文件分发脚本 dist/media_organizer
|
||||
#
|
||||
# 用法:
|
||||
# ./build.sh 构建 media_organizer.sh(覆盖根目录文件)
|
||||
# ./build.sh --check 仅校验根目录 media_organizer.sh 是否与最新源码一致
|
||||
# ./build.sh 构建(bashly generate + 语法/重复函数检查)
|
||||
# ./build.sh --check 仅校验当前 dist/media_organizer 是否与 src/ 最新源码一致
|
||||
#
|
||||
# 模块清单(顺序 = 依赖顺序,不可随意调整):
|
||||
# src/main.sh 文件头注释 + 常量 + 全局变量
|
||||
# src/lib/log.sh 日志与色彩(最先加载,保证全脚本日志输出一致)
|
||||
# src/lib/config.sh 配置加载与认证
|
||||
# src/lib/maps.sh 特典映射与季偏移
|
||||
# src/lib/strings.sh 字符串工具
|
||||
# src/lib/cache.sh 缓存管理(cache_* 系列)
|
||||
# src/lib/tmdb.sh TMDB API(tmdb_api 统一缓存封装)
|
||||
# src/lib/filename.sh 媒体文件名解析
|
||||
# src/lib/registry.sh 识别登记与并发池(register_* / emit / pool_run)
|
||||
# src/lib/identify.sh 媒体识别(电影/电视剧)
|
||||
# src/lib/ai.sh AI 批处理(请求构造/调用/特典学习)
|
||||
# src/lib/link.sh 硬链接基础工具(inode 判断/链接/错误处理)
|
||||
# src/lib/args.sh 帮助与参数解析
|
||||
# src/lib/process.sh 目录校验/扫描/识别流水线
|
||||
# src/lib/ai_resolve.sh AI 结果消费(重搜/匹配/回退命名)
|
||||
# src/lib/link_media.sh 创建硬链接及伴随文件
|
||||
# src/lib/report.sh 对照表导出与运行汇总
|
||||
# src/lib/entry.sh main() 唯一入口(文件末尾调用)
|
||||
# 版本单一来源:src/lib/main.sh 的 SCRIPT_VERSION 是唯一权威版本号,
|
||||
# 构建时注入 bashly.yml 的 version 字段(产物 --version 与脚本内版本一致)。
|
||||
#
|
||||
# 依赖:bashly(gem install bashly;开发期工具,产物运行无需 Ruby)
|
||||
# ============================================================================
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
OUT="media_organizer.sh"
|
||||
OUT="dist/media_organizer"
|
||||
BASE="$(pwd)"
|
||||
|
||||
MODULES=(
|
||||
src/main.sh
|
||||
src/lib/log.sh
|
||||
src/lib/config.sh
|
||||
src/lib/maps.sh
|
||||
src/lib/strings.sh
|
||||
src/lib/cache.sh
|
||||
src/lib/tmdb.sh
|
||||
src/lib/filename.sh
|
||||
src/lib/registry.sh
|
||||
src/lib/identify.sh
|
||||
src/lib/ai.sh
|
||||
src/lib/link.sh
|
||||
src/lib/args.sh
|
||||
src/lib/process.sh
|
||||
src/lib/ai_resolve.sh
|
||||
src/lib/link_media.sh
|
||||
src/lib/report.sh
|
||||
src/lib/entry.sh
|
||||
)
|
||||
|
||||
# 预检:所有模块存在
|
||||
for m in "${MODULES[@]}"; do
|
||||
if [[ ! -f "$m" ]]; then
|
||||
echo "错误:缺失模块 $m(请先拆分源码或检查模块清单)" >&2
|
||||
exit 1
|
||||
# 定位 bashly:环境变量 BASHLY 覆盖 > PATH > 本仓库 .rv-rubies(rv 管理的 Ruby)
|
||||
find_bashly() {
|
||||
if [[ -n "${BASHLY:-}" ]] && [[ -x "$BASHLY" ]]; then
|
||||
echo "$BASHLY"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
tmp="$(mktemp)"
|
||||
trap 'rm -f "$tmp"' EXIT
|
||||
|
||||
# 生成:shebang + 生成说明 + 按序拼接全部模块
|
||||
{
|
||||
printf '#!/bin/bash\n'
|
||||
printf '%s\n' \
|
||||
'################################################################################' \
|
||||
'# 本文件由 build.sh 从 src/ 自动生成,请勿直接编辑。' \
|
||||
'# 修改源码请编辑 src/ 下的模块文件(模块清单见 build.sh),然后运行 ./build.sh。' \
|
||||
'################################################################################'
|
||||
printf '\n'
|
||||
for m in "${MODULES[@]}"; do
|
||||
cat "$m"
|
||||
if command -v bashly >/dev/null 2>&1; then
|
||||
command -v bashly
|
||||
return 0
|
||||
fi
|
||||
local d
|
||||
for d in "$BASE"/.rv-rubies/*/bin/bashly; do
|
||||
[[ -x "$d" ]] && {
|
||||
echo "$d"
|
||||
return 0
|
||||
}
|
||||
done
|
||||
} >"$tmp"
|
||||
return 1
|
||||
}
|
||||
|
||||
if ! BASHLY_CMD="$(find_bashly)"; then
|
||||
echo "错误:未找到 bashly(gem install bashly,或设 BASHLY=/path/to/bashly)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 版本单一来源:从 main.sh 提取 SCRIPT_VERSION
|
||||
VERSION="$(sed -n 's/^readonly SCRIPT_VERSION="\([^"]*\)"/\1/p' src/lib/main.sh | head -1)"
|
||||
if [[ -z "$VERSION" ]]; then
|
||||
echo "错误:无法从 src/lib/main.sh 提取 SCRIPT_VERSION" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 在临时目录生成(注入版本号,不触碰工作区源码)
|
||||
work="$(mktemp -d)"
|
||||
trap 'rm -rf "$work"' EXIT
|
||||
cp -r src "$work/src"
|
||||
sed -i "s/^version: .*/version: $VERSION/" "$work/src/bashly.yml"
|
||||
(cd "$work" && "$BASHLY_CMD" generate --quiet >/dev/null)
|
||||
generated="$work/media_organizer"
|
||||
|
||||
# 语法检查
|
||||
if ! bash -n "$tmp"; then
|
||||
if ! bash -n "$generated"; then
|
||||
echo "错误:构建产物语法检查未通过" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 重复函数定义检查(防止模块合并后命名冲突)
|
||||
dups="$(grep -oE '^[A-Za-z_][A-Za-z0-9_]*\(\) \{' "$tmp" | sort | uniq -d || true)"
|
||||
# 重复函数定义检查
|
||||
dups="$(grep -oE '^[A-Za-z_][A-Za-z0-9_]*\(\) \{' "$generated" | sort | uniq -d || true)"
|
||||
if [[ -n "$dups" ]]; then
|
||||
echo "错误:存在重复函数定义:$dups" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--check" ]]; then
|
||||
if cmp -s "$tmp" "$OUT"; then
|
||||
echo "OK:$OUT 与最新源码一致"
|
||||
if [[ -f "$OUT" ]] && cmp -s "$generated" "$OUT"; then
|
||||
echo "OK:$OUT 与最新源码一致(v$VERSION)"
|
||||
else
|
||||
echo "DIFF:$OUT 已过期,请运行 ./build.sh 重新生成" >&2
|
||||
diff "$OUT" "$tmp" | head -50 >&2 || true
|
||||
echo "DIFF:$OUT 已过期或不存在,请运行 ./build.sh 重新生成" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
chmod +x "$tmp"
|
||||
mv "$tmp" "$OUT"
|
||||
mkdir -p "$(dirname "$OUT")"
|
||||
chmod +x "$generated"
|
||||
mv "$generated" "$OUT"
|
||||
trap - EXIT
|
||||
echo "构建完成:$OUT($(wc -l <"$OUT") 行,$(wc -c <"$OUT") 字节)"
|
||||
echo "构建完成:$OUT v$VERSION($(wc -l <"$OUT") 行,$(wc -c <"$OUT") 字节)"
|
||||
fi
|
||||
Reference in new issue
Block a user