185 lines
5.8 KiB
Bash
185 lines
5.8 KiB
Bash
#!/bin/bash
|
||
|
||
# 只更新 @DriftDatabase(tables: [...]), imports 和 getTableRegistry
|
||
# 其余内容保持不变
|
||
|
||
APP_DATABASE="apps/im_app/lib/data/local/drift/app_database.dart"
|
||
|
||
# ── 扫描表类 ────────────────────────────────────────────────────────────────
|
||
TABLE_CLASSES=()
|
||
DATA_CLASSES=()
|
||
GETTERS=()
|
||
IMPORTS=()
|
||
|
||
# 项目根目录(脚本所在目录的上一层)
|
||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||
|
||
# app_database.dart 所在目录(用于计算相对 import 路径)
|
||
APP_DATABASE_DIR="$(dirname "$ROOT_DIR/$APP_DATABASE")"
|
||
|
||
echo "🔍 扫描所有包中的 drift 表文件..."
|
||
echo " 根目录: $ROOT_DIR"
|
||
echo " app_database 目录: $APP_DATABASE_DIR"
|
||
|
||
# 搜索所有包中的 lib/data/local/drift/tables 目录下的 dart 文件
|
||
while IFS= read -r FILE; do
|
||
echo " 📄 $FILE"
|
||
|
||
# 提取继承 Table 或 View 的类名
|
||
while IFS= read -r LINE; do
|
||
CLASS=$(echo "$LINE" | sed -E "s/.*class ([A-Za-z0-9]+) extends (Table|View).*/\1/")
|
||
|
||
if [ -z "$CLASS" ]; then
|
||
continue
|
||
fi
|
||
|
||
TABLE_CLASSES+=("$CLASS")
|
||
|
||
# 提取 @DataClassName 注解
|
||
DATA_CLASS=$(grep -E "@DataClassName\('([^']+)'\)" "$FILE" | sed -E "s/.*@DataClassName\('([^']+)'\).*/\1/" | head -1)
|
||
|
||
if [ -z "$DATA_CLASS" ]; then
|
||
# 无注解时去掉末尾 's' 推断数据类名
|
||
DATA_CLASS="${CLASS%s}"
|
||
fi
|
||
|
||
DATA_CLASSES+=("$DATA_CLASS")
|
||
|
||
# getter 名 = 表类名首字母小写(跟 drift 生成一致)
|
||
GETTER=$(echo "$CLASS" | awk '{print tolower(substr($0,1,1)) substr($0,2)}')
|
||
GETTERS+=("$GETTER")
|
||
|
||
# 计算 package: import 路径(找到 pubspec.yaml 确定 package 名)
|
||
PKG_IMPORT=$(python3 -c "
|
||
import os, re
|
||
|
||
file_path = '$FILE'
|
||
search = os.path.dirname(file_path)
|
||
pkg_name = None
|
||
pkg_root = None
|
||
|
||
while search != '/':
|
||
pubspec = os.path.join(search, 'pubspec.yaml')
|
||
if os.path.exists(pubspec):
|
||
with open(pubspec) as f:
|
||
for line in f:
|
||
m = re.match(r'^name:\s*(\S+)', line)
|
||
if m:
|
||
pkg_name = m.group(1)
|
||
pkg_root = search
|
||
break
|
||
break
|
||
search = os.path.dirname(search)
|
||
|
||
if pkg_name and pkg_root:
|
||
lib_path = os.path.join(pkg_root, 'lib')
|
||
rel = os.path.relpath(file_path, lib_path)
|
||
print(f'package:{pkg_name}/{rel}')
|
||
else:
|
||
db_dir = '$APP_DATABASE_DIR'
|
||
print(os.path.relpath(file_path, db_dir))
|
||
")
|
||
IMPORTS+=("$PKG_IMPORT")
|
||
|
||
echo " ✅ 表类: $CLASS → 数据类: $DATA_CLASS → getter: $GETTER"
|
||
echo " 📦 import: $PKG_IMPORT"
|
||
|
||
done < <(grep -E "^class [A-Za-z0-9]+ extends (Table|View)" "$FILE")
|
||
|
||
done < <(find "$ROOT_DIR" \
|
||
-type f \
|
||
-name "*.dart" \
|
||
-path "*/lib/data/local/drift/tables/*" \
|
||
! -path "*/build/*" \
|
||
! -path "*/.dart_tool/*" \
|
||
! -path "*/.*")
|
||
|
||
if [ ${#TABLE_CLASSES[@]} -eq 0 ]; then
|
||
echo "❌ 未找到任何 drift 表类,请检查搜索路径。"
|
||
exit 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "✅ 共找到 ${#TABLE_CLASSES[@]} 个表类:"
|
||
for i in "${!TABLE_CLASSES[@]}"; do
|
||
echo " [${TABLE_CLASSES[$i]}] → [${DATA_CLASSES[$i]}] → getter: ${GETTERS[$i]} → ${IMPORTS[$i]}"
|
||
done
|
||
|
||
TABLES_LIST=$(IFS=', '; echo "${TABLE_CLASSES[*]}")
|
||
echo ""
|
||
echo "📋 @DriftDatabase(tables: [$TABLES_LIST])"
|
||
|
||
# ── 用 sed 替换 @DriftDatabase(tables: [...]) ──────────────────────────────
|
||
echo ""
|
||
echo "✍️ 更新 @DriftDatabase..."
|
||
sed -i '' "s/@DriftDatabase(tables: \[.*\])/@DriftDatabase(tables: [$TABLES_LIST])/" "$ROOT_DIR/$APP_DATABASE"
|
||
echo "✅ @DriftDatabase 已更新"
|
||
|
||
# ── 生成 import 块和 registry ─────────────────────────────────────────────
|
||
IMPORT_BLOCK=""
|
||
for IMPORT_PATH in "${IMPORTS[@]}"; do
|
||
IMPORT_BLOCK+="import '$IMPORT_PATH';\n"
|
||
done
|
||
|
||
REGISTRY=""
|
||
for i in "${!TABLE_CLASSES[@]}"; do
|
||
DATA="${DATA_CLASSES[$i]}"
|
||
GETTER="${GETTERS[$i]}"
|
||
REGISTRY+=" $DATA: database.$GETTER,\n"
|
||
echo " 注册: $DATA → database.$GETTER"
|
||
done
|
||
|
||
echo ""
|
||
echo "✍️ 更新 imports + getTableRegistry..."
|
||
|
||
python3 - "$ROOT_DIR/$APP_DATABASE" "$REGISTRY" "$IMPORT_BLOCK" << 'PYEOF'
|
||
import sys, re
|
||
|
||
file_path = sys.argv[1]
|
||
registry = sys.argv[2].replace('\\n', '\n')
|
||
imports = sys.argv[3].replace('\\n', '\n')
|
||
|
||
with open(file_path, 'r') as f:
|
||
content = f.read()
|
||
|
||
# 替换 import 块(保留 drift import,替换其余 table imports)
|
||
new_content = re.sub(
|
||
r"(import 'package:drift/drift\.dart';\n)(?:import '[^']+\';\n)*",
|
||
"import 'package:drift/drift.dart';\n" + imports,
|
||
content
|
||
)
|
||
|
||
# 替换 getTableRegistry 里的第二个 return { 块(不依赖注释)
|
||
parts = new_content.split('getTableRegistry', 1)
|
||
if len(parts) == 2:
|
||
after = parts[1]
|
||
# 跳过第一个 return {}(is! AppDatabase 那个),替换第二个
|
||
count = [0]
|
||
def replace_second(m):
|
||
count[0] += 1
|
||
if count[0] == 2:
|
||
return m.group(1) + '\n' + registry + ' ' + m.group(2)
|
||
return m.group(0)
|
||
new_after = re.sub(
|
||
r'(return \{)(.*?)(\};)',
|
||
lambda m: replace_second(re.match(r'(return \{)(.*?)(\};)', m.group(0), re.DOTALL)),
|
||
after,
|
||
flags=re.DOTALL
|
||
)
|
||
# 用更简单直接的方式:找到所有 return { 块,替换第二个
|
||
matches = list(re.finditer(r'return \{.*?\};', after, re.DOTALL))
|
||
if len(matches) >= 2:
|
||
m = matches[1]
|
||
new_after = after[:m.start()] + 'return {\n' + registry + ' };' + after[m.end():]
|
||
new_content = parts[0] + 'getTableRegistry' + new_after
|
||
|
||
with open(file_path, 'w') as f:
|
||
f.write(new_content)
|
||
|
||
print("✅ imports + getTableRegistry 已更新")
|
||
PYEOF
|
||
|
||
echo ""
|
||
echo "🎉 完成!下一步运行:"
|
||
echo " melos run gen"
|