verstak-official-plugins/scripts/check.sh

156 lines
4.7 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
FAILED=0
report() {
if [ "$2" -eq 0 ]; then
echo "$1"
else
echo "$1"
FAILED=1
fi
}
echo "=== verstak-official-plugins check ==="
# ── Dependency checks ──
HAS_PYTHON=0
if command -v python3 &>/dev/null; then HAS_PYTHON=1; fi
# Validate all plugin manifests against the SDK schema
if [ "$HAS_PYTHON" -eq 1 ]; then
echo "[manifest validation]"
SDK_SCHEMA="$ROOT/../verstak-sdk/schemas/manifest.json"
if [ -f "$SDK_SCHEMA" ]; then
python3 -c "
import json, glob
skipped = []
problems = []
for plugin_dir in glob.glob('$ROOT/plugins/*/'):
manifest_path = plugin_dir + 'plugin.json'
try:
with open(manifest_path) as f:
manifest = json.load(f)
except FileNotFoundError:
skipped.append(plugin_dir.split('/')[-2])
continue
except json.JSONDecodeError as e:
problems.append(plugin_dir.split('/')[-2] + ': invalid JSON — ' + str(e))
continue
checks = {
'id': isinstance(manifest.get('id'), str) and '.' in manifest['id'],
'version': isinstance(manifest.get('version'), str),
'schemaVersion': manifest.get('schemaVersion') == 1,
'provides': isinstance(manifest.get('provides'), list),
'requires': isinstance(manifest.get('requires'), list),
}
for check, ok in checks.items():
if not ok:
problems.append(manifest.get('id', plugin_dir.split('/')[-2]) + ': missing/empty \"' + check + '\"')
if skipped:
print(' \u26a0\ufe0f skipped (no plugin.json): ' + ', '.join(skipped))
if problems:
for p in problems:
print(' \u274c ' + p)
else:
print(' \u2705 all manifests valid')
"
report "manifests valid" $?
else
echo " SDK schema not found at $SDK_SCHEMA — run build.sh in verstak-sdk first"
fi
else
echo " python3 not available — skipping manifest validation"
fi
echo ""
# Check all scripts in plugins are executable
echo "[script permissions]"
MISSING_EXEC=0
while IFS= read -r script; do
if [ ! -x "$script" ]; then
echo " ❌ not executable: $script"
MISSING_EXEC=1
fi
done < <(find "$ROOT/plugins" -name '*.sh' -o -name '*.py' 2>/dev/null)
if [ "$MISSING_EXEC" -eq 0 ]; then
echo " ✅ all scripts executable"
fi
echo ""
echo "[frontend smoke]"
if command -v node &>/dev/null; then
node "$ROOT/scripts/smoke-platform-frontend.js"
report "platform-test frontend components mount" $?
else
echo " ⚠️ node not available — skipping frontend smoke"
fi
echo ""
echo "[frontend bundle execution]"
if command -v node &>/dev/null; then
BUNDLE_FAILED=0
for plugin_dir in "$ROOT"/plugins/*/; do
plugin_id=$(basename "$plugin_dir")
manifest="$plugin_dir/plugin.json"
if [ ! -f "$manifest" ]; then continue; fi
# Check if plugin has frontend entry
entry=$(node -e "const m=require('$manifest');console.log(m.frontend&&m.frontend.entry||'')" 2>/dev/null)
if [ -z "$entry" ]; then continue; fi
bundle="$plugin_dir$entry"
if [ ! -f "$bundle" ] && [ "$entry" = "frontend/dist/index.js" ] && [ -f "$plugin_dir/frontend/src/index.js" ]; then
bundle="$plugin_dir/frontend/src/index.js"
fi
if [ ! -f "$bundle" ]; then
echo "$plugin_id: bundle not found at $entry"
BUNDLE_FAILED=1
continue
fi
# Execute bundle via new Function() and verify registration
node -e "
const fs = require('fs');
const content = fs.readFileSync('$bundle', 'utf8');
// Provide minimal globals
global.window = { VerstakPluginRegister: function(id, def) { global.__registered = id; } };
global.document = { getElementById: function() { return null; }, createElement: function() { return { style: {}, setAttribute: function(){}, appendChild: function(){} }; }, head: { appendChild: function(){} } };
try {
new Function(content)();
if (!global.__registered) {
console.log('ERROR: plugin did not call VerstakPluginRegister');
process.exit(1);
}
console.log('OK: ' + global.__registered);
} catch(e) {
console.log('ERROR: ' + e.message);
process.exit(1);
}
" 2>&1 | while read -r line; do
if [[ "$line" == ERROR:* ]]; then
echo "$plugin_id: ${line#ERROR: }"
BUNDLE_FAILED=1
elif [[ "$line" == OK:* ]]; then
echo "$plugin_id: ${line#OK: }"
fi
done
done
if [ "$BUNDLE_FAILED" -ne 0 ]; then
FAILED=1
fi
else
echo " ⚠️ node not available — skipping bundle execution"
fi
echo ""
if [ "$FAILED" -eq 0 ]; then
echo "✅ all checks passed"
else
echo "❌ some checks failed"
fi
exit "$FAILED"