#!/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 ""