Skip to main content
Glama
run-quality-checks.sh13.8 kB
#!/bin/bash /** * EuConquisto Composer MCP Server - Quality Checks Script * * @version 0.1.0 * @created 2025-06-08 * @updated 2025-06-08 * @author EuConquisto Development Team * * @description Automated quality assurance script running linting, testing, * coverage analysis, and code quality metrics validation. * * @testStatus PENDING * @coverage N/A * * @dependencies * - npm * - ESLint * - Jest * - TypeScript * * @supersedes N/A * @supersededBy N/A */ set -e # Exit on any error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' NC='\033[0m' # No Color # Quality thresholds MIN_COVERAGE=80 MAX_COMPLEXITY=10 MAX_LINES_PER_FILE=500 MAX_FUNCTIONS_PER_FILE=20 # Function to print colored output print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_metric() { echo -e "${PURPLE}[METRIC]${NC} $1" } # Function to run TypeScript compilation run_typescript_check() { print_status "Running TypeScript compilation check..." if npm run build > /tmp/tsc-output.log 2>&1; then print_success "TypeScript compilation passed" return 0 else print_error "TypeScript compilation failed" cat /tmp/tsc-output.log return 1 fi } # Function to run ESLint run_eslint() { print_status "Running ESLint analysis..." # Run ESLint and capture output if npm run lint > /tmp/eslint-output.log 2>&1; then print_success "ESLint analysis passed" # Count warnings if any WARNINGS=$(grep -c "warning" /tmp/eslint-output.log || echo "0") if [ "$WARNINGS" -gt 0 ]; then print_warning "Found $WARNINGS ESLint warnings" fi return 0 else print_error "ESLint analysis failed" cat /tmp/eslint-output.log return 1 fi } # Function to run tests with coverage run_tests_with_coverage() { print_status "Running test suite with coverage..." if npm run test:coverage > /tmp/test-output.log 2>&1; then print_success "Test suite passed" # Extract coverage information COVERAGE=$(grep -o "All files.*[0-9]\+\.[0-9]\+" /tmp/test-output.log | tail -1 | grep -o "[0-9]\+\.[0-9]\+" || echo "0") if [ -n "$COVERAGE" ]; then print_metric "Test coverage: $COVERAGE%" # Check if coverage meets minimum requirement if (( $(echo "$COVERAGE >= $MIN_COVERAGE" | bc -l) )); then print_success "Coverage meets minimum requirement ($MIN_COVERAGE%)" else print_warning "Coverage below minimum requirement ($MIN_COVERAGE%). Current: $COVERAGE%" fi fi return 0 else print_error "Test suite failed" cat /tmp/test-output.log return 1 fi } # Function to analyze code complexity analyze_code_complexity() { print_status "Analyzing code complexity..." # Count files and functions TS_FILES=$(find src -name "*.ts" | wc -l) TOTAL_LINES=$(find src -name "*.ts" -exec wc -l {} + | tail -1 | awk '{print $1}') print_metric "TypeScript files: $TS_FILES" print_metric "Total lines of code: $TOTAL_LINES" # Check for large files LARGE_FILES=$(find src -name "*.ts" -exec wc -l {} + | awk -v max="$MAX_LINES_PER_FILE" '$1 > max {print $2 " (" $1 " lines)"}') if [ -n "$LARGE_FILES" ]; then print_warning "Large files detected (>$MAX_LINES_PER_FILE lines):" echo "$LARGE_FILES" else print_success "No overly large files detected" fi # Average lines per file if [ "$TS_FILES" -gt 0 ]; then AVG_LINES=$((TOTAL_LINES / TS_FILES)) print_metric "Average lines per file: $AVG_LINES" fi } # Function to check version consistency check_version_consistency() { print_status "Checking version consistency..." # Get versions from different files PROJECT_VERSION=$(grep '"version"' package.json | cut -d'"' -f4) VERSION_FILE_VERSION=$(grep "Version.*:" VERSION | head -1 | sed 's/.*: *//' | sed 's/ .*//') README_VERSION=$(grep "Version.*:" README.md | head -1 | sed 's/.*: *//' | sed 's/ .*//') print_metric "package.json version: $PROJECT_VERSION" print_metric "VERSION file version: $VERSION_FILE_VERSION" print_metric "README.md version: $README_VERSION" if [ "$PROJECT_VERSION" = "$VERSION_FILE_VERSION" ] && [ "$PROJECT_VERSION" = "$README_VERSION" ]; then print_success "Version consistency validated" VERSION_CONSISTENT="true" else print_error "Version inconsistency detected" VERSION_CONSISTENT="false" return 1 fi } # Function to check file version headers check_file_headers() { print_status "Checking file version headers..." # Check TypeScript files TS_FILES_TOTAL=$(find src -name "*.ts" | wc -l) TS_FILES_WITH_HEADERS=$(find src -name "*.ts" -exec grep -l "@version" {} + | wc -l) print_metric "TypeScript files: $TS_FILES_TOTAL" print_metric "Files with version headers: $TS_FILES_WITH_HEADERS" if [ "$TS_FILES_TOTAL" -eq "$TS_FILES_WITH_HEADERS" ]; then print_success "All TypeScript files have version headers" HEADERS_COMPLETE="true" else MISSING_HEADERS=$((TS_FILES_TOTAL - TS_FILES_WITH_HEADERS)) print_warning "$MISSING_HEADERS TypeScript files missing version headers" HEADERS_COMPLETE="false" fi } # Function to validate project metadata validate_project_metadata() { print_status "Validating project metadata..." if [ -f "project.json" ]; then # Check if project.json is valid JSON if jq empty project.json 2>/dev/null; then PROJECT_VERSION_JSON=$(jq -r '.project.version' project.json) COMPLETED_TASKS=$(jq -r '.development.completedTasks' project.json) print_metric "project.json version: $PROJECT_VERSION_JSON" print_metric "Completed tasks: $COMPLETED_TASKS/15" if [ "$PROJECT_VERSION" = "$PROJECT_VERSION_JSON" ]; then print_success "project.json metadata synchronized" METADATA_VALID="true" else print_warning "project.json version mismatch" METADATA_VALID="false" fi else print_error "project.json is not valid JSON" METADATA_VALID="false" fi else print_warning "project.json not found" METADATA_VALID="false" fi } # Function to check documentation coverage check_documentation_coverage() { print_status "Checking documentation coverage..." # Count files with JSDoc comments FILES_WITH_DOCS=$(find src -name "*.ts" -exec grep -l "/\*\*" {} + | wc -l) TOTAL_TS_FILES=$(find src -name "*.ts" | wc -l) if [ "$TOTAL_TS_FILES" -gt 0 ]; then DOC_COVERAGE=$((FILES_WITH_DOCS * 100 / TOTAL_TS_FILES)) print_metric "Documentation coverage: $DOC_COVERAGE% ($FILES_WITH_DOCS/$TOTAL_TS_FILES files)" if [ "$DOC_COVERAGE" -ge 80 ]; then print_success "Documentation coverage is good" else print_warning "Documentation coverage could be improved" fi fi # Check for README files README_FILES=$(find . -name "README.md" | wc -l) print_metric "README files: $README_FILES" } # Function to check security vulnerabilities check_security() { print_status "Checking for security vulnerabilities..." if command -v npm >/dev/null 2>&1; then if npm audit --audit-level=moderate > /tmp/audit-output.log 2>&1; then print_success "No moderate or high security vulnerabilities found" else VULNERABILITIES=$(grep -c "vulnerabilities" /tmp/audit-output.log || echo "0") if [ "$VULNERABILITIES" -gt 0 ]; then print_warning "Security vulnerabilities detected - run 'npm audit' for details" else print_success "Security audit completed" fi fi else print_warning "npm not available for security audit" fi } # Function to check Git status check_git_status() { print_status "Checking Git status..." if [ -d ".git" ]; then # Check for uncommitted changes if [ -n "$(git status --porcelain)" ]; then print_warning "Uncommitted changes detected" git status --short else print_success "Working directory is clean" fi # Check current branch CURRENT_BRANCH=$(git branch --show-current) print_metric "Current branch: $CURRENT_BRANCH" # Check for unpushed commits UNPUSHED=$(git log @{u}.. --oneline 2>/dev/null | wc -l || echo "0") if [ "$UNPUSHED" -gt 0 ]; then print_warning "$UNPUSHED unpushed commits" else print_success "All commits are pushed" fi else print_warning "Not a Git repository" fi } # Function to generate quality report generate_quality_report() { print_status "Generating quality report..." REPORT_DIR="validation/quality-metrics" REPORT_FILE="$REPORT_DIR/quality-report-$(date +%Y%m%d-%H%M%S).json" mkdir -p "$REPORT_DIR" # Create JSON report cat > "$REPORT_FILE" << EOF { "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", "version": "0.1.0", "metrics": { "coverage": ${COVERAGE:-0}, "files": { "total": $TS_FILES, "totalLines": $TOTAL_LINES, "averageLines": ${AVG_LINES:-0}, "withDocumentation": $FILES_WITH_DOCS }, "documentation": { "coverage": ${DOC_COVERAGE:-0}, "readmeFiles": $README_FILES }, "quality": { "minimumCoverage": $MIN_COVERAGE, "maxLinesPerFile": $MAX_LINES_PER_FILE, "coverageMet": $([ "${COVERAGE:-0}" -ge "$MIN_COVERAGE" ] && echo "true" || echo "false") }, "versioning": { "consistent": $([ "${VERSION_CONSISTENT:-false}" = "true" ] && echo "true" || echo "false"), "headersComplete": $([ "${HEADERS_COMPLETE:-false}" = "true" ] && echo "true" || echo "false"), "metadataValid": $([ "${METADATA_VALID:-false}" = "true" ] && echo "true" || echo "false") } }, "checks": { "typescript": $([ "$TYPESCRIPT_PASSED" = "true" ] && echo "true" || echo "false"), "eslint": $([ "$ESLINT_PASSED" = "true" ] && echo "true" || echo "false"), "tests": $([ "$TESTS_PASSED" = "true" ] && echo "true" || echo "false"), "security": $([ "$SECURITY_PASSED" = "true" ] && echo "true" || echo "false") } } EOF print_success "Quality report generated: $REPORT_FILE" } # Function to display summary display_summary() { echo "" echo "==============================================" echo "📊 Quality Check Summary" echo "==============================================" echo "" # Calculate overall score PASSED_CHECKS=0 TOTAL_CHECKS=4 [ "$TYPESCRIPT_PASSED" = "true" ] && PASSED_CHECKS=$((PASSED_CHECKS + 1)) [ "$ESLINT_PASSED" = "true" ] && PASSED_CHECKS=$((PASSED_CHECKS + 1)) [ "$TESTS_PASSED" = "true" ] && PASSED_CHECKS=$((PASSED_CHECKS + 1)) [ "$SECURITY_PASSED" = "true" ] && PASSED_CHECKS=$((PASSED_CHECKS + 1)) SCORE=$((PASSED_CHECKS * 100 / TOTAL_CHECKS)) echo "Overall Score: $SCORE% ($PASSED_CHECKS/$TOTAL_CHECKS checks passed)" echo "" echo "Check Results:" echo " TypeScript Compilation: $([ "$TYPESCRIPT_PASSED" = "true" ] && echo "✅ PASSED" || echo "❌ FAILED")" echo " ESLint Analysis: $([ "$ESLINT_PASSED" = "true" ] && echo "✅ PASSED" || echo "❌ FAILED")" echo " Test Suite: $([ "$TESTS_PASSED" = "true" ] && echo "✅ PASSED" || echo "❌ FAILED")" echo " Security Audit: $([ "$SECURITY_PASSED" = "true" ] && echo "✅ PASSED" || echo "❌ FAILED")" echo "" echo "Metrics:" echo " Test Coverage: ${COVERAGE:-0}% (minimum: $MIN_COVERAGE%)" echo " Documentation Coverage: ${DOC_COVERAGE:-0}%" echo " Total Files: $TS_FILES" echo " Total Lines: $TOTAL_LINES" echo "" if [ "$SCORE" -ge 75 ]; then print_success "Quality checks passed! 🎉" return 0 else print_warning "Quality checks need attention 🔧" return 1 fi } # Main execution main() { echo "==============================================" echo "🔍 EuConquisto Composer MCP Server - Quality Checks" echo "==============================================" echo "" # Initialize status variables TYPESCRIPT_PASSED="false" ESLINT_PASSED="false" TESTS_PASSED="false" SECURITY_PASSED="false" # Run checks if run_typescript_check; then TYPESCRIPT_PASSED="true" fi if run_eslint; then ESLINT_PASSED="true" fi if run_tests_with_coverage; then TESTS_PASSED="true" fi if check_security; then SECURITY_PASSED="true" fi # Additional analysis analyze_code_complexity check_documentation_coverage check_git_status # Version validation check_version_consistency check_file_headers validate_project_metadata # Generate report generate_quality_report # Display summary display_summary } # Execute main function main "$@"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rkm097git/euconquisto-composer-mcp-poc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server