mcp-dbutils 0.14.0__tar.gz → 0.15.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_dbutils-0.15.1/.github/workflows/code-style.yml +17 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/.github/workflows/quality-assurance.yml +164 -0
- mcp_dbutils-0.15.1/.pre-commit-config.yaml +7 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/CHANGELOG.md +14 -0
- mcp_dbutils-0.14.0/README.md → mcp_dbutils-0.15.1/PKG-INFO +76 -0
- mcp_dbutils-0.14.0/PKG-INFO → mcp_dbutils-0.15.1/README.md +51 -23
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/README_CN.md +83 -0
- mcp_dbutils-0.15.1/pyproject.toml +119 -0
- mcp_dbutils-0.15.1/scripts/sonar-ai-fix.fish +62 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/__init__.py +4 -3
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/base.py +5 -6
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/config.py +3 -4
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/log.py +2 -1
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/mysql/config.py +4 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/mysql/handler.py +2 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/mysql/server.py +6 -6
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/postgres/config.py +4 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/postgres/handler.py +2 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/postgres/server.py +6 -6
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/sqlite/config.py +4 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/sqlite/handler.py +2 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/sqlite/server.py +5 -6
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/stats.py +4 -3
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/conftest.py +6 -6
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/conftest.py +3 -6
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/fixtures.py +8 -6
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_logging.py +4 -7
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_monitoring.py +5 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_monitoring_enhanced.py +6 -5
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_mysql.py +7 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_mysql_config.py +5 -4
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_postgres.py +7 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_postgres_config.py +4 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_prompts.py +4 -3
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_sqlite.py +8 -3
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_sqlite_config.py +4 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_tools.py +4 -3
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/test_tools_advanced.py +4 -3
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/unit/test_log.py +5 -2
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/unit/test_stats.py +2 -1
- mcp_dbutils-0.14.0/pyproject.toml +0 -58
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/.coveragerc +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/.github/workflows/release.yml +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/.gitignore +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/.releaserc.json +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/Dockerfile +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/LICENSE +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/config.yaml.example +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/smithery.yaml +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/sonar-project.properties +0 -0
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/mysql/__init__.py +1 -1
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/postgres/__init__.py +1 -1
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/src/mcp_dbutils/sqlite/__init__.py +1 -1
- {mcp_dbutils-0.14.0 → mcp_dbutils-0.15.1}/tests/integration/__init__.py +0 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
name: Code Style
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ main ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
ruff:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v4
|
14
|
+
|
15
|
+
- uses: astral-sh/ruff-action@v3.2.1
|
16
|
+
with:
|
17
|
+
version: latest
|
@@ -103,13 +103,17 @@ jobs:
|
|
103
103
|
with:
|
104
104
|
name: coverage-report
|
105
105
|
- name: SonarCloud Scan
|
106
|
+
id: sonar_scan
|
106
107
|
uses: SonarSource/sonarqube-scan-action@v5.0.0
|
108
|
+
continue-on-error: true
|
107
109
|
env:
|
108
110
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
109
111
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
110
112
|
|
111
113
|
- name: SonarQube Quality Gate Check
|
114
|
+
id: sonar_qg
|
112
115
|
uses: sonarsource/sonarqube-quality-gate-action@master
|
116
|
+
continue-on-error: true
|
113
117
|
timeout-minutes: 5
|
114
118
|
env:
|
115
119
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
@@ -264,3 +268,163 @@ jobs:
|
|
264
268
|
});
|
265
269
|
console.log('Created new SonarCloud comment');
|
266
270
|
}
|
271
|
+
|
272
|
+
- name: Extract SonarCloud Issues
|
273
|
+
if: always()
|
274
|
+
uses: actions/github-script@v6
|
275
|
+
env:
|
276
|
+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
277
|
+
SONAR_PROJECT_KEY: 'donghao1393_mcp-dbutils'
|
278
|
+
with:
|
279
|
+
script: |
|
280
|
+
const fs = require('fs');
|
281
|
+
|
282
|
+
// 获取SonarCloud问题
|
283
|
+
const projectKey = process.env.SONAR_PROJECT_KEY;
|
284
|
+
console.log(`获取项目 ${projectKey} 的SonarCloud问题...`);
|
285
|
+
|
286
|
+
// 获取未解决的问题
|
287
|
+
const issuesResponse = await fetch(
|
288
|
+
`https://sonarcloud.io/api/issues/search?componentKeys=${projectKey}&resolved=false&ps=500`,
|
289
|
+
{ headers: { Authorization: `Bearer ${process.env.SONAR_TOKEN}` } }
|
290
|
+
).then(res => res.json());
|
291
|
+
|
292
|
+
console.log(`找到 ${issuesResponse.issues ? issuesResponse.issues.length : 0} 个未解决的问题`);
|
293
|
+
|
294
|
+
// 保存原始JSON
|
295
|
+
fs.writeFileSync('sonar_issues.json', JSON.stringify(issuesResponse, null, 2));
|
296
|
+
|
297
|
+
// 格式化为AI友好的Markdown
|
298
|
+
let markdownContent = '# SonarCloud分析问题报告\n\n';
|
299
|
+
markdownContent += `[在SonarCloud中查看完整报告](https://sonarcloud.io/project/issues?id=${projectKey})\n\n`;
|
300
|
+
|
301
|
+
// 添加问题摘要
|
302
|
+
if (issuesResponse.issues && issuesResponse.issues.length > 0) {
|
303
|
+
// 按严重性统计
|
304
|
+
const severityCounts = {};
|
305
|
+
// 按类型统计
|
306
|
+
const typeCounts = {};
|
307
|
+
|
308
|
+
issuesResponse.issues.forEach(issue => {
|
309
|
+
severityCounts[issue.severity] = (severityCounts[issue.severity] || 0) + 1;
|
310
|
+
typeCounts[issue.type] = (typeCounts[issue.type] || 0) + 1;
|
311
|
+
});
|
312
|
+
|
313
|
+
markdownContent += '## 问题摘要\n\n';
|
314
|
+
|
315
|
+
markdownContent += '### 按严重性\n\n';
|
316
|
+
for (const [severity, count] of Object.entries(severityCounts)) {
|
317
|
+
let severityText = '';
|
318
|
+
switch (severity) {
|
319
|
+
case 'BLOCKER': severityText = '阻断级'; break;
|
320
|
+
case 'CRITICAL': severityText = '严重级'; break;
|
321
|
+
case 'MAJOR': severityText = '主要级'; break;
|
322
|
+
case 'MINOR': severityText = '次要级'; break;
|
323
|
+
case 'INFO': severityText = '提示级'; break;
|
324
|
+
default: severityText = severity;
|
325
|
+
}
|
326
|
+
markdownContent += `- ${severityText}: ${count}个问题\n`;
|
327
|
+
}
|
328
|
+
|
329
|
+
markdownContent += '\n### 按类型\n\n';
|
330
|
+
for (const [type, count] of Object.entries(typeCounts)) {
|
331
|
+
let typeText = '';
|
332
|
+
switch (type) {
|
333
|
+
case 'BUG': typeText = 'Bug'; break;
|
334
|
+
case 'VULNERABILITY': typeText = '安全漏洞'; break;
|
335
|
+
case 'CODE_SMELL': typeText = '代码异味'; break;
|
336
|
+
default: typeText = type;
|
337
|
+
}
|
338
|
+
markdownContent += `- ${typeText}: ${count}个问题\n`;
|
339
|
+
}
|
340
|
+
|
341
|
+
// 按文件分组问题
|
342
|
+
const issuesByFile = {};
|
343
|
+
issuesResponse.issues.forEach(issue => {
|
344
|
+
const component = issue.component.split(':').pop();
|
345
|
+
if (!issuesByFile[component]) {
|
346
|
+
issuesByFile[component] = [];
|
347
|
+
}
|
348
|
+
issuesByFile[component].push(issue);
|
349
|
+
});
|
350
|
+
|
351
|
+
markdownContent += '\n## 详细问题列表\n\n';
|
352
|
+
|
353
|
+
for (const [file, issues] of Object.entries(issuesByFile)) {
|
354
|
+
markdownContent += `### 文件: ${file}\n\n`;
|
355
|
+
|
356
|
+
issues.forEach(issue => {
|
357
|
+
let severityText = '';
|
358
|
+
switch (issue.severity) {
|
359
|
+
case 'BLOCKER': severityText = '阻断级'; break;
|
360
|
+
case 'CRITICAL': severityText = '严重级'; break;
|
361
|
+
case 'MAJOR': severityText = '主要级'; break;
|
362
|
+
case 'MINOR': severityText = '次要级'; break;
|
363
|
+
case 'INFO': severityText = '提示级'; break;
|
364
|
+
default: severityText = issue.severity;
|
365
|
+
}
|
366
|
+
|
367
|
+
let typeText = '';
|
368
|
+
switch (issue.type) {
|
369
|
+
case 'BUG': typeText = 'Bug'; break;
|
370
|
+
case 'VULNERABILITY': typeText = '安全漏洞'; break;
|
371
|
+
case 'CODE_SMELL': typeText = '代码异味'; break;
|
372
|
+
default: typeText = issue.type;
|
373
|
+
}
|
374
|
+
|
375
|
+
markdownContent += `- 文件: ${file}\n`;
|
376
|
+
markdownContent += ` 行号: ${issue.line || 'N/A'}\n`;
|
377
|
+
markdownContent += ` 问题: ${issue.message}\n`;
|
378
|
+
markdownContent += ` 严重性: ${severityText}\n`;
|
379
|
+
markdownContent += ` 类型: ${typeText}\n`;
|
380
|
+
markdownContent += ` [在SonarCloud中查看](https://sonarcloud.io/project/issues?id=${projectKey}&open=${issue.key})\n\n`;
|
381
|
+
});
|
382
|
+
}
|
383
|
+
|
384
|
+
// 添加常见问题修复建议
|
385
|
+
markdownContent += '## 常见问题修复建议\n\n';
|
386
|
+
|
387
|
+
// 检查是否存在特定规则的问题
|
388
|
+
const hasRule = rule => issuesResponse.issues.some(issue => issue.rule === rule);
|
389
|
+
|
390
|
+
if (hasRule('python:S1481')) {
|
391
|
+
markdownContent += '- **未使用的变量**: 删除未使用的变量声明,或者在变量名前添加下划线(例如 `_unused`)\n';
|
392
|
+
}
|
393
|
+
|
394
|
+
if (hasRule('python:S5754')) {
|
395
|
+
markdownContent += '- **类型检查**: 使用 `isinstance()` 替代 `type()` 进行类型检查\n';
|
396
|
+
}
|
397
|
+
|
398
|
+
if (hasRule('python:S1066')) {
|
399
|
+
markdownContent += '- **合并嵌套if语句**: 将嵌套的if语句合并为一个使用 `and` 运算符的条件\n';
|
400
|
+
}
|
401
|
+
|
402
|
+
if (hasRule('python:S1172')) {
|
403
|
+
markdownContent += '- **未使用的参数**: 删除未使用的函数参数,或者在参数名前添加下划线\n';
|
404
|
+
}
|
405
|
+
|
406
|
+
if (hasRule('python:S5806')) {
|
407
|
+
markdownContent += '- **不必要的lambda**: 使用函数引用替代只调用另一个函数的lambda\n';
|
408
|
+
}
|
409
|
+
|
410
|
+
// 添加通用建议
|
411
|
+
markdownContent += '- **代码重复**: 提取重复代码为共享函数或类\n';
|
412
|
+
markdownContent += '- **复杂函数**: 将大型函数拆分为更小的函数,每个函数只做一件事\n';
|
413
|
+
markdownContent += '- **注释**: 为复杂逻辑添加清晰的注释,解释"为什么"而不仅仅是"做什么"\n';
|
414
|
+
} else {
|
415
|
+
markdownContent += '## 没有发现问题\n\n恭喜!SonarCloud没有检测到任何问题。';
|
416
|
+
}
|
417
|
+
|
418
|
+
// 保存Markdown文件
|
419
|
+
fs.writeFileSync('sonar_report.md', markdownContent);
|
420
|
+
|
421
|
+
console.log('已生成SonarCloud问题报告');
|
422
|
+
|
423
|
+
- name: Upload SonarCloud Issues Report
|
424
|
+
if: always()
|
425
|
+
uses: actions/upload-artifact@v4
|
426
|
+
with:
|
427
|
+
name: sonarcloud-issues
|
428
|
+
path: |
|
429
|
+
sonar_issues.json
|
430
|
+
sonar_report.md
|
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.15.1](https://github.com/donghao1393/mcp-dbutils/compare/v0.15.0...v0.15.1) (2025-03-14)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* ensure SonarCloud reports are generated even when analysis fails ([#40](https://github.com/donghao1393/mcp-dbutils/issues/40)) ([01d8a43](https://github.com/donghao1393/mcp-dbutils/commit/01d8a431f22079e621cc4160c210f3e8ce68a754)), closes [#39](https://github.com/donghao1393/mcp-dbutils/issues/39)
|
7
|
+
|
8
|
+
# [0.15.0](https://github.com/donghao1393/mcp-dbutils/compare/v0.14.0...v0.15.0) (2025-03-14)
|
9
|
+
|
10
|
+
|
11
|
+
### Features
|
12
|
+
|
13
|
+
* integrate Ruff code style automation ([#35](https://github.com/donghao1393/mcp-dbutils/issues/35)) ([6b2bdd7](https://github.com/donghao1393/mcp-dbutils/commit/6b2bdd749cecf2ad9167867c6e41149d1a57746f)), closes [#34](https://github.com/donghao1393/mcp-dbutils/issues/34)
|
14
|
+
|
1
15
|
# [0.14.0](https://github.com/donghao1393/mcp-dbutils/compare/v0.13.0...v0.14.0) (2025-03-14)
|
2
16
|
|
3
17
|
|
@@ -1,3 +1,28 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: mcp-dbutils
|
3
|
+
Version: 0.15.1
|
4
|
+
Summary: MCP Database Utilities Service
|
5
|
+
Author: Dong Hao
|
6
|
+
License-Expression: MIT
|
7
|
+
License-File: LICENSE
|
8
|
+
Requires-Python: >=3.10
|
9
|
+
Requires-Dist: mcp>=1.2.1
|
10
|
+
Requires-Dist: mysql-connector-python>=8.2.0
|
11
|
+
Requires-Dist: psycopg2-binary>=2.9.10
|
12
|
+
Requires-Dist: python-dotenv>=1.0.1
|
13
|
+
Requires-Dist: pyyaml>=6.0.2
|
14
|
+
Provides-Extra: test
|
15
|
+
Requires-Dist: aiosqlite>=0.19.0; extra == 'test'
|
16
|
+
Requires-Dist: docker>=7.0.0; extra == 'test'
|
17
|
+
Requires-Dist: pre-commit>=3.6.0; extra == 'test'
|
18
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
|
19
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
|
20
|
+
Requires-Dist: pytest-docker>=2.0.0; extra == 'test'
|
21
|
+
Requires-Dist: pytest>=7.0.0; extra == 'test'
|
22
|
+
Requires-Dist: ruff>=0.3.0; extra == 'test'
|
23
|
+
Requires-Dist: testcontainers>=3.7.0; extra == 'test'
|
24
|
+
Description-Content-Type: text/markdown
|
25
|
+
|
1
26
|
# MCP Database Utilities
|
2
27
|
|
3
28
|

|
@@ -460,6 +485,19 @@ Our CI/CD pipeline automatically performs:
|
|
460
485
|
|
461
486
|
Pull requests that don't meet these standards will be automatically blocked from merging.
|
462
487
|
|
488
|
+
### Code Style
|
489
|
+
We use Ruff for code style checking and formatting:
|
490
|
+
|
491
|
+
[](https://github.com/astral-sh/ruff)
|
492
|
+
|
493
|
+
All code must follow our style guide:
|
494
|
+
- Line length: 88 characters
|
495
|
+
- Indentation: 4 spaces
|
496
|
+
- Quotes: Double quotes
|
497
|
+
- Naming: PEP8 conventions
|
498
|
+
|
499
|
+
For detailed guidelines, see [STYLE_GUIDE.md](docs/STYLE_GUIDE.md).
|
500
|
+
|
463
501
|
### Local Development
|
464
502
|
To check code quality locally:
|
465
503
|
1. Run tests with coverage:
|
@@ -468,6 +506,44 @@ To check code quality locally:
|
|
468
506
|
```
|
469
507
|
2. Use SonarLint in your IDE to catch issues early
|
470
508
|
3. Review SonarCloud analysis results in PR comments
|
509
|
+
4. Run Ruff for code style checking:
|
510
|
+
```bash
|
511
|
+
# Install Ruff
|
512
|
+
uv pip install ruff
|
513
|
+
|
514
|
+
# Check code style
|
515
|
+
ruff check .
|
516
|
+
|
517
|
+
# Format code
|
518
|
+
ruff format .
|
519
|
+
```
|
520
|
+
5. Use pre-commit hooks for automatic checks:
|
521
|
+
```bash
|
522
|
+
# Install pre-commit
|
523
|
+
uv pip install pre-commit
|
524
|
+
pre-commit install
|
525
|
+
|
526
|
+
# Run all checks
|
527
|
+
pre-commit run --all-files
|
528
|
+
```
|
529
|
+
|
530
|
+
### SonarCloud AI Integration
|
531
|
+
We've implemented an AI-assisted workflow for fixing SonarCloud issues:
|
532
|
+
|
533
|
+
1. Our CI/CD pipeline automatically extracts SonarCloud analysis results
|
534
|
+
2. Results are formatted into both JSON and Markdown formats
|
535
|
+
3. These reports can be downloaded using the provided Fish function
|
536
|
+
4. The reports can then be provided to AI tools for analysis and fix suggestions
|
537
|
+
|
538
|
+
For detailed instructions, see [SonarCloud AI Integration Guide](docs/sonarcloud-ai-integration.md).
|
539
|
+
|
540
|
+
```bash
|
541
|
+
# Load the function
|
542
|
+
source scripts/sonar-ai-fix.fish
|
543
|
+
|
544
|
+
# Download the latest SonarCloud analysis reports
|
545
|
+
sonar-ai-fix
|
546
|
+
```
|
471
547
|
|
472
548
|
## Contributing
|
473
549
|
Contributions are welcome! Here's how you can help:
|
@@ -1,26 +1,3 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: mcp-dbutils
|
3
|
-
Version: 0.14.0
|
4
|
-
Summary: MCP Database Utilities Service
|
5
|
-
Author: Dong Hao
|
6
|
-
License-Expression: MIT
|
7
|
-
License-File: LICENSE
|
8
|
-
Requires-Python: >=3.10
|
9
|
-
Requires-Dist: mcp>=1.2.1
|
10
|
-
Requires-Dist: mysql-connector-python>=8.2.0
|
11
|
-
Requires-Dist: psycopg2-binary>=2.9.10
|
12
|
-
Requires-Dist: python-dotenv>=1.0.1
|
13
|
-
Requires-Dist: pyyaml>=6.0.2
|
14
|
-
Provides-Extra: test
|
15
|
-
Requires-Dist: aiosqlite>=0.19.0; extra == 'test'
|
16
|
-
Requires-Dist: docker>=7.0.0; extra == 'test'
|
17
|
-
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
|
18
|
-
Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
|
19
|
-
Requires-Dist: pytest-docker>=2.0.0; extra == 'test'
|
20
|
-
Requires-Dist: pytest>=7.0.0; extra == 'test'
|
21
|
-
Requires-Dist: testcontainers>=3.7.0; extra == 'test'
|
22
|
-
Description-Content-Type: text/markdown
|
23
|
-
|
24
1
|
# MCP Database Utilities
|
25
2
|
|
26
3
|

|
@@ -483,6 +460,19 @@ Our CI/CD pipeline automatically performs:
|
|
483
460
|
|
484
461
|
Pull requests that don't meet these standards will be automatically blocked from merging.
|
485
462
|
|
463
|
+
### Code Style
|
464
|
+
We use Ruff for code style checking and formatting:
|
465
|
+
|
466
|
+
[](https://github.com/astral-sh/ruff)
|
467
|
+
|
468
|
+
All code must follow our style guide:
|
469
|
+
- Line length: 88 characters
|
470
|
+
- Indentation: 4 spaces
|
471
|
+
- Quotes: Double quotes
|
472
|
+
- Naming: PEP8 conventions
|
473
|
+
|
474
|
+
For detailed guidelines, see [STYLE_GUIDE.md](docs/STYLE_GUIDE.md).
|
475
|
+
|
486
476
|
### Local Development
|
487
477
|
To check code quality locally:
|
488
478
|
1. Run tests with coverage:
|
@@ -491,6 +481,44 @@ To check code quality locally:
|
|
491
481
|
```
|
492
482
|
2. Use SonarLint in your IDE to catch issues early
|
493
483
|
3. Review SonarCloud analysis results in PR comments
|
484
|
+
4. Run Ruff for code style checking:
|
485
|
+
```bash
|
486
|
+
# Install Ruff
|
487
|
+
uv pip install ruff
|
488
|
+
|
489
|
+
# Check code style
|
490
|
+
ruff check .
|
491
|
+
|
492
|
+
# Format code
|
493
|
+
ruff format .
|
494
|
+
```
|
495
|
+
5. Use pre-commit hooks for automatic checks:
|
496
|
+
```bash
|
497
|
+
# Install pre-commit
|
498
|
+
uv pip install pre-commit
|
499
|
+
pre-commit install
|
500
|
+
|
501
|
+
# Run all checks
|
502
|
+
pre-commit run --all-files
|
503
|
+
```
|
504
|
+
|
505
|
+
### SonarCloud AI Integration
|
506
|
+
We've implemented an AI-assisted workflow for fixing SonarCloud issues:
|
507
|
+
|
508
|
+
1. Our CI/CD pipeline automatically extracts SonarCloud analysis results
|
509
|
+
2. Results are formatted into both JSON and Markdown formats
|
510
|
+
3. These reports can be downloaded using the provided Fish function
|
511
|
+
4. The reports can then be provided to AI tools for analysis and fix suggestions
|
512
|
+
|
513
|
+
For detailed instructions, see [SonarCloud AI Integration Guide](docs/sonarcloud-ai-integration.md).
|
514
|
+
|
515
|
+
```bash
|
516
|
+
# Load the function
|
517
|
+
source scripts/sonar-ai-fix.fish
|
518
|
+
|
519
|
+
# Download the latest SonarCloud analysis reports
|
520
|
+
sonar-ai-fix
|
521
|
+
```
|
494
522
|
|
495
523
|
## Contributing
|
496
524
|
Contributions are welcome! Here's how you can help:
|
@@ -419,6 +419,89 @@ except Exception as e:
|
|
419
419
|
- SSL/TLS安全连接
|
420
420
|
- URL和标准连接方式
|
421
421
|
|
422
|
+
## 代码质量
|
423
|
+
|
424
|
+
### 质量门禁
|
425
|
+
我们使用SonarCloud维持高代码质量标准。所有的Pull Request必须通过以下质量门禁:
|
426
|
+
|
427
|
+
- 代码覆盖率:≥ 80%
|
428
|
+
- 代码质量:
|
429
|
+
* 无阻塞级和严重级问题
|
430
|
+
* 主要问题数少于10个
|
431
|
+
* 代码重复率 < 3%
|
432
|
+
- 安全性:
|
433
|
+
* 无安全漏洞
|
434
|
+
* 无安全热点问题
|
435
|
+
|
436
|
+
### 自动化检查
|
437
|
+
我们的CI/CD流程自动执行:
|
438
|
+
1. 完整测试套件运行
|
439
|
+
2. 代码覆盖率分析
|
440
|
+
3. SonarCloud静态代码分析
|
441
|
+
4. 质量门禁验证
|
442
|
+
|
443
|
+
不符合这些标准的Pull Request将被自动阻止合并。
|
444
|
+
|
445
|
+
### 代码风格
|
446
|
+
我们使用Ruff进行代码风格检查和格式化:
|
447
|
+
|
448
|
+
[](https://github.com/astral-sh/ruff)
|
449
|
+
|
450
|
+
所有代码必须遵循我们的风格指南:
|
451
|
+
- 行长度:88个字符
|
452
|
+
- 缩进:4个空格
|
453
|
+
- 引号:双引号
|
454
|
+
- 命名:PEP8约定
|
455
|
+
|
456
|
+
详细指南请参见[STYLE_GUIDE.md](docs/STYLE_GUIDE.md)。
|
457
|
+
|
458
|
+
### 本地开发
|
459
|
+
本地检查代码质量:
|
460
|
+
1. 运行带覆盖率的测试:
|
461
|
+
```bash
|
462
|
+
pytest --cov=src/mcp_dbutils --cov-report=xml:coverage.xml tests/
|
463
|
+
```
|
464
|
+
2. 在IDE中使用SonarLint及早发现问题
|
465
|
+
3. 在PR评论中查看SonarCloud分析结果
|
466
|
+
4. 运行Ruff进行代码风格检查:
|
467
|
+
```bash
|
468
|
+
# 安装Ruff
|
469
|
+
uv pip install ruff
|
470
|
+
|
471
|
+
# 检查代码风格
|
472
|
+
ruff check .
|
473
|
+
|
474
|
+
# 格式化代码
|
475
|
+
ruff format .
|
476
|
+
```
|
477
|
+
5. 使用pre-commit钩子进行自动检查:
|
478
|
+
```bash
|
479
|
+
# 安装pre-commit
|
480
|
+
uv pip install pre-commit
|
481
|
+
pre-commit install
|
482
|
+
|
483
|
+
# 运行所有检查
|
484
|
+
pre-commit run --all-files
|
485
|
+
```
|
486
|
+
|
487
|
+
### SonarCloud AI 集成
|
488
|
+
我们实现了一个AI辅助的SonarCloud问题修复工作流:
|
489
|
+
|
490
|
+
1. 我们的CI/CD流程自动提取SonarCloud分析结果
|
491
|
+
2. 结果被格式化为JSON和Markdown两种格式
|
492
|
+
3. 这些报告可以使用提供的Fish函数下载
|
493
|
+
4. 然后可以将报告提供给AI工具进行分析和修复建议
|
494
|
+
|
495
|
+
详细说明请参见[SonarCloud AI集成指南](docs/sonarcloud-ai-integration.md)。
|
496
|
+
|
497
|
+
```bash
|
498
|
+
# 加载函数
|
499
|
+
source scripts/sonar-ai-fix.fish
|
500
|
+
|
501
|
+
# 下载最新的SonarCloud分析报告
|
502
|
+
sonar-ai-fix
|
503
|
+
```
|
504
|
+
|
422
505
|
## 参与贡献
|
423
506
|
欢迎贡献!以下是参与项目的方式:
|
424
507
|
|
@@ -0,0 +1,119 @@
|
|
1
|
+
[project]
|
2
|
+
name = "mcp-dbutils"
|
3
|
+
version = "0.15.1"
|
4
|
+
description = "MCP Database Utilities Service"
|
5
|
+
readme = "README.md"
|
6
|
+
license = "MIT"
|
7
|
+
authors = [
|
8
|
+
{name = "Dong Hao"}
|
9
|
+
]
|
10
|
+
dependencies = [
|
11
|
+
"mcp>=1.2.1",
|
12
|
+
"psycopg2-binary>=2.9.10",
|
13
|
+
"python-dotenv>=1.0.1",
|
14
|
+
"pyyaml>=6.0.2",
|
15
|
+
"mysql-connector-python>=8.2.0",
|
16
|
+
]
|
17
|
+
requires-python = ">=3.10"
|
18
|
+
|
19
|
+
[build-system]
|
20
|
+
requires = ["hatchling"]
|
21
|
+
build-backend = "hatchling.build"
|
22
|
+
|
23
|
+
[project.scripts]
|
24
|
+
mcp-dbutils = "mcp_dbutils:main"
|
25
|
+
|
26
|
+
[tool.semantic_release]
|
27
|
+
version_variables = [
|
28
|
+
"pyproject.toml:project.version"
|
29
|
+
]
|
30
|
+
version_toml = [
|
31
|
+
"pyproject.toml:project.version"
|
32
|
+
]
|
33
|
+
commit_parser = "conventional"
|
34
|
+
major_on_zero = false
|
35
|
+
branch = "main"
|
36
|
+
changelog_components = "semantic_release.changelog.changelog"
|
37
|
+
build_command = "uv build"
|
38
|
+
|
39
|
+
[project.optional-dependencies]
|
40
|
+
test = [
|
41
|
+
"pytest>=7.0.0",
|
42
|
+
"pytest-asyncio>=0.23.0",
|
43
|
+
"pytest-docker>=2.0.0",
|
44
|
+
"docker>=7.0.0",
|
45
|
+
"aiosqlite>=0.19.0",
|
46
|
+
"testcontainers>=3.7.0",
|
47
|
+
"pytest-cov>=4.1.0",
|
48
|
+
"ruff>=0.3.0",
|
49
|
+
"pre-commit>=3.6.0"
|
50
|
+
]
|
51
|
+
|
52
|
+
[tool.pytest.ini_options]
|
53
|
+
asyncio_mode = "strict"
|
54
|
+
asyncio_default_fixture_loop_scope = "function"
|
55
|
+
markers = [
|
56
|
+
"no_collect: marks test classes that should not be collected as test cases"
|
57
|
+
]
|
58
|
+
filterwarnings = [
|
59
|
+
"ignore::pytest.PytestCollectionWarning"
|
60
|
+
]
|
61
|
+
|
62
|
+
# Ruff配置
|
63
|
+
[tool.ruff]
|
64
|
+
# 目标Python版本
|
65
|
+
target-version = "0.15.1"
|
66
|
+
# 行长度限制
|
67
|
+
line-length = 88
|
68
|
+
# 排除的文件和目录
|
69
|
+
exclude = [
|
70
|
+
".git",
|
71
|
+
".venv",
|
72
|
+
"__pycache__",
|
73
|
+
"build",
|
74
|
+
"dist",
|
75
|
+
]
|
76
|
+
|
77
|
+
# Lint配置
|
78
|
+
[tool.ruff.lint]
|
79
|
+
# 选择的规则集
|
80
|
+
select = [
|
81
|
+
"E", # pycodestyle错误
|
82
|
+
"F", # pyflakes
|
83
|
+
"I", # isort
|
84
|
+
"N", # pep8-naming
|
85
|
+
"UP", # pyupgrade
|
86
|
+
"B", # flake8-bugbear
|
87
|
+
"C4", # flake8-comprehensions
|
88
|
+
"SIM", # flake8-simplify
|
89
|
+
"T20", # flake8-print
|
90
|
+
]
|
91
|
+
# 忽略的规则 - 暂时忽略,后续PR中逐步修复
|
92
|
+
ignore = [
|
93
|
+
"E501", # 行太长
|
94
|
+
"B904", # 在except子句中使用raise ... from err
|
95
|
+
"UP035", # 使用新的typing语法
|
96
|
+
"UP006", # 使用新的类型注解语法
|
97
|
+
"UP007", # 使用X | Y替代Union
|
98
|
+
"F401", # 未使用的导入
|
99
|
+
"F541", # f-string没有占位符
|
100
|
+
"UP015", # 不必要的mode参数
|
101
|
+
"UP032", # 使用f-string替代format
|
102
|
+
"B905", # zip()没有strict参数
|
103
|
+
"SIM105", # 使用contextlib.suppress
|
104
|
+
"UP038", # 在isinstance调用中使用X | Y
|
105
|
+
"F821", # 未定义的名称
|
106
|
+
"F841", # 未使用的局部变量
|
107
|
+
"E402", # 模块级导入不在文件顶部
|
108
|
+
"T201", # print语句 - 在日志模块中是必要的
|
109
|
+
]
|
110
|
+
|
111
|
+
# isort配置
|
112
|
+
[tool.ruff.lint.isort]
|
113
|
+
known-first-party = ["mcp_dbutils"]
|
114
|
+
|
115
|
+
# 格式化配置
|
116
|
+
[tool.ruff.format]
|
117
|
+
quote-style = "double"
|
118
|
+
indent-style = "space"
|
119
|
+
line-ending = "auto"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env fish
|
2
|
+
|
3
|
+
function sonar-ai-fix
|
4
|
+
# 检查当前目录是否是项目目录
|
5
|
+
if not test -f "pyproject.toml"; or not test -d "src/mcp_dbutils"
|
6
|
+
echo "错误: 请在项目根目录运行此命令"
|
7
|
+
echo "当前目录不是mcp-dbutils项目目录"
|
8
|
+
return 1
|
9
|
+
end
|
10
|
+
|
11
|
+
# 下载最新的构件
|
12
|
+
echo "正在下载 SonarCloud 分析报告..."
|
13
|
+
|
14
|
+
# 获取最新的工作流运行ID
|
15
|
+
set RUN_ID (gh run list --workflow "Quality Assurance" --limit 1 --json databaseId --jq '.[0].databaseId')
|
16
|
+
|
17
|
+
if test -z "$RUN_ID"
|
18
|
+
echo "错误: 无法获取最新的工作流运行ID"
|
19
|
+
return 1
|
20
|
+
end
|
21
|
+
|
22
|
+
# 创建临时目录存放下载的文件
|
23
|
+
set TEMP_DIR (mktemp -d)
|
24
|
+
|
25
|
+
# 下载构件
|
26
|
+
gh run download $RUN_ID --name sonarcloud-issues --dir $TEMP_DIR
|
27
|
+
|
28
|
+
if test $status -ne 0
|
29
|
+
echo "错误: 下载构件失败"
|
30
|
+
rm -rf $TEMP_DIR
|
31
|
+
return 1
|
32
|
+
end
|
33
|
+
|
34
|
+
# 检查文件是否存在
|
35
|
+
if not test -f "$TEMP_DIR/sonar_report.md"
|
36
|
+
echo "错误: 未找到 sonar_report.md 文件"
|
37
|
+
rm -rf $TEMP_DIR
|
38
|
+
return 1
|
39
|
+
end
|
40
|
+
|
41
|
+
if not test -f "$TEMP_DIR/sonar_issues.json"
|
42
|
+
echo "错误: 未找到 sonar_issues.json 文件"
|
43
|
+
rm -rf $TEMP_DIR
|
44
|
+
return 1
|
45
|
+
end
|
46
|
+
|
47
|
+
# 复制文件到当前目录
|
48
|
+
cp "$TEMP_DIR/sonar_report.md" ./sonar_report.md
|
49
|
+
cp "$TEMP_DIR/sonar_issues.json" ./sonar_issues.json
|
50
|
+
|
51
|
+
# 清理临时目录
|
52
|
+
rm -rf $TEMP_DIR
|
53
|
+
|
54
|
+
echo "已下载 SonarCloud 分析报告:"
|
55
|
+
echo "- sonar_report.md: Markdown格式的报告,适合人类阅读"
|
56
|
+
echo "- sonar_issues.json: JSON格式的原始数据,适合AI处理"
|
57
|
+
echo ""
|
58
|
+
echo "使用方法:"
|
59
|
+
echo "1. 查看报告: cat sonar_report.md"
|
60
|
+
echo "2. 提供给AI: 将sonar_report.md的内容复制给AI,请求修复建议"
|
61
|
+
echo "3. 高级分析: 将sonar_issues.json提供给AI进行更深入的分析"
|
62
|
+
end
|