feat(M1): échafaudage et outillage complétés
- .pre-commit-config.yaml : hooks ruff, mypy, bandit, detect-secrets, whitespace - .secrets.baseline : baseline detect-secrets (faux positif GUIDE_DEV_PYTHON.md) - pyproject.toml : migration clés ruff vers [tool.ruff.lint], exclusion guide du format - pip install -e ".[dev]" : dépendances installées dans le venv - pre-commit install : hook git installé - TODO.md : items M1 cochés Validations : - ruff check . : PASS - ruff format --check . : PASS - mypy . : PASS (17 fichiers) - pytest : PASS (0 test, infrastructure OK) - bandit -r pronote_sync/ : PASS - pre-commit run --all-files : 9 passed, 1 skipped, 0 failed - import pronote_sync : OK Co-authored-by: OpenCode/orchestrator <opencode-orchestrator@agents.invalid>
This commit is contained in:
60
.pre-commit-config.yaml
Normal file
60
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
# Hooks pre-commit pour pronote-sync
|
||||
# Installation : pre-commit install
|
||||
# Exécution manuelle : pre-commit run --all-files
|
||||
default_language_version:
|
||||
python: python3
|
||||
|
||||
repos:
|
||||
# Outils du venv (ruff, mypy, bandit) — exécutés dans l'environnement géré par pre-commit
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
name: ruff check
|
||||
entry: ruff check
|
||||
language: python
|
||||
additional_dependencies: ["ruff>=0.4.0"]
|
||||
types: [python]
|
||||
|
||||
- id: ruff-format
|
||||
name: ruff format
|
||||
entry: ruff format
|
||||
language: python
|
||||
additional_dependencies: ["ruff>=0.4.0"]
|
||||
types: [python]
|
||||
|
||||
- id: mypy
|
||||
name: mypy
|
||||
entry: mypy
|
||||
language: python
|
||||
additional_dependencies: ["mypy>=1.10.0"]
|
||||
types: [python]
|
||||
pass_filenames: true
|
||||
|
||||
- id: bandit
|
||||
name: bandit
|
||||
entry: bandit
|
||||
args: [-c, pyproject.toml, -r]
|
||||
language: python
|
||||
additional_dependencies: ["bandit>=1.7.0"]
|
||||
types: [python]
|
||||
|
||||
# Hooks standard de pre-commit
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
exclude: 'GUIDE_DEV_PYTHON\.md'
|
||||
- id: end-of-file-fixer
|
||||
exclude: 'GUIDE_DEV_PYTHON\.md'
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
args: [--maxkb=500]
|
||||
exclude: 'GUIDE_DEV_PYTHON\.md'
|
||||
- id: check-merge-conflict
|
||||
|
||||
# Détection de secrets
|
||||
- repo: https://github.com/Yelp/detect-secrets
|
||||
rev: v1.5.0
|
||||
hooks:
|
||||
- id: detect-secrets
|
||||
args: [--baseline, .secrets.baseline]
|
||||
144
.secrets.baseline
Normal file
144
.secrets.baseline
Normal file
@@ -0,0 +1,144 @@
|
||||
{
|
||||
"version": "1.5.0",
|
||||
"plugins_used": [
|
||||
{
|
||||
"name": "ArtifactoryDetector"
|
||||
},
|
||||
{
|
||||
"name": "AWSKeyDetector"
|
||||
},
|
||||
{
|
||||
"name": "AzureStorageKeyDetector"
|
||||
},
|
||||
{
|
||||
"name": "Base64HighEntropyString",
|
||||
"limit": 4.5
|
||||
},
|
||||
{
|
||||
"name": "BasicAuthDetector"
|
||||
},
|
||||
{
|
||||
"name": "CloudantDetector"
|
||||
},
|
||||
{
|
||||
"name": "DiscordBotTokenDetector"
|
||||
},
|
||||
{
|
||||
"name": "GitHubTokenDetector"
|
||||
},
|
||||
{
|
||||
"name": "GitLabTokenDetector"
|
||||
},
|
||||
{
|
||||
"name": "HexHighEntropyString",
|
||||
"limit": 3.0
|
||||
},
|
||||
{
|
||||
"name": "IbmCloudIamDetector"
|
||||
},
|
||||
{
|
||||
"name": "IbmCosHmacDetector"
|
||||
},
|
||||
{
|
||||
"name": "IPPublicDetector"
|
||||
},
|
||||
{
|
||||
"name": "JwtTokenDetector"
|
||||
},
|
||||
{
|
||||
"name": "KeywordDetector",
|
||||
"keyword_exclude": ""
|
||||
},
|
||||
{
|
||||
"name": "MailchimpDetector"
|
||||
},
|
||||
{
|
||||
"name": "NpmDetector"
|
||||
},
|
||||
{
|
||||
"name": "OpenAIDetector"
|
||||
},
|
||||
{
|
||||
"name": "PrivateKeyDetector"
|
||||
},
|
||||
{
|
||||
"name": "PypiTokenDetector"
|
||||
},
|
||||
{
|
||||
"name": "SendGridDetector"
|
||||
},
|
||||
{
|
||||
"name": "SlackDetector"
|
||||
},
|
||||
{
|
||||
"name": "SoftlayerDetector"
|
||||
},
|
||||
{
|
||||
"name": "SquareOAuthDetector"
|
||||
},
|
||||
{
|
||||
"name": "StripeDetector"
|
||||
},
|
||||
{
|
||||
"name": "TelegramBotTokenDetector"
|
||||
},
|
||||
{
|
||||
"name": "TwilioKeyDetector"
|
||||
}
|
||||
],
|
||||
"filters_used": [
|
||||
{
|
||||
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
|
||||
"min_level": 2
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_lock_file"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_sequential_string"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_swagger_file"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.heuristic.is_templated_secret"
|
||||
},
|
||||
{
|
||||
"path": "detect_secrets.filters.regex.should_exclude_file",
|
||||
"pattern": [
|
||||
"\\.venv/.*",
|
||||
"\\.git/.*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"results": {
|
||||
"GUIDE_DEV_PYTHON.md": [
|
||||
{
|
||||
"type": "Hex High Entropy String",
|
||||
"filename": "GUIDE_DEV_PYTHON.md",
|
||||
"hashed_secret": "90bd1b48e958257948487b90bee080ba5ed00caa",
|
||||
"is_verified": false,
|
||||
"line_number": 5073
|
||||
}
|
||||
]
|
||||
},
|
||||
"generated_at": "2026-09-05T17:53:24Z"
|
||||
}
|
||||
16
TODO.md
16
TODO.md
@@ -10,14 +10,14 @@
|
||||
|
||||
Mettre en place le dépôt, l'environnement, l'arborescence du package et la chaîne d'outils (lint/type/test/pré-commit).
|
||||
|
||||
- [ ] Créer l'environnement virtuel Python (≥ 3.13.5) et l'activer (`python -m venv venv`).
|
||||
- [ ] Créer `pyproject.toml` d'après l'Annexe C (projet `pronote-sync`, `requires-python = ">=3.13.5"`, dépendances, extras `dev` et `ai-litellm`, script console `pronote-sync`).
|
||||
- [ ] Configurer ruff (`line-length = 100`, `target-version = "py313"`, règles E/W/F/I/B/C4/UP), mypy (`strict`), bandit et coverage (`fail_under = 90`) dans `pyproject.toml`.
|
||||
- [ ] Créer `.gitignore` (venv, `__pycache__`, `.env`, `.blog_rss_state.json`, `.coverage`, artefacts `.ics` temporaires).
|
||||
- [ ] Créer l'arborescence `pronote_sync/` avec `__init__.py` dans chaque package (`config`, `models`, `sources/pronote`, `sources/blog`, `sources/theoretical`, `sync`, `synthesis`, `channels`, `pipeline/steps`, `cli`, `utils`, `tests`).
|
||||
- [ ] Ajouter la configuration pre-commit (ruff, mypy, bandit, detect-secrets, `trailing-whitespace`, `end-of-file`).
|
||||
- [ ] Installer le projet en mode éditable : `pip install -e ".[dev]"`.
|
||||
- [ ] Créer le commit initial (scaffold + `.gitignore`, sans aucun secret).
|
||||
- [x] Créer l'environnement virtuel Python (≥ 3.13.5) et l'activer (`python -m venv venv`).
|
||||
- [x] Créer `pyproject.toml` d'après l'Annexe C (projet `pronote-sync`, `requires-python = ">=3.13.5"`, dépendances, extras `dev` et `ai-litellm`, script console `pronote-sync`).
|
||||
- [x] Configurer ruff (`line-length = 100`, `target-version = "py313"`, règles E/W/F/I/B/C4/UP), mypy (`strict`), bandit et coverage (`fail_under = 90`) dans `pyproject.toml`.
|
||||
- [x] Créer `.gitignore` (venv, `__pycache__`, `.env`, `.blog_rss_state.json`, `.coverage`, artefacts `.ics` temporaires).
|
||||
- [x] Créer l'arborescence `pronote_sync/` avec `__init__.py` dans chaque package (`config`, `models`, `sources/pronote`, `sources/blog`, `sources/theoretical`, `sync`, `synthesis`, `channels`, `pipeline/steps`, `cli`, `utils`, `tests`).
|
||||
- [x] Ajouter la configuration pre-commit (ruff, mypy, bandit, detect-secrets, `trailing-whitespace`, `end-of-file`).
|
||||
- [x] Installer le projet en mode éditable : `pip install -e ".[dev]"`.
|
||||
- [x] Créer le commit initial (scaffold + `.gitignore`, sans aucun secret).
|
||||
|
||||
### Critères d'acceptation
|
||||
- Le package `pronote_sync` est importable sans erreur.
|
||||
|
||||
@@ -93,6 +93,10 @@ skips = ["B101"] # Ignorer les assertions (utilisées dans les tests)
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
target-version = "py313"
|
||||
# Exclure la documentation markdown (ruff format ne doit pas toucher aux blocs de code Python inclus)
|
||||
extend-exclude = ["GUIDE_DEV_PYTHON.md"]
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E", # pycodestyle errors
|
||||
"W", # pycodestyle warnings
|
||||
|
||||
Reference in New Issue
Block a user