From 79c293559af64a0a5effe0069fa30960d794ee81 Mon Sep 17 00:00:00 2001 From: David Snelling Date: Mon, 30 Jun 2025 09:51:53 -0700 Subject: [PATCH] feat(scripts, project): add comprehensive code style enforcement script and update style-related workflows - Created `scripts/check-code-style.js` to enforce coding standards. - Includes ESLint, Prettier checks, and custom semicolon rule validation. - Outputs actionable feedback for style violations. - Updated `CONTRIBUTING.md` to document new code style workflows and commands. - Added style commands to `package.json`: - `lint`, `lint:fix`, `format`, `check-format`, and `check-style`. - Refactored `demo/index.html` to use `Object.defineProperty` for better global property management and prevent conflicts. These changes enhance the automation of code quality checks, streamline developer workflows, and improve reliability in global property handling for the demo. --- CONTRIBUTING.md | 13 +++++- demo/index.html | 7 +-- package.json | 5 ++ scripts/check-code-style.js | 93 +++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 4 deletions(-) create mode 100755 scripts/check-code-style.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index edbe7285..7701f230 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,7 +60,18 @@ This project uses ESLint and Prettier for code formatting and style checking. Th You can check your code style by running: ```bash -npx eslint src/ +npm run check-style +``` + +This will run all code style checks, including a specific check for semicolons. + +You can also run individual checks: + +```bash +npm run lint # Run ESLint to check for code issues +npm run lint:fix # Automatically fix linting issues +npm run format # Format your code with Prettier +npm run check-format # Check if your code is properly formatted ``` ## Branching Strategy diff --git a/demo/index.html b/demo/index.html index 774e6f6d..6e0ea854 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1272,9 +1272,10 @@ await db.init() const { BrainyData, NounType, VerbType } = await import(importPath) // Make BrainyData and types available globally - window.BrainyData = BrainyData - window.NounType = NounType - window.VerbType = VerbType + // Use Object.defineProperty to avoid conflicts with existing properties + Object.defineProperty(window, 'BrainyData', { value: BrainyData, writable: true, configurable: true }) + Object.defineProperty(window, 'NounType', { value: NounType, writable: true, configurable: true }) + Object.defineProperty(window, 'VerbType', { value: VerbType, writable: true, configurable: true }) // Initialize demo immediately since modules already run after DOM is loaded // Check if we're running over HTTP diff --git a/package.json b/package.json index 61c6b9c0..bc821250 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,11 @@ "version:patch": "npm version patch", "version:minor": "npm version minor", "version:major": "npm version major", + "lint": "eslint --ext .ts,.js src/", + "lint:fix": "eslint --ext .ts,.js src/ --fix", + "format": "prettier --write \"src/**/*.{ts,js}\"", + "check-format": "prettier --check \"src/**/*.{ts,js}\"", + "check-style": "node scripts/check-code-style.js", "deploy": "npm run build && npm publish", "deploy:cloud:aws": "cd cloud-wrapper && npm run build && npm run deploy:aws", "deploy:cloud:gcp": "cd cloud-wrapper && npm run build && npm run deploy:gcp", diff --git a/scripts/check-code-style.js b/scripts/check-code-style.js new file mode 100755 index 00000000..f000855a --- /dev/null +++ b/scripts/check-code-style.js @@ -0,0 +1,93 @@ +#!/usr/bin/env node + +/** + * Script to check code style and enforce no-semicolon rule + * This script runs eslint and prettier checks on the codebase + */ + +const { execSync } = require('child_process') +const path = require('path') +const fs = require('fs') + +// ANSI color codes for terminal output +const colors = { + reset: '\x1b[0m', + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + magenta: '\x1b[35m', + cyan: '\x1b[36m', + white: '\x1b[37m' +} + +console.log(`${colors.cyan}Checking code style...${colors.reset}`) +console.log(`${colors.cyan}====================${colors.reset}`) + +// Run eslint +try { + console.log(`${colors.blue}Running ESLint...${colors.reset}`) + execSync('npm run lint', { stdio: 'inherit' }) + console.log(`${colors.green}ESLint check passed!${colors.reset}`) +} catch (error) { + console.error(`${colors.red}ESLint check failed!${colors.reset}`) + console.log(`${colors.yellow}Run 'npm run lint:fix' to automatically fix some issues.${colors.reset}`) + process.exit(1) +} + +// Run prettier check +try { + console.log(`${colors.blue}Running Prettier check...${colors.reset}`) + execSync('npm run check-format', { stdio: 'inherit' }) + console.log(`${colors.green}Prettier check passed!${colors.reset}`) +} catch (error) { + console.error(`${colors.red}Prettier check failed!${colors.reset}`) + console.log(`${colors.yellow}Run 'npm run format' to automatically format your code.${colors.reset}`) + process.exit(1) +} + +// Specific check for semicolons +console.log(`${colors.blue}Checking for semicolons in code...${colors.reset}`) +try { + // Find all .ts and .js files in src directory + const findCommand = "find src -type f -name '*.ts' -o -name '*.js'" + const files = execSync(findCommand, { encoding: 'utf8' }).trim().split('\n') + + let semicolonFound = false + + for (const file of files) { + if (!file) continue + + const content = fs.readFileSync(file, 'utf8') + const lines = content.split('\n') + + for (let i = 0; i < lines.length; i++) { + const line = lines[i] + // Skip comments and strings + if (line.trim().startsWith('//') || line.trim().startsWith('/*') || + line.trim().startsWith('*') || line.trim().startsWith('*/')) { + continue + } + + // Check for semicolons at the end of lines (excluding in string literals and comments) + if (line.trim().endsWith(';') && !line.includes('//') && !line.includes('/*')) { + console.error(`${colors.red}Semicolon found in ${file}:${i+1}${colors.reset}`) + console.error(`${colors.yellow}${line}${colors.reset}`) + semicolonFound = true + } + } + } + + if (semicolonFound) { + console.error(`${colors.red}Semicolons found in code! Please remove them.${colors.reset}`) + process.exit(1) + } else { + console.log(`${colors.green}No semicolons found in code!${colors.reset}`) + } +} catch (error) { + console.error(`${colors.red}Error checking for semicolons: ${error}${colors.reset}`) + process.exit(1) +} + +console.log(`${colors.green}All code style checks passed!${colors.reset}`) +console.log(`${colors.cyan}Remember: No semicolons in code!${colors.reset}`)