PromucFlow_constructor/.cursor/rules/quality/pre-commit-checks.mdc
vivek-appsmith d176e40726
refactor: restructure .cursor directory for improved organization and clarity (#40196)
# refactor: restructure .cursor directory for improved organization and
clarity

## Description

This PR refactors the `.cursor` directory to enhance organization,
clarity, and maintainability.

### Problem

The existing `.cursor` directory lacked clear organization, making it
difficult to find specific files, understand their purpose, and add new
components consistently.

### Solution

A comprehensive restructuring:

#### New Directory Structure

```
.cursor/
├── settings.json                  # Main configuration file
├── docs/                          # Documentation
│   ├── guides/                    # In-depth guides
│   ├── references/                # Quick references
│   └── practices/                 # Best practices
├── rules/                         # Rule definitions
│   ├── commit/                    # Commit-related rules
│   ├── quality/                   # Code quality rules
│   ├── testing/                   # Testing rules
│   └── verification/              # Verification rules
└── hooks/                         # Git hooks and scripts
```

#### Key Changes

1. **Logical Categorization**: Organized files into clear categories
based on purpose
2. **Improved Documentation**: Added comprehensive README files for each
directory
3. **Standardized Naming**: Implemented consistent kebab-case naming
convention
4. **Reference Updates**: Updated all internal references to point to
new file locations

### Benefits

- **Easier Navigation**: Clear categorization makes finding files
intuitive
- **Improved Understanding**: Comprehensive documentation explains
purpose and usage
- **Simplified Maintenance**: Logical structure makes updates and
additions easier
- **Better Onboarding**: New team members can quickly understand the
system

This refactoring sets a solid foundation for all Cursor AI-related
configurations and rules, making it easier for the team to leverage
Cursor's capabilities.
2025-04-11 12:04:33 +05:30

310 lines
8.2 KiB
Plaintext

---
description:
globs:
alwaysApply: true
---
# Pre-Commit Quality Checks
```yaml
name: Pre-Commit Quality Checks
description: Runs quality checks similar to GitHub Actions locally before commits
author: Cursor AI
version: 1.0.0
tags:
- quality
- pre-commit
- testing
- linting
activation:
always: true
events:
- pre_commit
- command
triggers:
- pre_commit
- command: "run_quality_checks"
```
## Rule Definition
This rule runs the same quality checks locally that would normally run in CI, preventing commits that would fail in the GitHub workflow quality-checks.yml.
## Implementation
```javascript
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
/**
* Determines which checks to run based on changed files
* @param {string[]} changedFiles - List of changed files
* @returns {Object} Object indicating which checks to run
*/
function determineChecksToRun(changedFiles) {
const checks = {
serverChecks: false,
clientChecks: false,
};
// Check if server files have changed
checks.serverChecks = changedFiles.some(file =>
file.startsWith('app/server/')
);
// Check if client files have changed
checks.clientChecks = changedFiles.some(file =>
file.startsWith('app/client/')
);
return checks;
}
/**
* Gets a list of changed files in the current git staging area
* @returns {string[]} List of changed files
*/
function getChangedFiles() {
try {
const output = execSync('git diff --cached --name-only', { encoding: 'utf8' });
return output.split('\n').filter(Boolean);
} catch (error) {
console.error('Error getting changed files:', error.message);
return [];
}
}
/**
* Runs client-side quality checks
* @returns {Object} Results of the checks
*/
function runClientChecks() {
const results = {
success: true,
errors: [],
output: []
};
try {
// Run client lint
console.log('Running client lint checks...');
try {
const lintOutput = execSync('cd app/client && yarn lint', { encoding: 'utf8' });
results.output.push('✅ Client lint passed');
} catch (error) {
results.success = false;
results.errors.push('Client lint failed');
results.output.push(`❌ Client lint failed: ${error.message}`);
}
// Run client unit tests
console.log('Running client unit tests...');
try {
const testOutput = execSync('cd app/client && yarn test', { encoding: 'utf8' });
results.output.push('✅ Client unit tests passed');
} catch (error) {
results.success = false;
results.errors.push('Client unit tests failed');
results.output.push(`❌ Client unit tests failed: ${error.message}`);
}
// Check for cyclic dependencies
console.log('Checking for cyclic dependencies...');
try {
const cyclicCheckOutput = execSync('cd app/client && yarn check-circular-deps', { encoding: 'utf8' });
results.output.push('✅ No cyclic dependencies found');
} catch (error) {
results.success = false;
results.errors.push('Cyclic dependencies check failed');
results.output.push(`❌ Cyclic dependencies found: ${error.message}`);
}
// Run prettier check
console.log('Running prettier check...');
try {
const prettierOutput = execSync('cd app/client && yarn prettier', { encoding: 'utf8' });
results.output.push('✅ Prettier check passed');
} catch (error) {
results.success = false;
results.errors.push('Prettier check failed');
results.output.push(`❌ Prettier check failed: ${error.message}`);
}
} catch (error) {
results.success = false;
results.errors.push(`General error in client checks: ${error.message}`);
}
return results;
}
/**
* Runs server-side quality checks
* @returns {Object} Results of the checks
*/
function runServerChecks() {
const results = {
success: true,
errors: [],
output: []
};
try {
// Run server unit tests
console.log('Running server unit tests...');
try {
const testOutput = execSync('cd app/server && ./gradlew test', { encoding: 'utf8' });
results.output.push('✅ Server unit tests passed');
} catch (error) {
results.success = false;
results.errors.push('Server unit tests failed');
results.output.push(`❌ Server unit tests failed: ${error.message}`);
}
// Run server spotless check
console.log('Running server spotless check...');
try {
const spotlessOutput = execSync('cd app/server && ./gradlew spotlessCheck', { encoding: 'utf8' });
results.output.push('✅ Server spotless check passed');
} catch (error) {
results.success = false;
results.errors.push('Server spotless check failed');
results.output.push(`❌ Server spotless check failed: ${error.message}`);
}
} catch (error) {
results.success = false;
results.errors.push(`General error in server checks: ${error.message}`);
}
return results;
}
/**
* Runs all quality checks
* @param {Object} context - The execution context
* @returns {Object} Results of the checks
*/
function runQualityChecks(context) {
console.log('Running pre-commit quality checks...');
const changedFiles = getChangedFiles();
if (!changedFiles.length) {
return {
status: 'success',
message: 'No files to check'
};
}
const checksToRun = determineChecksToRun(changedFiles);
const results = {
success: true,
output: ['Starting quality checks for staged files...'],
clientChecks: null,
serverChecks: null
};
// Run client checks if client files have changed
if (checksToRun.clientChecks) {
results.output.push('\n=== Client Checks ===');
results.clientChecks = runClientChecks();
results.output = results.output.concat(results.clientChecks.output);
results.success = results.success && results.clientChecks.success;
}
// Run server checks if server files have changed
if (checksToRun.serverChecks) {
results.output.push('\n=== Server Checks ===');
results.serverChecks = runServerChecks();
results.output = results.output.concat(results.serverChecks.output);
results.success = results.success && results.serverChecks.success;
}
// If no checks were run, note that
if (!checksToRun.clientChecks && !checksToRun.serverChecks) {
results.output.push('No client or server files were changed, skipping checks');
}
if (results.success) {
return {
status: 'success',
message: 'All quality checks passed',
details: results.output.join('\n')
};
} else {
return {
status: 'failure',
message: 'Quality checks failed',
details: results.output.join('\n')
};
}
}
/**
* Register command and hooks
* @param {Object} context - The cursor context
*/
function activate(context) {
// Register pre-commit hook
context.on('pre_commit', (event) => {
return runQualityChecks(context);
});
// Register command for manual validation
context.registerCommand('run_quality_checks', () => {
return runQualityChecks(context);
});
}
module.exports = {
activate,
runQualityChecks
};
```
## Usage
This rule runs automatically on pre-commit events. You can also manually trigger it with the command `run_quality_checks`.
### What It Checks
1. **For Client-side Changes:**
- Runs linting checks
- Runs unit tests
- Checks for cyclic dependencies
- Runs prettier formatting validation
2. **For Server-side Changes:**
- Runs unit tests
- Runs spotless formatting checks
### Behavior
- Only runs checks relevant to the files being committed (client and/or server)
- Prevents commits if any checks fail
- Provides detailed output about which checks passed or failed
### Requirements
- Node.js and yarn for client-side checks
- Java and Gradle for server-side checks
- Git for determining changed files
### Customization
You can customize which checks are run by modifying the `runClientChecks` and `runServerChecks` functions.
### Example Output
```
Running pre-commit quality checks...
Starting quality checks for staged files...
=== Client Checks ===
✅ Client lint passed
✅ Client unit tests passed
✅ No cyclic dependencies found
✅ Prettier check passed
=== Server Checks ===
✅ Server unit tests passed
✅ Server spotless check passed
```