posimai-root/scripts/check-design.sh

157 lines
7.1 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
# Posimai — Design Rules Checker
# デプロイ前に実行して禁止パターンの混入を検出する
# 使い方: bash scripts/check-design.sh [対象ディレクトリ]
# 例: bash scripts/check-design.sh posimai-habit
# bash scripts/check-design.sh ← 全 HTML アプリを対象
# =============================================================================
TARGET="${1:-.}"
ERRORS=0
WARNINGS=0
RED='\033[0;31m'
YLW='\033[0;33m'
GRN='\033[0;32m'
DIM='\033[2m'
NC='\033[0m'
err() { echo -e "${RED}[ERR]${NC} $1"; ((ERRORS++)); }
warn() { echo -e "${YLW}[WARN]${NC} $1"; ((WARNINGS++)); }
ok() { echo -e "${GRN}[OK]${NC} $1"; }
echo ""
echo " Posimai Design Rules Checker"
echo " Target: ${TARGET}"
echo " ────────────────────────────────────────"
echo ""
# ── 1. 絵文字の混入 ──────────────────────────────────────────────────────────
echo "1. 絵文字チェック"
EMOJI_HITS=$(grep -rn --include="*.html" --include="*.tsx" --include="*.ts" --include="*.js" \
-P '[\x{1F300}-\x{1F9FF}]|[\x{2600}-\x{27BF}]|✅|📱|⚙️|🎉|🚀|❌|⚠️|💡|🔧|📦|🎨' \
"${TARGET}" 2>/dev/null | grep -v ".git/" | grep -v "node_modules/")
if [ -n "$EMOJI_HITS" ]; then
err "絵文字が検出されました"
echo "$EMOJI_HITS" | while read -r line; do echo -e " ${DIM}${line}${NC}"; done
else
ok "絵文字なし"
fi
echo ""
# ── 2. @latest バージョン未固定 ─────────────────────────────────────────────
echo "2. CDN バージョン固定チェック (@latest)"
LATEST_HITS=$(grep -rn --include="*.html" --include="*.tsx" --include="*.ts" \
"@latest" "${TARGET}" 2>/dev/null | grep -v ".git/" | grep -v "node_modules/")
if [ -n "$LATEST_HITS" ]; then
err "@latest が検出されました — バージョンを固定してください"
echo "$LATEST_HITS" | while read -r line; do echo -e " ${DIM}${line}${NC}"; done
else
ok "@latest なし"
fi
echo ""
# ── 3. manifest.json 参照の確認 ──────────────────────────────────────────────
echo "3. manifest.json 参照チェック"
HTML_FILES=$(find "${TARGET}" -name "index.html" -not -path "*/.git/*" -not -path "*/node_modules/*" 2>/dev/null)
MISSING_MANIFEST=""
for f in $HTML_FILES; do
if ! grep -q "manifest.json" "$f"; then
MISSING_MANIFEST="${MISSING_MANIFEST}\n ${f}"
fi
done
if [ -n "$MISSING_MANIFEST" ]; then
err "manifest.json 参照がない index.html:${MISSING_MANIFEST}"
else
[ -n "$HTML_FILES" ] && ok "全 index.html に manifest.json あり"
fi
echo ""
# ── 4. sw.js 参照の確認 ──────────────────────────────────────────────────────
echo "4. sw.js 参照チェック"
MISSING_SW=""
for f in $HTML_FILES; do
if ! grep -q "sw.js" "$f"; then
MISSING_SW="${MISSING_SW}\n ${f}"
fi
done
if [ -n "$MISSING_SW" ]; then
err "sw.js 参照がない index.html:${MISSING_SW}"
else
[ -n "$HTML_FILES" ] && ok "全 index.html に sw.js あり"
fi
echo ""
# ── 5. theme-color メディアクエリ欠落チェック ────────────────────────────────
echo "5. theme-color メディアクエリチェック"
MISSING_MQ=""
for f in $HTML_FILES; do
# theme-color はあるがメディアクエリがない行を検出
if grep -q 'name="theme-color"' "$f"; then
if grep -P 'name="theme-color"' "$f" | grep -qv 'media='; then
MISSING_MQ="${MISSING_MQ}\n ${f}"
fi
fi
done
if [ -n "$MISSING_MQ" ]; then
err "theme-color にメディアクエリがありません:${MISSING_MQ}"
else
[ -n "$HTML_FILES" ] && ok "theme-color メディアクエリ OK"
fi
echo ""
# ── 6. アクセントカラー直書きチェック ───────────────────────────────────────
echo "6. アクセントカラー直書きチェック"
HARDCODED_HITS=$(grep -rn --include="*.html" --include="*.css" \
-E '(color|background|border|box-shadow|fill|stroke)\s*:\s*(#6EE7B7|#059669|#80CAEE|#0284C7)' \
"${TARGET}" 2>/dev/null | grep -v ".git/" | grep -v "node_modules/" | \
# CLAUDE.md や定義部分 (:root, CSS変数定義) は除外
grep -v "var(--" | grep -v ":root")
if [ -n "$HARDCODED_HITS" ]; then
warn "アクセントカラーが CSS 変数ではなく直書きされています (var(--accent) 推奨)"
echo "$HARDCODED_HITS" | while read -r line; do echo -e " ${DIM}${line}${NC}"; done
else
ok "アクセントカラー直書きなし"
fi
echo ""
# ── 7. rel="noopener" チェック ────────────────────────────────────────────────
echo "7. rel=noopener チェック (target=_blank)"
NOOP_HITS=$(grep -rn --include="*.html" --include="*.tsx" --include="*.ts" \
'target="_blank"' "${TARGET}" 2>/dev/null | \
grep -v 'rel=.*noopener' | grep -v ".git/" | grep -v "node_modules/")
if [ -n "$NOOP_HITS" ]; then
warn 'target="_blank" に rel="noopener" がありません'
echo "$NOOP_HITS" | while read -r line; do echo -e " ${DIM}${line}${NC}"; done
else
ok 'rel="noopener" OK'
fi
echo ""
# ── 8. lucide@0.344.0 以外のバージョン ──────────────────────────────────────
echo "8. Lucide バージョンチェック"
LUCIDE_WRONG=$(grep -rn --include="*.html" \
"lucide@" "${TARGET}" 2>/dev/null | \
grep -v "lucide@0.344.0" | grep -v ".git/" | grep -v "node_modules/")
if [ -n "$LUCIDE_WRONG" ]; then
err "lucide@0.344.0 以外のバージョンが検出されました"
echo "$LUCIDE_WRONG" | while read -r line; do echo -e " ${DIM}${line}${NC}"; done
else
ok "Lucide バージョン OK"
fi
echo ""
# ── 結果サマリ ────────────────────────────────────────────────────────────────
echo " ────────────────────────────────────────"
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
echo -e " ${GRN}すべてのチェックをパスしました。${NC}"
elif [ $ERRORS -eq 0 ]; then
echo -e " ${YLW}警告 ${WARNINGS} 件(エラーなし)。確認してからデプロイしてください。${NC}"
else
echo -e " ${RED}エラー ${ERRORS} 件 / 警告 ${WARNINGS} 件。デプロイ前に修正してください。${NC}"
echo ""
exit 1
fi
echo ""