baobab-ai-dev-git 0.1.0__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.
- baobab_ai_dev_git-0.1.0/LICENSE +21 -0
- baobab_ai_dev_git-0.1.0/PKG-INFO +290 -0
- baobab_ai_dev_git-0.1.0/README.md +254 -0
- baobab_ai_dev_git-0.1.0/pyproject.toml +94 -0
- baobab_ai_dev_git-0.1.0/setup.cfg +4 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/__init__.py +75 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/__init__.py +1 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/branch_hierarchy_validator.py +83 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/branch_name.py +31 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/branch_name_builder.py +120 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/branch_name_parser.py +62 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/branch_name_validator.py +77 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/branch_service.py +116 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/branch/branch_type.py +20 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/domain/__init__.py +7 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/__init__.py +29 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/branch_already_exists_error.py +16 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/branch_not_found_error.py +16 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/git_operation_error.py +15 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/github_integration_error.py +15 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/github_operation_error.py +15 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/invalid_branch_hierarchy_error.py +23 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/invalid_branch_name_error.py +15 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/invalid_pull_request_target_error.py +17 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/merge_not_allowed_error.py +23 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/exceptions/repository_dirty_error.py +13 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/__init__.py +21 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_check_run_info.py +20 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_client_port.py +71 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_pull_request_adapter.py +216 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_pull_request_api_client.py +69 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_pull_request_info.py +32 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_repository_adapter.py +130 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_repository_api_client.py +31 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/github/github_repository_info.py +23 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/policy/__init__.py +1 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/policy/branch_policy.py +25 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/policy/branch_policy_service.py +56 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/policy/merge_policy_service.py +123 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/policy/pull_request_policy.py +19 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/policy/pull_request_policy_service.py +44 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/pull_request/__init__.py +1 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/pull_request/pull_request_service.py +150 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/pull_request/pull_request_target_resolver.py +149 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/pull_request/pull_request_validator.py +73 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/report/__init__.py +9 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/report/git_compliance_report.py +52 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/report/git_compliance_report_builder.py +175 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/repository/__init__.py +1 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/repository/git_command_runner.py +61 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/repository/git_repository_service.py +137 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/repository/git_repository_state_reader.py +164 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/result/__init__.py +15 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/result/branch_validation_result.py +39 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/result/git_operation_result.py +52 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/result/merge_eligibility_result.py +41 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/result/pull_request_creation_result.py +48 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/result/pull_request_validation_result.py +44 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git/result/serializable_result.py +14 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git.egg-info/PKG-INFO +290 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git.egg-info/SOURCES.txt +62 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git.egg-info/dependency_links.txt +1 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git.egg-info/requires.txt +10 -0
- baobab_ai_dev_git-0.1.0/src/baobab_ai_dev_git.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 baobabgit
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: baobab-ai-dev-git
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Librairie Python de gestion Git pour l'écosystème Baobab AI Dev.
|
|
5
|
+
Author: Baobab AI Dev
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/baobabgit/baobab-ai-dev-git
|
|
8
|
+
Project-URL: Documentation, https://github.com/baobabgit/baobab-ai-dev-git/blob/main/README.md
|
|
9
|
+
Project-URL: Repository, https://github.com/baobabgit/baobab-ai-dev-git
|
|
10
|
+
Project-URL: Issues, https://github.com/baobabgit/baobab-ai-dev-git/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/baobabgit/baobab-ai-dev-git/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: git,github,baobab,workflow,branches,pull-request,developer-tools
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.12
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: baobab-ai-dev-core<2,>=1.1.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: bandit>=1.7; extra == "dev"
|
|
29
|
+
Requires-Dist: black>=24.0; extra == "dev"
|
|
30
|
+
Requires-Dist: coverage>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
32
|
+
Requires-Dist: pylint>=3.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# baobab-ai-dev-git
|
|
38
|
+
|
|
39
|
+
Librairie Python de gestion Git pour l'écosystème **Baobab AI Dev**.
|
|
40
|
+
|
|
41
|
+
Elle permet à une IA de développement (ou à un outil CLI/workflow) de piloter les opérations Git d'un projet structuré en **user stories**, **features** et **backlogs**, avec des règles hiérarchiques explicites et testables.
|
|
42
|
+
|
|
43
|
+
Spécification complète : [`docs/01-cahier-des-charges.md`](docs/01-cahier-des-charges.md).
|
|
44
|
+
|
|
45
|
+
## Rôle dans l'écosystème
|
|
46
|
+
|
|
47
|
+
| Module | Rôle |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `baobab-ai-dev-core` | Objets métier partagés (`UserStory`, `Feature`, `Backlog`, …) |
|
|
50
|
+
| **`baobab-ai-dev-git`** | Conventions de branches, validation PR, éligibilité au merge, Git local |
|
|
51
|
+
| `baobab-ai-dev-workflow` | Orchestration des runs IA |
|
|
52
|
+
| `baobab-ai-dev-cli` | Interface en ligne de commande |
|
|
53
|
+
|
|
54
|
+
Cette librairie **ne dépend pas** du backend API, du frontend, de la base de données ni des providers IA.
|
|
55
|
+
|
|
56
|
+
## Dépendance `baobab-ai-dev-core`
|
|
57
|
+
|
|
58
|
+
Les entités métier `UserStory`, `Feature` et `Backlog` sont fournies par [`baobab-ai-dev-core`](https://pypi.org/project/baobab-ai-dev-core/) (≥ 1.1.0), réexportées via `baobab_ai_dev_git.domain` pour compatibilité.
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from baobab_ai_dev_git.domain import Backlog, Feature, UserStory
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Les services Git (`BranchNameBuilder`, `BranchService`, …) consomment ces entités officielles. Consultez la documentation de `baobab-ai-dev-core` pour la construction complète (identifiants, statuts, critères d'acceptation, branche Git associée).
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
Prérequis : Python **≥ 3.12** (requis par `baobab-ai-dev-core`), Git disponible dans le `PATH`.
|
|
69
|
+
|
|
70
|
+
Depuis PyPI :
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install baobab-ai-dev-git
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Depuis les sources (développement) :
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
git clone https://github.com/baobabgit/baobab-ai-dev-git.git
|
|
80
|
+
cd baobab-ai-dev-git
|
|
81
|
+
python -m pip install -e ".[dev]"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Publication : voir [`docs/RELEASE.md`](docs/RELEASE.md).
|
|
85
|
+
|
|
86
|
+
Vérification rapide :
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python -c "import baobab_ai_dev_git as git; print(git.__version__)"
|
|
90
|
+
pytest -q
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## API publique
|
|
94
|
+
|
|
95
|
+
Les symboles stables sont exportés depuis le package racine :
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
import baobab_ai_dev_git as git
|
|
99
|
+
|
|
100
|
+
print(git.__all__)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Services et types principaux :
|
|
104
|
+
|
|
105
|
+
| Symbole | Rôle |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `BranchNameBuilder` | Génère un nom de branche conforme à partir d'un objet métier |
|
|
108
|
+
| `BranchNameValidator` | Valide le format d'un nom de branche |
|
|
109
|
+
| `BranchService` | Crée des branches locales en respectant la hiérarchie |
|
|
110
|
+
| `PullRequestValidator` | Vérifie la cible d'une Pull Request |
|
|
111
|
+
| `PullRequestService` | Prépare et crée une PR (port GitHub injectable) |
|
|
112
|
+
| `MergePolicyService` | Évalue l'éligibilité au merge |
|
|
113
|
+
| `GitOperationResult`, `MergeEligibilityResult`, … | Résultats typés sérialisables |
|
|
114
|
+
| `GitComplianceReport`, `GitComplianceReportBuilder` | Diagnostic de conformité Git |
|
|
115
|
+
| `GithubClientPort`, `GithubPullRequestAdapter`, `GithubRepositoryAdapter` | Intégration GitHub abstraite |
|
|
116
|
+
| `MergeNotAllowedError`, `BranchNotFoundError`, `BranchAlreadyExistsError`, `RepositoryDirtyError`, `GithubIntegrationError`, … | Exceptions métier explicites |
|
|
117
|
+
|
|
118
|
+
## Conventions de branches
|
|
119
|
+
|
|
120
|
+
Hiérarchie obligatoire :
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
main
|
|
124
|
+
└── us/<US-ID>-<slug>
|
|
125
|
+
└── feat/<US-ID>/<FEAT-ID>-<slug>
|
|
126
|
+
└── bl/<FEAT-ID>/<BL-ID>-<slug>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Règles de Pull Request :
|
|
130
|
+
|
|
131
|
+
| Branche source | Branche cible attendue |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `bl/...` | Sa branche feature parente |
|
|
134
|
+
| `feat/...` | Sa branche user story parente |
|
|
135
|
+
| `us/...` | `main` |
|
|
136
|
+
|
|
137
|
+
Exemples de noms générés :
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from baobab_ai_dev_git import BranchNameBuilder
|
|
141
|
+
from baobab_ai_dev_git.domain import Backlog, Feature, UserStory
|
|
142
|
+
|
|
143
|
+
builder = BranchNameBuilder()
|
|
144
|
+
|
|
145
|
+
# Entités baobab-ai-dev-core — champs requis : code, title, branch_name, etc.
|
|
146
|
+
# Voir tests/helpers/core_entities.py pour des factories de test minimales.
|
|
147
|
+
us = ... # UserStory avec code US-001 et titre normalisé
|
|
148
|
+
feat = ... # Feature liée à us/US-001/...
|
|
149
|
+
bl = ... # Backlog lié à feat/FEAT-001/...
|
|
150
|
+
|
|
151
|
+
print(builder.build_user_story_branch(us))
|
|
152
|
+
# us/US-001-initialiser-module-git
|
|
153
|
+
|
|
154
|
+
print(builder.build_feature_branch(feat))
|
|
155
|
+
# feat/US-001/FEAT-001-gestion-branches
|
|
156
|
+
|
|
157
|
+
print(builder.build_backlog_branch(bl))
|
|
158
|
+
# bl/FEAT-001/BL-001-validator
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Les slugs sont normalisés : minuscules, sans accents, espaces → tirets.
|
|
162
|
+
|
|
163
|
+
## Exemples d'usage
|
|
164
|
+
|
|
165
|
+
### Valider une cible de Pull Request
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from baobab_ai_dev_git import PullRequestValidator
|
|
169
|
+
|
|
170
|
+
validator = PullRequestValidator()
|
|
171
|
+
known = [
|
|
172
|
+
"main",
|
|
173
|
+
"us/US-001-initialiser-module-git",
|
|
174
|
+
"feat/US-001/FEAT-001-gestion-branches",
|
|
175
|
+
"bl/FEAT-001/BL-001-validator",
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
result = validator.validate(
|
|
179
|
+
"bl/FEAT-001/BL-001-validator",
|
|
180
|
+
"feat/US-001/FEAT-001-gestion-branches",
|
|
181
|
+
known_branches=known,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
if result.is_valid:
|
|
185
|
+
print("Cible PR conforme")
|
|
186
|
+
else:
|
|
187
|
+
print(result.errors)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Évaluer l'éligibilité au merge
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from baobab_ai_dev_git import MergePolicyService
|
|
194
|
+
|
|
195
|
+
service = MergePolicyService()
|
|
196
|
+
eligibility = service.evaluate_merge_eligibility(
|
|
197
|
+
source_branch="bl/FEAT-001/BL-001-validator",
|
|
198
|
+
target_branch="feat/US-001/FEAT-001-gestion-branches",
|
|
199
|
+
known_branches=known,
|
|
200
|
+
quality_checks={"pytest": True, "ruff": True, "mypy": True},
|
|
201
|
+
open_branches=[],
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
print(eligibility.merge_allowed)
|
|
205
|
+
print(eligibility.to_dict())
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Un merge est refusé si des branches enfants restent ouvertes (ex. backlogs non mergés avant leur feature).
|
|
209
|
+
|
|
210
|
+
### Créer une branche backlog locale
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from baobab_ai_dev_git import BranchService
|
|
214
|
+
from baobab_ai_dev_git.domain import Backlog
|
|
215
|
+
|
|
216
|
+
service = BranchService()
|
|
217
|
+
backlog = ... # Backlog core FEAT-008 / BL-022
|
|
218
|
+
|
|
219
|
+
result = service.create_backlog_branch(
|
|
220
|
+
backlog,
|
|
221
|
+
parent_branch="feat/US-008/FEAT-008-socle-technique-transversal",
|
|
222
|
+
cwd="/chemin/vers/le/depot",
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
if result.success:
|
|
226
|
+
print(f"Branche créée : {result.branch_name}")
|
|
227
|
+
else:
|
|
228
|
+
print(result.errors)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Exemple de workflow IA
|
|
232
|
+
|
|
233
|
+
Scénario type pour une IA qui développe un backlog :
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
1. Lire le backlog (ex. BL-022) et sa feature parente (FEAT-008).
|
|
237
|
+
2. Construire le nom de branche avec BranchNameBuilder.
|
|
238
|
+
3. Créer la branche via BranchService.create_backlog_branch().
|
|
239
|
+
4. Développer sur bl/<FEAT-ID>/<BL-ID>-<slug> uniquement.
|
|
240
|
+
5. Avant d'ouvrir une PR :
|
|
241
|
+
- PullRequestValidator → vérifier la cible feat/<US-ID>/...
|
|
242
|
+
- MergePolicyService → vérifier checks qualité + absence de branches enfants ouvertes.
|
|
243
|
+
6. Si merge_allowed est False → corriger (tests, branches dépendantes) sans tenter le merge.
|
|
244
|
+
7. Sérialiser les résultats (to_dict()) pour les rapports du workflow IA.
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Pseudo-code :
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
import baobab_ai_dev_git as git
|
|
251
|
+
|
|
252
|
+
backlog = ... # Backlog core
|
|
253
|
+
parent = "feat/US-008/FEAT-008-socle-technique-transversal"
|
|
254
|
+
|
|
255
|
+
branch_name = git.BranchNameBuilder().build_backlog_branch(backlog)
|
|
256
|
+
creation = git.BranchService().create_backlog_branch(backlog, parent_branch=parent)
|
|
257
|
+
|
|
258
|
+
pr_check = git.PullRequestValidator().validate(branch_name, parent, known_branches=[parent, branch_name])
|
|
259
|
+
merge_check = git.MergePolicyService().evaluate_merge_eligibility(
|
|
260
|
+
branch_name,
|
|
261
|
+
parent,
|
|
262
|
+
known_branches=[parent, branch_name],
|
|
263
|
+
quality_checks={"pytest": True, "ruff": True},
|
|
264
|
+
open_branches=[],
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
report = {
|
|
268
|
+
"branch": branch_name,
|
|
269
|
+
"created": creation.to_dict(),
|
|
270
|
+
"pr_valid": pr_check.to_dict(),
|
|
271
|
+
"merge_eligible": merge_check.to_dict(),
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Qualité et tests
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
pytest
|
|
279
|
+
ruff check .
|
|
280
|
+
mypy src
|
|
281
|
+
black --check src tests
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Couverture minimale attendue : **90 %** (voir `pyproject.toml`).
|
|
285
|
+
|
|
286
|
+
## Documentation
|
|
287
|
+
|
|
288
|
+
- Cahier des charges : [`docs/01-cahier-des-charges.md`](docs/01-cahier-des-charges.md)
|
|
289
|
+
- Backlogs et features : [`docs/04-backlogs/`](docs/04-backlogs/), [`docs/03-features/`](docs/03-features/)
|
|
290
|
+
- Décisions d'architecture : [`docs/ia_workflow/decisions/`](docs/ia_workflow/decisions/)
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# baobab-ai-dev-git
|
|
2
|
+
|
|
3
|
+
Librairie Python de gestion Git pour l'écosystème **Baobab AI Dev**.
|
|
4
|
+
|
|
5
|
+
Elle permet à une IA de développement (ou à un outil CLI/workflow) de piloter les opérations Git d'un projet structuré en **user stories**, **features** et **backlogs**, avec des règles hiérarchiques explicites et testables.
|
|
6
|
+
|
|
7
|
+
Spécification complète : [`docs/01-cahier-des-charges.md`](docs/01-cahier-des-charges.md).
|
|
8
|
+
|
|
9
|
+
## Rôle dans l'écosystème
|
|
10
|
+
|
|
11
|
+
| Module | Rôle |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `baobab-ai-dev-core` | Objets métier partagés (`UserStory`, `Feature`, `Backlog`, …) |
|
|
14
|
+
| **`baobab-ai-dev-git`** | Conventions de branches, validation PR, éligibilité au merge, Git local |
|
|
15
|
+
| `baobab-ai-dev-workflow` | Orchestration des runs IA |
|
|
16
|
+
| `baobab-ai-dev-cli` | Interface en ligne de commande |
|
|
17
|
+
|
|
18
|
+
Cette librairie **ne dépend pas** du backend API, du frontend, de la base de données ni des providers IA.
|
|
19
|
+
|
|
20
|
+
## Dépendance `baobab-ai-dev-core`
|
|
21
|
+
|
|
22
|
+
Les entités métier `UserStory`, `Feature` et `Backlog` sont fournies par [`baobab-ai-dev-core`](https://pypi.org/project/baobab-ai-dev-core/) (≥ 1.1.0), réexportées via `baobab_ai_dev_git.domain` pour compatibilité.
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from baobab_ai_dev_git.domain import Backlog, Feature, UserStory
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Les services Git (`BranchNameBuilder`, `BranchService`, …) consomment ces entités officielles. Consultez la documentation de `baobab-ai-dev-core` pour la construction complète (identifiants, statuts, critères d'acceptation, branche Git associée).
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
Prérequis : Python **≥ 3.12** (requis par `baobab-ai-dev-core`), Git disponible dans le `PATH`.
|
|
33
|
+
|
|
34
|
+
Depuis PyPI :
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install baobab-ai-dev-git
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Depuis les sources (développement) :
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git clone https://github.com/baobabgit/baobab-ai-dev-git.git
|
|
44
|
+
cd baobab-ai-dev-git
|
|
45
|
+
python -m pip install -e ".[dev]"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Publication : voir [`docs/RELEASE.md`](docs/RELEASE.md).
|
|
49
|
+
|
|
50
|
+
Vérification rapide :
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
python -c "import baobab_ai_dev_git as git; print(git.__version__)"
|
|
54
|
+
pytest -q
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## API publique
|
|
58
|
+
|
|
59
|
+
Les symboles stables sont exportés depuis le package racine :
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
import baobab_ai_dev_git as git
|
|
63
|
+
|
|
64
|
+
print(git.__all__)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Services et types principaux :
|
|
68
|
+
|
|
69
|
+
| Symbole | Rôle |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `BranchNameBuilder` | Génère un nom de branche conforme à partir d'un objet métier |
|
|
72
|
+
| `BranchNameValidator` | Valide le format d'un nom de branche |
|
|
73
|
+
| `BranchService` | Crée des branches locales en respectant la hiérarchie |
|
|
74
|
+
| `PullRequestValidator` | Vérifie la cible d'une Pull Request |
|
|
75
|
+
| `PullRequestService` | Prépare et crée une PR (port GitHub injectable) |
|
|
76
|
+
| `MergePolicyService` | Évalue l'éligibilité au merge |
|
|
77
|
+
| `GitOperationResult`, `MergeEligibilityResult`, … | Résultats typés sérialisables |
|
|
78
|
+
| `GitComplianceReport`, `GitComplianceReportBuilder` | Diagnostic de conformité Git |
|
|
79
|
+
| `GithubClientPort`, `GithubPullRequestAdapter`, `GithubRepositoryAdapter` | Intégration GitHub abstraite |
|
|
80
|
+
| `MergeNotAllowedError`, `BranchNotFoundError`, `BranchAlreadyExistsError`, `RepositoryDirtyError`, `GithubIntegrationError`, … | Exceptions métier explicites |
|
|
81
|
+
|
|
82
|
+
## Conventions de branches
|
|
83
|
+
|
|
84
|
+
Hiérarchie obligatoire :
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
main
|
|
88
|
+
└── us/<US-ID>-<slug>
|
|
89
|
+
└── feat/<US-ID>/<FEAT-ID>-<slug>
|
|
90
|
+
└── bl/<FEAT-ID>/<BL-ID>-<slug>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Règles de Pull Request :
|
|
94
|
+
|
|
95
|
+
| Branche source | Branche cible attendue |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `bl/...` | Sa branche feature parente |
|
|
98
|
+
| `feat/...` | Sa branche user story parente |
|
|
99
|
+
| `us/...` | `main` |
|
|
100
|
+
|
|
101
|
+
Exemples de noms générés :
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from baobab_ai_dev_git import BranchNameBuilder
|
|
105
|
+
from baobab_ai_dev_git.domain import Backlog, Feature, UserStory
|
|
106
|
+
|
|
107
|
+
builder = BranchNameBuilder()
|
|
108
|
+
|
|
109
|
+
# Entités baobab-ai-dev-core — champs requis : code, title, branch_name, etc.
|
|
110
|
+
# Voir tests/helpers/core_entities.py pour des factories de test minimales.
|
|
111
|
+
us = ... # UserStory avec code US-001 et titre normalisé
|
|
112
|
+
feat = ... # Feature liée à us/US-001/...
|
|
113
|
+
bl = ... # Backlog lié à feat/FEAT-001/...
|
|
114
|
+
|
|
115
|
+
print(builder.build_user_story_branch(us))
|
|
116
|
+
# us/US-001-initialiser-module-git
|
|
117
|
+
|
|
118
|
+
print(builder.build_feature_branch(feat))
|
|
119
|
+
# feat/US-001/FEAT-001-gestion-branches
|
|
120
|
+
|
|
121
|
+
print(builder.build_backlog_branch(bl))
|
|
122
|
+
# bl/FEAT-001/BL-001-validator
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Les slugs sont normalisés : minuscules, sans accents, espaces → tirets.
|
|
126
|
+
|
|
127
|
+
## Exemples d'usage
|
|
128
|
+
|
|
129
|
+
### Valider une cible de Pull Request
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from baobab_ai_dev_git import PullRequestValidator
|
|
133
|
+
|
|
134
|
+
validator = PullRequestValidator()
|
|
135
|
+
known = [
|
|
136
|
+
"main",
|
|
137
|
+
"us/US-001-initialiser-module-git",
|
|
138
|
+
"feat/US-001/FEAT-001-gestion-branches",
|
|
139
|
+
"bl/FEAT-001/BL-001-validator",
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
result = validator.validate(
|
|
143
|
+
"bl/FEAT-001/BL-001-validator",
|
|
144
|
+
"feat/US-001/FEAT-001-gestion-branches",
|
|
145
|
+
known_branches=known,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if result.is_valid:
|
|
149
|
+
print("Cible PR conforme")
|
|
150
|
+
else:
|
|
151
|
+
print(result.errors)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Évaluer l'éligibilité au merge
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from baobab_ai_dev_git import MergePolicyService
|
|
158
|
+
|
|
159
|
+
service = MergePolicyService()
|
|
160
|
+
eligibility = service.evaluate_merge_eligibility(
|
|
161
|
+
source_branch="bl/FEAT-001/BL-001-validator",
|
|
162
|
+
target_branch="feat/US-001/FEAT-001-gestion-branches",
|
|
163
|
+
known_branches=known,
|
|
164
|
+
quality_checks={"pytest": True, "ruff": True, "mypy": True},
|
|
165
|
+
open_branches=[],
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
print(eligibility.merge_allowed)
|
|
169
|
+
print(eligibility.to_dict())
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Un merge est refusé si des branches enfants restent ouvertes (ex. backlogs non mergés avant leur feature).
|
|
173
|
+
|
|
174
|
+
### Créer une branche backlog locale
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from baobab_ai_dev_git import BranchService
|
|
178
|
+
from baobab_ai_dev_git.domain import Backlog
|
|
179
|
+
|
|
180
|
+
service = BranchService()
|
|
181
|
+
backlog = ... # Backlog core FEAT-008 / BL-022
|
|
182
|
+
|
|
183
|
+
result = service.create_backlog_branch(
|
|
184
|
+
backlog,
|
|
185
|
+
parent_branch="feat/US-008/FEAT-008-socle-technique-transversal",
|
|
186
|
+
cwd="/chemin/vers/le/depot",
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
if result.success:
|
|
190
|
+
print(f"Branche créée : {result.branch_name}")
|
|
191
|
+
else:
|
|
192
|
+
print(result.errors)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Exemple de workflow IA
|
|
196
|
+
|
|
197
|
+
Scénario type pour une IA qui développe un backlog :
|
|
198
|
+
|
|
199
|
+
```text
|
|
200
|
+
1. Lire le backlog (ex. BL-022) et sa feature parente (FEAT-008).
|
|
201
|
+
2. Construire le nom de branche avec BranchNameBuilder.
|
|
202
|
+
3. Créer la branche via BranchService.create_backlog_branch().
|
|
203
|
+
4. Développer sur bl/<FEAT-ID>/<BL-ID>-<slug> uniquement.
|
|
204
|
+
5. Avant d'ouvrir une PR :
|
|
205
|
+
- PullRequestValidator → vérifier la cible feat/<US-ID>/...
|
|
206
|
+
- MergePolicyService → vérifier checks qualité + absence de branches enfants ouvertes.
|
|
207
|
+
6. Si merge_allowed est False → corriger (tests, branches dépendantes) sans tenter le merge.
|
|
208
|
+
7. Sérialiser les résultats (to_dict()) pour les rapports du workflow IA.
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Pseudo-code :
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
import baobab_ai_dev_git as git
|
|
215
|
+
|
|
216
|
+
backlog = ... # Backlog core
|
|
217
|
+
parent = "feat/US-008/FEAT-008-socle-technique-transversal"
|
|
218
|
+
|
|
219
|
+
branch_name = git.BranchNameBuilder().build_backlog_branch(backlog)
|
|
220
|
+
creation = git.BranchService().create_backlog_branch(backlog, parent_branch=parent)
|
|
221
|
+
|
|
222
|
+
pr_check = git.PullRequestValidator().validate(branch_name, parent, known_branches=[parent, branch_name])
|
|
223
|
+
merge_check = git.MergePolicyService().evaluate_merge_eligibility(
|
|
224
|
+
branch_name,
|
|
225
|
+
parent,
|
|
226
|
+
known_branches=[parent, branch_name],
|
|
227
|
+
quality_checks={"pytest": True, "ruff": True},
|
|
228
|
+
open_branches=[],
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
report = {
|
|
232
|
+
"branch": branch_name,
|
|
233
|
+
"created": creation.to_dict(),
|
|
234
|
+
"pr_valid": pr_check.to_dict(),
|
|
235
|
+
"merge_eligible": merge_check.to_dict(),
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Qualité et tests
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
pytest
|
|
243
|
+
ruff check .
|
|
244
|
+
mypy src
|
|
245
|
+
black --check src tests
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Couverture minimale attendue : **90 %** (voir `pyproject.toml`).
|
|
249
|
+
|
|
250
|
+
## Documentation
|
|
251
|
+
|
|
252
|
+
- Cahier des charges : [`docs/01-cahier-des-charges.md`](docs/01-cahier-des-charges.md)
|
|
253
|
+
- Backlogs et features : [`docs/04-backlogs/`](docs/04-backlogs/), [`docs/03-features/`](docs/03-features/)
|
|
254
|
+
- Décisions d'architecture : [`docs/ia_workflow/decisions/`](docs/ia_workflow/decisions/)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "baobab-ai-dev-git"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Librairie Python de gestion Git pour l'écosystème Baobab AI Dev."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Baobab AI Dev" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"git",
|
|
15
|
+
"github",
|
|
16
|
+
"baobab",
|
|
17
|
+
"workflow",
|
|
18
|
+
"branches",
|
|
19
|
+
"pull-request",
|
|
20
|
+
"developer-tools",
|
|
21
|
+
]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 4 - Beta",
|
|
24
|
+
"Intended Audience :: Developers",
|
|
25
|
+
"License :: OSI Approved :: MIT License",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
31
|
+
"Topic :: Software Development :: Version Control :: Git",
|
|
32
|
+
"Typing :: Typed",
|
|
33
|
+
]
|
|
34
|
+
dependencies = [
|
|
35
|
+
"baobab-ai-dev-core>=1.1.0,<2",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/baobabgit/baobab-ai-dev-git"
|
|
40
|
+
Documentation = "https://github.com/baobabgit/baobab-ai-dev-git/blob/main/README.md"
|
|
41
|
+
Repository = "https://github.com/baobabgit/baobab-ai-dev-git"
|
|
42
|
+
Issues = "https://github.com/baobabgit/baobab-ai-dev-git/issues"
|
|
43
|
+
Changelog = "https://github.com/baobabgit/baobab-ai-dev-git/blob/main/CHANGELOG.md"
|
|
44
|
+
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
dev = [
|
|
47
|
+
"bandit>=1.7",
|
|
48
|
+
"black>=24.0",
|
|
49
|
+
"coverage>=7.0",
|
|
50
|
+
"mypy>=1.8",
|
|
51
|
+
"pylint>=3.0",
|
|
52
|
+
"pytest>=8.0",
|
|
53
|
+
"ruff>=0.4",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.packages.find]
|
|
57
|
+
where = ["src"]
|
|
58
|
+
|
|
59
|
+
[tool.pytest.ini_options]
|
|
60
|
+
testpaths = ["tests"]
|
|
61
|
+
pythonpath = ["src", "."]
|
|
62
|
+
|
|
63
|
+
[tool.coverage.run]
|
|
64
|
+
source = ["baobab_ai_dev_git"]
|
|
65
|
+
branch = true
|
|
66
|
+
|
|
67
|
+
[tool.coverage.report]
|
|
68
|
+
fail_under = 90
|
|
69
|
+
show_missing = true
|
|
70
|
+
|
|
71
|
+
[tool.mypy]
|
|
72
|
+
python_version = "3.12"
|
|
73
|
+
strict = true
|
|
74
|
+
packages = ["baobab_ai_dev_git"]
|
|
75
|
+
|
|
76
|
+
[tool.ruff]
|
|
77
|
+
target-version = "py312"
|
|
78
|
+
line-length = 100
|
|
79
|
+
|
|
80
|
+
[tool.ruff.lint]
|
|
81
|
+
select = ["E", "F", "I", "UP"]
|
|
82
|
+
|
|
83
|
+
[tool.black]
|
|
84
|
+
line-length = 100
|
|
85
|
+
target-version = ["py312"]
|
|
86
|
+
|
|
87
|
+
[tool.pylint.main]
|
|
88
|
+
py-version = "3.12"
|
|
89
|
+
|
|
90
|
+
[tool.pylint.format]
|
|
91
|
+
max-line-length = 100
|
|
92
|
+
|
|
93
|
+
[tool.pylint.messages_control]
|
|
94
|
+
disable = ["too-few-public-methods", "too-many-instance-attributes"]
|