django-clade 0.0.5__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.
- django_clade-0.0.5/.codecov.yml +92 -0
- django_clade-0.0.5/.gitignore +176 -0
- django_clade-0.0.5/.gitlab/issue_templates/bug.md +60 -0
- django_clade-0.0.5/.gitlab/issue_templates/decision.md +65 -0
- django_clade-0.0.5/.gitlab/issue_templates/feature.md +61 -0
- django_clade-0.0.5/.gitlab/issue_templates/maintenance.md +58 -0
- django_clade-0.0.5/.gitlab/merge_request_templates/default.md +42 -0
- django_clade-0.0.5/.gitlab-ci.yml +148 -0
- django_clade-0.0.5/.tox-config/coverage-version.txt +9 -0
- django_clade-0.0.5/.tox-config/requirements/base-dj52.txt +4 -0
- django_clade-0.0.5/.tox-config/requirements/base-djlatest.txt +4 -0
- django_clade-0.0.5/.tox-config/requirements/full.txt +10 -0
- django_clade-0.0.5/.tox-config/requirements/linter.txt +2 -0
- django_clade-0.0.5/.tox-config/requirements/type-check.txt +3 -0
- django_clade-0.0.5/.tox-config/scripts/coverage.sh +89 -0
- django_clade-0.0.5/.tox-config/scripts/test.sh +90 -0
- django_clade-0.0.5/.tox-config/versions.txt +25 -0
- django_clade-0.0.5/CHANGELOG.md +26 -0
- django_clade-0.0.5/CODE_DE_CONDUITE.md +43 -0
- django_clade-0.0.5/CODE_OF_CONDUCT.md +39 -0
- django_clade-0.0.5/CONTRIBUTING.fr.md +99 -0
- django_clade-0.0.5/CONTRIBUTING.md +99 -0
- django_clade-0.0.5/LICENSE.txt +173 -0
- django_clade-0.0.5/NOTICE +12 -0
- django_clade-0.0.5/PKG-INFO +282 -0
- django_clade-0.0.5/README.fr.md +72 -0
- django_clade-0.0.5/README.md +70 -0
- django_clade-0.0.5/SECURITY.md +38 -0
- django_clade-0.0.5/codecov.yml +92 -0
- django_clade-0.0.5/pyproject.toml +309 -0
- django_clade-0.0.5/src/clade/__init__.py +0 -0
- django_clade-0.0.5/uv.lock +761 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# .codecov.yml — Clade project
|
|
3
|
+
# Coverage reporting configuration for codecov.io
|
|
4
|
+
#
|
|
5
|
+
# Validate: curl -X POST --data-binary @.codecov.yml https://codecov.io/validate
|
|
6
|
+
#
|
|
7
|
+
# Refs: DD-006 (test strategy), DD-009 (toolchain)
|
|
8
|
+
# GitLab: #6, #9
|
|
9
|
+
# =============================================================================
|
|
10
|
+
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# Coverage targets
|
|
13
|
+
# -----------------------------------------------------------------------------
|
|
14
|
+
coverage:
|
|
15
|
+
precision: 2
|
|
16
|
+
round: down
|
|
17
|
+
status:
|
|
18
|
+
project:
|
|
19
|
+
default:
|
|
20
|
+
target: 80% # minimum acceptable project coverage (DD-006)
|
|
21
|
+
threshold: 1% # allow 1% drop before reporting a failure
|
|
22
|
+
patch:
|
|
23
|
+
default:
|
|
24
|
+
target: 80% # new code in each MR must meet the same target
|
|
25
|
+
threshold: 1%
|
|
26
|
+
|
|
27
|
+
# -----------------------------------------------------------------------------
|
|
28
|
+
# Components — coverage by conceptual area (DD-001 to DD-004)
|
|
29
|
+
# Paths will be populated as the module grows.
|
|
30
|
+
# -----------------------------------------------------------------------------
|
|
31
|
+
component_management:
|
|
32
|
+
default_rules:
|
|
33
|
+
statuses:
|
|
34
|
+
- type: project
|
|
35
|
+
target: 80%
|
|
36
|
+
threshold: 1%
|
|
37
|
+
|
|
38
|
+
individual_components:
|
|
39
|
+
|
|
40
|
+
- component_id: node_tree
|
|
41
|
+
name: "Node Tree" # DD-001 — core tree model
|
|
42
|
+
paths:
|
|
43
|
+
- "src/clade/models/**"
|
|
44
|
+
- "src/clade/tree/**"
|
|
45
|
+
|
|
46
|
+
- component_id: kinship
|
|
47
|
+
name: "Kinship queries" # DD-002 — parent, sibling, pibling, nibling…
|
|
48
|
+
paths:
|
|
49
|
+
- "src/clade/kinship/**"
|
|
50
|
+
- "src/clade/relations/**"
|
|
51
|
+
|
|
52
|
+
- component_id: backends
|
|
53
|
+
name: "Backends" # DD-003 — ltree + fallback
|
|
54
|
+
paths:
|
|
55
|
+
- "src/clade/backends/**"
|
|
56
|
+
|
|
57
|
+
- component_id: affinity
|
|
58
|
+
name: "Affinity" # DD-004 — lateral shared-attribute grouping
|
|
59
|
+
paths:
|
|
60
|
+
- "src/clade/affinity/**"
|
|
61
|
+
|
|
62
|
+
# -----------------------------------------------------------------------------
|
|
63
|
+
# Flags — by test type
|
|
64
|
+
# -----------------------------------------------------------------------------
|
|
65
|
+
flags:
|
|
66
|
+
unittests:
|
|
67
|
+
paths:
|
|
68
|
+
- src/clade/
|
|
69
|
+
carryforward: true
|
|
70
|
+
|
|
71
|
+
# -----------------------------------------------------------------------------
|
|
72
|
+
# Ignored paths
|
|
73
|
+
# -----------------------------------------------------------------------------
|
|
74
|
+
ignore:
|
|
75
|
+
- "src/clade/migrations/**"
|
|
76
|
+
- "tests/**"
|
|
77
|
+
- "docs/**"
|
|
78
|
+
|
|
79
|
+
# -----------------------------------------------------------------------------
|
|
80
|
+
# MR comments
|
|
81
|
+
# -----------------------------------------------------------------------------
|
|
82
|
+
comment:
|
|
83
|
+
layout: "reach,diff,components,flags,files"
|
|
84
|
+
behavior: default
|
|
85
|
+
require_changes: true
|
|
86
|
+
|
|
87
|
+
# -----------------------------------------------------------------------------
|
|
88
|
+
# Codecov behaviour
|
|
89
|
+
# -----------------------------------------------------------------------------
|
|
90
|
+
codecov:
|
|
91
|
+
notify:
|
|
92
|
+
after_n_builds: 1 # raise to 8 when full matrix is active
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
.python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
110
|
+
.pdm.toml
|
|
111
|
+
.pdm-python
|
|
112
|
+
.pdm-build/
|
|
113
|
+
|
|
114
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
115
|
+
__pypackages__/
|
|
116
|
+
|
|
117
|
+
# Celery stuff
|
|
118
|
+
celerybeat-schedule
|
|
119
|
+
celerybeat.pid
|
|
120
|
+
|
|
121
|
+
# SageMath parsed files
|
|
122
|
+
*.sage.py
|
|
123
|
+
|
|
124
|
+
# Environments
|
|
125
|
+
.env
|
|
126
|
+
.venv
|
|
127
|
+
env/
|
|
128
|
+
venv/
|
|
129
|
+
ENV/
|
|
130
|
+
env.bak/
|
|
131
|
+
venv.bak/
|
|
132
|
+
|
|
133
|
+
# uv
|
|
134
|
+
.uv/
|
|
135
|
+
# uv.lock is intentionally not committed for a distributed module
|
|
136
|
+
# (consumers manage their own dependency resolution).
|
|
137
|
+
# uv.lock
|
|
138
|
+
|
|
139
|
+
# Pyright
|
|
140
|
+
.pyright/
|
|
141
|
+
|
|
142
|
+
# Extended environment files
|
|
143
|
+
.env.*
|
|
144
|
+
!.env.example
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# Spyder project settings
|
|
148
|
+
.spyderproject
|
|
149
|
+
.spyproject
|
|
150
|
+
|
|
151
|
+
# Rope project settings
|
|
152
|
+
.ropeproject
|
|
153
|
+
|
|
154
|
+
# mkdocs documentation
|
|
155
|
+
/site
|
|
156
|
+
|
|
157
|
+
# mypy
|
|
158
|
+
.mypy_cache/
|
|
159
|
+
.dmypy.json
|
|
160
|
+
dmypy.json
|
|
161
|
+
|
|
162
|
+
# Pyre type checker
|
|
163
|
+
.pyre/
|
|
164
|
+
|
|
165
|
+
# pytype static type analyzer
|
|
166
|
+
.pytype/
|
|
167
|
+
|
|
168
|
+
# Cython debug symbols
|
|
169
|
+
cython_debug/
|
|
170
|
+
|
|
171
|
+
# PyCharm
|
|
172
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
173
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
174
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
175
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
176
|
+
.idea/
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# 🐛 Bug Report
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
<!-- One sentence: what happens vs what should happen. -->
|
|
6
|
+
|
|
7
|
+
**Observed:**
|
|
8
|
+
**Expected:**
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Reproduction steps
|
|
13
|
+
|
|
14
|
+
<!-- Minimal Python code reproducing the issue (MCVE). A failing pytest is ideal. -->
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Environment
|
|
23
|
+
|
|
24
|
+
| Field | Value |
|
|
25
|
+
|---|---|
|
|
26
|
+
| **Package version** | <!-- output of: pip show hierarchy \| grep Version --> |
|
|
27
|
+
| **Python version** | <!-- output of: python --version --> |
|
|
28
|
+
| **Django version** | <!-- output of: python -m django --version --> |
|
|
29
|
+
| **OS** | <!-- Linux / macOS / Windows --> |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Affected scope
|
|
34
|
+
|
|
35
|
+
<!-- Check all that apply -->
|
|
36
|
+
|
|
37
|
+
- [ ] `api` — public interface
|
|
38
|
+
- [ ] `docs` — docstrings, examples
|
|
39
|
+
- [ ] `tests` — pytest, coverage
|
|
40
|
+
- [ ] `ci` — pipeline
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Severity
|
|
45
|
+
|
|
46
|
+
<!-- Remove the lines that do not apply -->
|
|
47
|
+
|
|
48
|
+
- **high** — unhandled exception, data corruption, public regression
|
|
49
|
+
- **medium** — incorrect behaviour, workaround available
|
|
50
|
+
- **low** — cosmetic, imprecise error message
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Additional context
|
|
55
|
+
|
|
56
|
+
<!-- Full traceback, logs, pip freeze output, etc. -->
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
/label ~"type: bug" ~"status: triage" ~"priority: high"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 🧭 Design Decision (DD)
|
|
2
|
+
|
|
3
|
+
## DD Identifier
|
|
4
|
+
|
|
5
|
+
<!-- Three-digit sequential number — check existing closed DD issues for the next available.
|
|
6
|
+
Format: DD-NNN -->
|
|
7
|
+
|
|
8
|
+
**DD-NNN**
|
|
9
|
+
|
|
10
|
+
## Target version
|
|
11
|
+
|
|
12
|
+
<!-- Project version where this decision takes effect (= milestone) -->
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
<!-- Why is this decision necessary?
|
|
19
|
+
What constraint, gap, or opportunity motivates it? -->
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Options considered
|
|
24
|
+
|
|
25
|
+
| Option | Advantage | Risk |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| **A** — | | |
|
|
28
|
+
| **B** — | | |
|
|
29
|
+
| **C** — | | |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Decision
|
|
34
|
+
|
|
35
|
+
<!-- The chosen option and a brief justification. -->
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Consequences
|
|
40
|
+
|
|
41
|
+
<!-- Impact on the public API, dependencies, tests,
|
|
42
|
+
backward compatibility, or future decisions. -->
|
|
43
|
+
|
|
44
|
+
- Related: <!-- #xx (DD-NNN) -->
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Affected scopes
|
|
49
|
+
|
|
50
|
+
- [ ] `api` — public interface
|
|
51
|
+
- [ ] `docs` — docstrings, guides
|
|
52
|
+
- [ ] `tests` — pytest, coverage
|
|
53
|
+
- [ ] `ci` — pipeline
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Closing checklist
|
|
58
|
+
|
|
59
|
+
- [ ] Affected modules are identified
|
|
60
|
+
- [ ] Implementation issues / MRs are linked
|
|
61
|
+
- [ ] The `status: closed` label has been applied
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
/label ~"type: decision" ~"status: triage"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# ✨ Feature Request
|
|
2
|
+
|
|
3
|
+
## Why?
|
|
4
|
+
|
|
5
|
+
<!-- What problem does this feature solve?
|
|
6
|
+
Which use case is currently impossible or cumbersome? -->
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## What?
|
|
11
|
+
|
|
12
|
+
<!-- Precise description of the desired feature. -->
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Acceptance criteria
|
|
17
|
+
|
|
18
|
+
<!-- Verifiable conditions — each should map to a test or doc test. -->
|
|
19
|
+
|
|
20
|
+
- [ ] `pytest` passes — coverage ≥ 80%
|
|
21
|
+
- [ ] `ruff` and `pyright`: 0 errors
|
|
22
|
+
- [ ] Existing public API unchanged (or breaking change documented)
|
|
23
|
+
- [ ] `CHANGELOG.md` updated
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## API sketch (optional)
|
|
28
|
+
|
|
29
|
+
<!-- Proposed signatures, usage examples, or configuration structure. -->
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Related Design Decisions
|
|
38
|
+
|
|
39
|
+
<!-- DD issue numbers covering the associated architecture choices -->
|
|
40
|
+
|
|
41
|
+
Refs: <!-- #xx (DD-NNN) -->
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Affected scope
|
|
46
|
+
|
|
47
|
+
- [ ] `api` — public interface
|
|
48
|
+
- [ ] `docs` — docstrings, guides
|
|
49
|
+
- [ ] `tests` — pytest, coverage
|
|
50
|
+
- [ ] `ci` — pipeline
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Breaking change?
|
|
55
|
+
|
|
56
|
+
- [ ] No — backward-compatible
|
|
57
|
+
- [ ] Yes — requires a minor or major version bump
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
/label ~"type: feature" ~"status: triage"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# 🔧 Maintenance
|
|
2
|
+
|
|
3
|
+
## Task type
|
|
4
|
+
|
|
5
|
+
<!-- Remove the lines that do not apply, then update the label below -->
|
|
6
|
+
|
|
7
|
+
- **chore** — dependencies, housekeeping, configuration
|
|
8
|
+
- **docs** — docstrings, README, guides, examples
|
|
9
|
+
- **test** — adding or fixing tests, coverage
|
|
10
|
+
- **refactor** — restructuring without behaviour change
|
|
11
|
+
- **ci** — pipeline, tox, GitLab CI
|
|
12
|
+
- **perf** — performance optimisation
|
|
13
|
+
- **deprecation** — mark obsolete code with deprecation warnings
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Description
|
|
18
|
+
|
|
19
|
+
<!-- What needs to be done, and why now? -->
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Completion criteria
|
|
24
|
+
|
|
25
|
+
- [ ] `tox -e lint,type,security` exits 0
|
|
26
|
+
- [ ] `pytest` passes
|
|
27
|
+
- [ ] Coverage ≥ 80%
|
|
28
|
+
- [ ] `CHANGELOG.md` updated if necessary
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Urgency (optional)
|
|
33
|
+
|
|
34
|
+
<!-- Why now rather than later?
|
|
35
|
+
E.g.: CVE, blocking technical debt, prerequisite for a feature. -->
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Dependency update detail (optional)
|
|
40
|
+
|
|
41
|
+
<!-- Fill in only for a dependency-update chore -->
|
|
42
|
+
|
|
43
|
+
| Package | Before | After | Breaking? |
|
|
44
|
+
|---|---|---|---|
|
|
45
|
+
| | | | |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Affected scope
|
|
50
|
+
|
|
51
|
+
- [ ] `api` — public interface
|
|
52
|
+
- [ ] `docs` — docstrings, guides
|
|
53
|
+
- [ ] `tests` — pytest, coverage
|
|
54
|
+
- [ ] `ci` — pipeline
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
/label ~"status: triage"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Description
|
|
2
|
+
|
|
3
|
+
<!-- Brief description of the changes and their motivation.
|
|
4
|
+
What does this MR do, and why? -->
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Related issue
|
|
9
|
+
|
|
10
|
+
Closes #<!-- issue number -->
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Type of change
|
|
15
|
+
|
|
16
|
+
<!-- Remove the lines that do not apply -->
|
|
17
|
+
|
|
18
|
+
- **feat** — new feature
|
|
19
|
+
- **fix** — bug fix
|
|
20
|
+
- **docs** — documentation only
|
|
21
|
+
- **chore** — build, deps, configuration
|
|
22
|
+
- **refactor** — code restructuring, no behaviour change
|
|
23
|
+
- **test** — adding or fixing tests
|
|
24
|
+
- **ci** — pipeline changes
|
|
25
|
+
- **perf** — performance improvement
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Checklist
|
|
30
|
+
|
|
31
|
+
- [ ] `tox -e lint,type,security` exits 0 locally
|
|
32
|
+
- [ ] `pytest` passes locally
|
|
33
|
+
- [ ] Coverage ≥ 80% (no regression)
|
|
34
|
+
- [ ] `CHANGELOG.md` updated under `[Unreleased]`
|
|
35
|
+
- [ ] Issue linked with `Closes #xx`
|
|
36
|
+
- [ ] Breaking change documented (if applicable)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Notes for reviewer (optional)
|
|
41
|
+
|
|
42
|
+
<!-- Anything that needs special attention during review. -->
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# .gitlab-ci.yml — Hierarchy project
|
|
3
|
+
#
|
|
4
|
+
# Jobs:
|
|
5
|
+
# lint — Ruff (every push)
|
|
6
|
+
# type — Pyright (every push)
|
|
7
|
+
# security — Bandit (every push)
|
|
8
|
+
# test — pytest + pytest-cov, full matrix (tag push only)
|
|
9
|
+
#
|
|
10
|
+
# Refs: DD-006 (test strategy), DD-009 (toolchain)
|
|
11
|
+
# GitLab: #6, #9
|
|
12
|
+
# =============================================================================
|
|
13
|
+
|
|
14
|
+
default:
|
|
15
|
+
image: python:3.12-slim
|
|
16
|
+
|
|
17
|
+
variables:
|
|
18
|
+
UV_VERSION: "latest"
|
|
19
|
+
PIP_NO_CACHE_DIR: "1"
|
|
20
|
+
|
|
21
|
+
# -----------------------------------------------------------------------------
|
|
22
|
+
# Pipeline rules
|
|
23
|
+
# -----------------------------------------------------------------------------
|
|
24
|
+
workflow:
|
|
25
|
+
rules:
|
|
26
|
+
- if: $CI_COMMIT_BRANCH # every push on any branch
|
|
27
|
+
- if: $CI_COMMIT_TAG # every tag push
|
|
28
|
+
|
|
29
|
+
# -----------------------------------------------------------------------------
|
|
30
|
+
# Stages
|
|
31
|
+
# -----------------------------------------------------------------------------
|
|
32
|
+
stages:
|
|
33
|
+
- quality # lint, type, security — fast, runs on every push
|
|
34
|
+
- test # pytest full matrix — runs on tag only (DD-006)
|
|
35
|
+
|
|
36
|
+
# -----------------------------------------------------------------------------
|
|
37
|
+
# Shared setup — install uv and the project dev dependencies
|
|
38
|
+
# -----------------------------------------------------------------------------
|
|
39
|
+
.setup: &setup
|
|
40
|
+
before_script:
|
|
41
|
+
- pip install uv --quiet
|
|
42
|
+
- uv venv --quiet
|
|
43
|
+
- source .venv/bin/activate
|
|
44
|
+
- uv pip install -e ".[dev]" --quiet
|
|
45
|
+
|
|
46
|
+
# -----------------------------------------------------------------------------
|
|
47
|
+
# Quality stage — every push
|
|
48
|
+
# -----------------------------------------------------------------------------
|
|
49
|
+
lint:
|
|
50
|
+
stage: quality
|
|
51
|
+
<<: *setup
|
|
52
|
+
script:
|
|
53
|
+
- ruff check .
|
|
54
|
+
- ruff format --check .
|
|
55
|
+
rules:
|
|
56
|
+
- if: $CI_COMMIT_BRANCH
|
|
57
|
+
- if: $CI_COMMIT_TAG
|
|
58
|
+
|
|
59
|
+
type:
|
|
60
|
+
stage: quality
|
|
61
|
+
<<: *setup
|
|
62
|
+
script:
|
|
63
|
+
- pyright
|
|
64
|
+
rules:
|
|
65
|
+
- if: $CI_COMMIT_BRANCH
|
|
66
|
+
- if: $CI_COMMIT_TAG
|
|
67
|
+
|
|
68
|
+
security:
|
|
69
|
+
stage: quality
|
|
70
|
+
<<: *setup
|
|
71
|
+
script:
|
|
72
|
+
- bandit -c pyproject.toml -r hierarchy
|
|
73
|
+
rules:
|
|
74
|
+
- if: $CI_COMMIT_BRANCH
|
|
75
|
+
- if: $CI_COMMIT_TAG
|
|
76
|
+
|
|
77
|
+
# -----------------------------------------------------------------------------
|
|
78
|
+
# Test stage — tag push only (DD-006)
|
|
79
|
+
# Full matrix: Python 3.10–3.13 × Django 5.2 LTS + Django latest
|
|
80
|
+
# -----------------------------------------------------------------------------
|
|
81
|
+
.test_base:
|
|
82
|
+
stage: test
|
|
83
|
+
script:
|
|
84
|
+
- pip install uv --quiet
|
|
85
|
+
- uv venv --quiet
|
|
86
|
+
- source .venv/bin/activate
|
|
87
|
+
- uv pip install django${DJANGO_VERSION} pytest pytest-django pytest-cov --quiet
|
|
88
|
+
- uv pip install -e . --quiet
|
|
89
|
+
- pytest --cov=hierarchy --cov-report=term-missing --cov-report=xml
|
|
90
|
+
coverage: '/TOTAL.*\s+(\d+%)$/'
|
|
91
|
+
artifacts:
|
|
92
|
+
reports:
|
|
93
|
+
coverage_report:
|
|
94
|
+
coverage_format: cobertura
|
|
95
|
+
path: coverage.xml
|
|
96
|
+
expire_in: 1 week
|
|
97
|
+
rules:
|
|
98
|
+
- if: $CI_COMMIT_TAG
|
|
99
|
+
|
|
100
|
+
# Django 5.2 LTS
|
|
101
|
+
test-py310-dj52:
|
|
102
|
+
extends: .test_base
|
|
103
|
+
image: python:3.10-slim
|
|
104
|
+
variables:
|
|
105
|
+
DJANGO_VERSION: "~=5.2"
|
|
106
|
+
|
|
107
|
+
test-py311-dj52:
|
|
108
|
+
extends: .test_base
|
|
109
|
+
image: python:3.11-slim
|
|
110
|
+
variables:
|
|
111
|
+
DJANGO_VERSION: "~=5.2"
|
|
112
|
+
|
|
113
|
+
test-py312-dj52:
|
|
114
|
+
extends: .test_base
|
|
115
|
+
image: python:3.12-slim
|
|
116
|
+
variables:
|
|
117
|
+
DJANGO_VERSION: "~=5.2"
|
|
118
|
+
|
|
119
|
+
test-py313-dj52:
|
|
120
|
+
extends: .test_base
|
|
121
|
+
image: python:3.13-slim
|
|
122
|
+
variables:
|
|
123
|
+
DJANGO_VERSION: "~=5.2"
|
|
124
|
+
|
|
125
|
+
# Django latest
|
|
126
|
+
test-py310-djlatest:
|
|
127
|
+
extends: .test_base
|
|
128
|
+
image: python:3.10-slim
|
|
129
|
+
variables:
|
|
130
|
+
DJANGO_VERSION: ""
|
|
131
|
+
|
|
132
|
+
test-py311-djlatest:
|
|
133
|
+
extends: .test_base
|
|
134
|
+
image: python:3.11-slim
|
|
135
|
+
variables:
|
|
136
|
+
DJANGO_VERSION: ""
|
|
137
|
+
|
|
138
|
+
test-py312-djlatest:
|
|
139
|
+
extends: .test_base
|
|
140
|
+
image: python:3.12-slim
|
|
141
|
+
variables:
|
|
142
|
+
DJANGO_VERSION: ""
|
|
143
|
+
|
|
144
|
+
test-py313-djlatest:
|
|
145
|
+
extends: .test_base
|
|
146
|
+
image: python:3.13-slim
|
|
147
|
+
variables:
|
|
148
|
+
DJANGO_VERSION: ""
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# .tox-config/coverage-version.txt — Hierarchy project
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Version Python utilisée pour générer le rapport de couverture.
|
|
5
|
+
# Une seule version active (première ligne non commentée).
|
|
6
|
+
# Doit correspondre à un environnement défini dans pyproject.toml.
|
|
7
|
+
# =============================================================================
|
|
8
|
+
|
|
9
|
+
py312-dj52
|