Skip to content

Commit 343cc0b

Browse files
Copilotlstein
andauthored
Add linting infrastructure with Ruff, ESLint, and Prettier (#199)
* Add linting tools configuration for backend (Ruff) and frontend (ESLint/Prettier) Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix pytest fixture discovery - import client and new_album fixtures into conftest.py Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com>
1 parent 89776c3 commit 343cc0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+5077
-4050
lines changed

.github/copilot-instructions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ PhotoMapAI/
4242
- Prefer f-strings for string formatting
4343
- Use pathlib.Path for file path operations instead of os.path
4444
- Import organization: standard library → third-party → local imports
45+
- Python files must pass ruff check
4546

4647
#### JavaScript
4748
- Use ES6 modules with explicit imports/exports
4849
- Use const/let instead of var
4950
- Use descriptive function and variable names
5051
- Add comments for complex logic, especially in event handlers
5152
- Follow existing file structure: one module per file with clear responsibilities
53+
- JavaScript files must pass `npm lint` and `npm run format:check`
5254

5355
### Testing
5456

.github/workflows/lint.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Lint Code
2+
3+
on:
4+
push:
5+
branches: [ master, main ]
6+
pull_request:
7+
branches: [ master, main ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
backend-lint:
14+
name: Backend Linting (Ruff)
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: '3.10'
25+
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install .[development]
30+
31+
- name: Run Ruff
32+
run: |
33+
ruff check photomap tests
34+
35+
frontend-lint:
36+
name: Frontend Linting (ESLint & Prettier)
37+
runs-on: ubuntu-latest
38+
39+
steps:
40+
- name: Checkout code
41+
uses: actions/checkout@v4
42+
43+
- name: Set up Node.js
44+
uses: actions/setup-node@v4
45+
with:
46+
node-version: '20'
47+
cache: 'npm'
48+
49+
- name: Install dependencies
50+
run: npm ci
51+
52+
- name: Run ESLint
53+
run: npm run lint
54+
55+
- name: Run Prettier check
56+
run: npm run format:check

.prettierignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
node_modules
2+
dist
3+
build
4+
coverage
5+
.pytest_cache
6+
__pycache__
7+
*.min.js
8+
package-lock.json
9+
*.pyc

.prettierrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "es5",
4+
"singleQuote": false,
5+
"printWidth": 120,
6+
"tabWidth": 2,
7+
"useTabs": false,
8+
"arrowParens": "always",
9+
"endOfLine": "lf"
10+
}

Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ help:
1111
@echo "docker-demo Build the Docker demo site image."
1212
@echo "docs Serve the mkdocs site with live reload."
1313
@echo "deploy-docs Deploy the mkdocs site to GitHub pages."
14+
@echo "backend-lint Run Python backend linting with Ruff."
15+
@echo "frontend-lint Run JavaScript frontend linting with ESLint and Prettier."
16+
@echo "lint Run both backend and frontend linting."
1417

1518
# Run the unit tests
1619
test:
@@ -48,3 +51,26 @@ docs:
4851

4952
deploy-docs:
5053
mkdocs gh-deploy
54+
55+
# Run backend linting with Ruff
56+
# fix with ruff check photomap tests photomap --fix
57+
.PHONY: backend-lint
58+
backend-lint:
59+
@echo "Running Ruff on Python backend..."
60+
ruff check photomap tests photomap
61+
62+
# Run frontend linting with ESLint and Prettier
63+
# Fix with npm run lint:fix
64+
# npm run format
65+
.PHONY: frontend-lint
66+
frontend-lint:
67+
@echo "Installing npm dependencies if needed..."
68+
npm install
69+
@echo "Running ESLint on JavaScript frontend..."
70+
npm run lint
71+
@echo "Running Prettier check on JavaScript frontend..."
72+
npm run format:check
73+
74+
# Run both backend and frontend linting
75+
.PHONY: lint
76+
lint: backend-lint frontend-lint

eslint.config.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
export default [
2+
{
3+
ignores: [
4+
'**/node_modules/**',
5+
'**/dist/**',
6+
'**/build/**',
7+
'**/.pytest_cache/**',
8+
'**/__pycache__/**',
9+
'**/coverage/**',
10+
],
11+
},
12+
{
13+
files: ['**/*.js'],
14+
languageOptions: {
15+
ecmaVersion: 2022,
16+
sourceType: 'module',
17+
globals: {
18+
// Browser globals
19+
window: 'readonly',
20+
document: 'readonly',
21+
console: 'readonly',
22+
localStorage: 'readonly',
23+
sessionStorage: 'readonly',
24+
fetch: 'readonly',
25+
FormData: 'readonly',
26+
URLSearchParams: 'readonly',
27+
URL: 'readonly',
28+
setTimeout: 'readonly',
29+
clearTimeout: 'readonly',
30+
setInterval: 'readonly',
31+
clearInterval: 'readonly',
32+
alert: 'readonly',
33+
confirm: 'readonly',
34+
prompt: 'readonly',
35+
CustomEvent: 'readonly',
36+
Event: 'readonly',
37+
MouseEvent: 'readonly',
38+
KeyboardEvent: 'readonly',
39+
TouchEvent: 'readonly',
40+
ResizeObserver: 'readonly',
41+
IntersectionObserver: 'readonly',
42+
MutationObserver: 'readonly',
43+
HTMLElement: 'readonly',
44+
Element: 'readonly',
45+
Node: 'readonly',
46+
NodeList: 'readonly',
47+
Blob: 'readonly',
48+
File: 'readonly',
49+
FileReader: 'readonly',
50+
Image: 'readonly',
51+
navigator: 'readonly',
52+
performance: 'readonly',
53+
requestAnimationFrame: 'readonly',
54+
getComputedStyle: 'readonly',
55+
// Plotly global (used in umap.js)
56+
Plotly: 'readonly',
57+
// Swiper global (used in swiper.js)
58+
Swiper: 'readonly',
59+
},
60+
},
61+
rules: {
62+
// Possible errors
63+
'no-console': 'off',
64+
'no-debugger': 'warn',
65+
'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
66+
'no-undef': 'error',
67+
68+
// Best practices
69+
'eqeqeq': ['error', 'always'],
70+
'curly': ['error', 'all'],
71+
'no-eval': 'error',
72+
'no-implied-eval': 'error',
73+
'no-with': 'error',
74+
'no-new-func': 'error',
75+
76+
// ES6+
77+
'prefer-const': 'warn',
78+
'no-var': 'warn',
79+
'prefer-arrow-callback': 'warn',
80+
'arrow-spacing': 'error',
81+
82+
// Style (mostly handled by Prettier, but some logical style rules)
83+
// Note: quotes handled by Prettier, semi retained for logical consistency
84+
'semi': ['error', 'always'],
85+
},
86+
},
87+
{
88+
files: ['tests/**/*.js', '**/*.test.js'],
89+
languageOptions: {
90+
globals: {
91+
// Jest globals
92+
describe: 'readonly',
93+
it: 'readonly',
94+
test: 'readonly',
95+
expect: 'readonly',
96+
beforeEach: 'readonly',
97+
afterEach: 'readonly',
98+
beforeAll: 'readonly',
99+
afterAll: 'readonly',
100+
jest: 'readonly',
101+
global: 'readonly',
102+
},
103+
},
104+
},
105+
];

0 commit comments

Comments
 (0)