Initial import: shopdb-flask multi-site asset platform
Flask + Vue rewrite of the classic-ASP shopdb, built as a plugin framework so sister GE Aerospace sites can adopt it. Product version 0.7.0-pre-0.8.0, plugin contract 0.11.0, 966 backend tests. Key entry points: - docs/INSTALL-WINDOWS-IIS.md - tested Windows + IIS install runbook (own-site and subpath deployment methods) - docs/PILOT-DEPLOY.md - production pilot: stand up + import + verify - docs/IMPORT-API.md - schema-agnostic legacy data import contract - scripts/site_imports/wjf/ - West Jefferson reference import loader - docs/adr/ - twelve accepted architecture decision records
This commit is contained in:
118
scripts/check-naming-and-style.sh
Executable file
118
scripts/check-naming-and-style.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Pre-commit naming + style check for shopdb-flask.
|
||||
# Enforces CONTRIBUTING.md rules:
|
||||
# 1. No non-ASCII chars in source (em-dashes, smart quotes, arrows, emojis)
|
||||
# 2. No banned shorthand identifiers (cfg, ctx, mgr, req, res, env, util, helper)
|
||||
# as standalone names (suffix usage like printers_bp, request_obj is allowed)
|
||||
# 3. No snake_case DB column names in __tablename__ or db.Column attrs
|
||||
# 4. No snake_case API params in frontend that should match DB column names
|
||||
#
|
||||
# Exits non-zero if any violation found.
|
||||
# Skips: venv/, node_modules/, __pycache__/, frontend/dist/, migrations/versions/
|
||||
|
||||
set -e
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo .)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
VIOLATIONS=0
|
||||
|
||||
EXCLUDES=(
|
||||
--exclude-dir=venv
|
||||
--exclude-dir=node_modules
|
||||
--exclude-dir=__pycache__
|
||||
--exclude-dir=dist
|
||||
--exclude-dir=.git
|
||||
--exclude-dir=versions
|
||||
)
|
||||
|
||||
INCLUDES_CODE=(
|
||||
--include='*.py'
|
||||
--include='*.vue'
|
||||
--include='*.js'
|
||||
--include='*.ts'
|
||||
)
|
||||
|
||||
INCLUDES_ALL=(
|
||||
--include='*.py'
|
||||
--include='*.vue'
|
||||
--include='*.js'
|
||||
--include='*.ts'
|
||||
--include='*.json'
|
||||
--include='*.md'
|
||||
--include='*.yaml'
|
||||
--include='*.yml'
|
||||
)
|
||||
|
||||
echo "==> Checking for non-ASCII characters..."
|
||||
NON_ASCII=$(grep -rPn '[^\x00-\x7F]' "${EXCLUDES[@]}" "${INCLUDES_CODE[@]}" . 2>/dev/null || true)
|
||||
if [ -n "$NON_ASCII" ]; then
|
||||
echo "FAIL: non-ASCII characters found (em-dashes, smart quotes, arrows, emojis):"
|
||||
echo "$NON_ASCII"
|
||||
echo
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
|
||||
echo "==> Checking for banned shorthand (standalone)..."
|
||||
# Match the word as a standalone identifier: not preceded or followed by underscore/word char
|
||||
# Word boundary in grep is \b but we want to exclude suffix usage like printers_bp
|
||||
# So: match (^|[^a-zA-Z0-9_])(banned)([^a-zA-Z0-9_]|$)
|
||||
for word in cfg ctx mgr req res; do
|
||||
HITS=$(grep -rPn "(^|[^a-zA-Z0-9_])${word}([^a-zA-Z0-9_]|\$)" "${EXCLUDES[@]}" --include='*.py' --include='*.vue' --include='*.js' --include='*.ts' . 2>/dev/null \
|
||||
| grep -vP "(^|[^a-zA-Z0-9_])(request_obj|response_obj)" \
|
||||
|| true)
|
||||
if [ -n "$HITS" ]; then
|
||||
echo "FAIL: banned shorthand '$word' (standalone) found:"
|
||||
echo "$HITS"
|
||||
echo
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo "==> Checking for snake_case DB tablenames..."
|
||||
SNAKE_TABLES=$(grep -rPn "__tablename__\s*=\s*['\"][^'\"]*_" "${EXCLUDES[@]}" --include='*.py' . 2>/dev/null || true)
|
||||
if [ -n "$SNAKE_TABLES" ]; then
|
||||
echo "FAIL: snake_case __tablename__ found (must be lowercase concatenated):"
|
||||
echo "$SNAKE_TABLES"
|
||||
echo
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
|
||||
echo "==> Checking for snake_case DB column attrs..."
|
||||
SNAKE_COLS=$(grep -rPn "^\s+[a-z]+_[a-z_]+\s*=\s*db\.Column" "${EXCLUDES[@]}" --include='*.py' . 2>/dev/null || true)
|
||||
if [ -n "$SNAKE_COLS" ]; then
|
||||
echo "FAIL: snake_case db.Column attribute found (must match column name, no underscores):"
|
||||
echo "$SNAKE_COLS"
|
||||
echo
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
|
||||
echo "==> Checking for snake_case ForeignKey targets..."
|
||||
SNAKE_FK=$(grep -rPn "ForeignKey\(['\"][^'\"]*_[^'\"]*['\"]" "${EXCLUDES[@]}" --include='*.py' . 2>/dev/null || true)
|
||||
if [ -n "$SNAKE_FK" ]; then
|
||||
echo "FAIL: snake_case ForeignKey target found:"
|
||||
echo "$SNAKE_FK"
|
||||
echo
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
|
||||
echo "==> Checking for snake_case API params in frontend (DB-mirrored fields)..."
|
||||
SNAKE_FE=$(grep -rPn "params\.(machine_id|location_id|vendor_id|type_id|business_unit_id|model_id|status_id|operating_system_id|asset_id|user_id|is_active|is_shopfloor)" "${EXCLUDES[@]}" --include='*.vue' --include='*.js' --include='*.ts' . 2>/dev/null || true)
|
||||
if [ -n "$SNAKE_FE" ]; then
|
||||
echo "FAIL: snake_case API params in frontend (must match DB column names without underscores):"
|
||||
echo "$SNAKE_FE"
|
||||
echo
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
|
||||
if [ "$VIOLATIONS" -gt 0 ]; then
|
||||
echo "=================================================="
|
||||
echo "$VIOLATIONS naming/style violation(s) found."
|
||||
echo "See CONTRIBUTING.md for the full convention."
|
||||
echo "=================================================="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> All naming/style checks passed."
|
||||
exit 0
|
||||
Reference in New Issue
Block a user