feat: add npm commands for single file operations with minified output

- Add 'npm run checkFile <file>' to run prettier and lint on a single file
- Add 'npm run prettier:file <file>' for formatting individual files
- Add 'npm run lint:file <file>' for linting individual files
- Add 'npm run test:file <file>' for running tests on individual spec files
- Create wrapper scripts that show minimal output on success, full output on errors
- Update CLAUDE.md to emphasize using checkFile command frequently
- Add 25-second timeout for test execution to prevent hanging
This commit is contained in:
Johannes Millan 2025-07-12 10:48:51 +02:00
parent 6f40e18d34
commit 4ea38843d0
4 changed files with 109 additions and 3 deletions

View file

@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
2. KISS (Keep It Simple, Stupid): Aim for simplicity and clarity in code. Avoid unnecessary complexity and abstractions.
3. DRY (Don't Repeat Yourself): Reuse code where possible. Create utility functions or services for common logic, but avoid unnecessary abstractions.
4. Confirm understanding before making changes: If you're unsure about the purpose of a piece of code, ask for clarification rather than making assumptions.
5. Use `npm run prettier` and `npm run lint` to format and check code style before committing changes.
5. **ALWAYS** use `npm run checkFile <filepath>` on each file you modify to ensure proper formatting and linting. This runs both prettier and lint checks on individual files. Unless you want to lint and format multiple files, then use `npm run prettier` and `npm run lint` instead.
6. When creating html templates, prefer plain html like `<table>` and `<div>`. Keep CSS styles to a minimum. Keep nesting to a minimum. Keep css classes to a minimum. Use Angular Material components where appropriate, but avoid overusing them.
## Project Overview
@ -38,11 +38,18 @@ npm run lint # Linting
# Build for production
npm run dist # All platforms Builds (all available in current environment)
# IMPORTANT: Check individual files before committing
# Example: npm run checkFile src/app/features/tasks/task.service.ts
# Use this command OFTEN when modifying files to ensure code quality
npm run checkFile <filepath> # Runs prettier and lint on a single file
# executes unit tests of a single spec file
npm run test:file <filepath>
```
### Testing
- Unit tests: `npm test` - Uses Jasmine/Karma, tests are co-located with source files (`.spec.ts`)
- Unit tests: `npm test` - Uses Jasmine/Karma, tests are co-located with source files (`.spec.ts`)
- E2E tests: `npm run e2e` - Uses Nightwatch, located in `/e2e/src/`
- Linting: `npm run lint` - ESLint for TypeScript, Stylelint for SCSS
@ -81,7 +88,7 @@ The app uses NgRx (Redux pattern) for state management. Key state slices:
### Data Sync
- Multiple sync providers: Dropbox, WebDAV, local file
- Sync is conflict-aware with vector-clock resolution
- Sync is conflict-aware with vector-clock resolution
- All sync operations go through `/src/app/imex/sync/`
## Important Development Notes

View file

@ -102,6 +102,10 @@
"version": "npm run prebuild && npm run release.changelog && node ./tools/bump-android-version.js && git add -A",
"prepare": "ts-patch install && npm run plugin-api:build",
"prettier": "pretty-quick",
"prettier:file": "prettier --write",
"lint:file": "ng lint --lint-file-patterns",
"test:file": "cross-env TZ='Europe/Berlin' ng test --watch=false --include",
"checkFile": "node tools/check-file.js",
"clean:translations": "node ./tools/clean-translations.js",
"plugin-api:build": "cd packages/plugin-api && npm run build",
"plugin-api:build:watch": "cd packages/plugin-api && npm run build:watch",

36
tools/check-file.js Normal file
View file

@ -0,0 +1,36 @@
#!/usr/bin/env node
const { execSync } = require('child_process');
const path = require('path');
const file = process.argv[2];
if (!file) {
console.error('❌ Please provide a file path');
process.exit(1);
}
// Get absolute path
const absolutePath = path.resolve(file);
try {
// Run prettier
console.log(`🎨 Formatting ${path.basename(file)}...`);
execSync(`npm run prettier:file ${absolutePath}`, {
stdio: 'pipe',
encoding: 'utf8',
});
// Run lint
console.log(`🔍 Linting ${path.basename(file)}...`);
const lintOutput = execSync(`npm run lint:file ${absolutePath}`, {
stdio: 'pipe',
encoding: 'utf8',
});
// If we get here, both commands succeeded
console.log(`${path.basename(file)} - All checks passed!`);
} catch (error) {
// If there's an error, show the full output
console.error('\n❌ Errors found:\n');
console.error(error.stdout || error.stderr || error.message);
process.exit(1);
}

59
tools/test-file.js Normal file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env node
const { execSync } = require('child_process');
const path = require('path');
const file = process.argv[2];
if (!file) {
console.error('❌ Please provide a test file path');
process.exit(1);
}
// Get absolute path
const absolutePath = path.resolve(file);
try {
console.log(`🧪 Running tests for ${path.basename(file)}...`);
// Run the test directly with cross-env
const { execSync: exec } = require('child_process');
const output = exec(
`./node_modules/.bin/cross-env TZ='Europe/Berlin' ./node_modules/.bin/ng test --watch=false --include="${absolutePath}"`,
{
stdio: 'pipe',
encoding: 'utf8',
shell: true,
timeout: 25000, // 25 second timeout
},
);
// Extract test results
const lines = output.split('\n');
const successLine = lines.find(
(line) => line.includes('SUCCESS') || line.includes('FAILED'),
);
const totalLine = lines.find((line) => line.includes('TOTAL:'));
if (totalLine) {
const match = totalLine.match(/TOTAL: (\d+) (?:SUCCESS|FAILED)/);
if (match) {
const totalTests = match[1];
if (successLine && successLine.includes('SUCCESS')) {
console.log(`✅ All ${totalTests} tests passed!`);
} else {
console.log(`${totalLine.trim()}`);
}
} else {
console.log(`✅ Tests completed: ${totalLine.trim()}`);
}
} else if (successLine) {
console.log(`${successLine.trim()}`);
} else {
// Fallback - just indicate completion
console.log(`✅ Tests completed for ${path.basename(file)}`);
}
} catch (error) {
// If there's an error, show the full output
console.error('\n❌ Test failures:\n');
console.error(error.stdout || error.stderr || error.message);
process.exit(1);
}