Skip to content

Commit 7b5e0e2

Browse files
Merge branch 'main' into feat/improve-sphinx
2 parents 3be66e7 + d0e4b74 commit 7b5e0e2

File tree

7 files changed

+125
-86
lines changed

7 files changed

+125
-86
lines changed

CITATION.cff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ message: "If you use this software, please cite it using the metadata below."
55
preferred-citation:
66
type: software
77
title: "gen_surv"
8-
version: "1.0.0"
8+
version: "1.0.3"
99
url: "https://github.com/DiogoRibeiro7/genSurvPy"
1010
authors:
1111
- family-names: Ribeiro

README.md

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,26 +91,34 @@ genSurvPy/
9191
│ ├── censoring.py
9292
│ ├── bivariate.py
9393
│ ├── validate.py
94-
94+
└── interface.py
9595
├── tests/ # Testes automatizados
9696
│ ├── test_cphm.py
9797
│ ├── test_cmm.py
9898
│ ├── test_tdcm.py
9999
│ ├── test_thmm.py
100-
101100
├── examples/ # Exemplos de uso
101+
│ ├── run_aft.py
102+
│ ├── run_cmm.py
102103
│ ├── run_cphm.py
103-
│ ├── ...
104-
104+
│ ├── run_tdcm.py
105+
│ └── run_thmm.py
106+
├── docs/ # Documentação Sphinx
107+
│ ├── source/
108+
│ └── ...
109+
├── scripts/ # Utilidades diversas
110+
│ └── check_version_match.py
111+
├── tasks.py # Tarefas automatizadas com Invoke
112+
├── TODO.md # Roadmap de desenvolvimento
105113
├── pyproject.toml # Configurado com Poetry
106114
├── README.md
107-
├── LICENSE
108-
── .gitignore
115+
├── LICENCE
116+
── .gitignore
109117
```
110118

111119
## 🧠 License
112120

113-
MIT License. See [LICENSE](LICENSE) for details.
121+
MIT License. See [LICENCE](LICENCE) for details.
114122

115123

116124
## 🔖 Release Process
@@ -130,8 +138,25 @@ expectations for participants in this project.
130138

131139
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on setting up your environment, running tests, and submitting pull requests.
132140

141+
## 🔧 Development Tasks
142+
143+
Common project commands are defined in [`tasks.py`](tasks.py) and can be executed with [Invoke](https://www.pyinvoke.org/):
144+
145+
```bash
146+
poetry run inv -l # list available tasks
147+
poetry run inv test # run the test suite
148+
```
149+
133150
## 📑 Citation
134151

135152
If you use **gen_surv** in your work, please cite it using the metadata in
136153
[`CITATION.cff`](CITATION.cff). Many reference managers can import this file
137154
directly.
155+
156+
## Author
157+
158+
**Diogo Ribeiro**[ESMAD - Instituto Politécnico do Porto](https://esmad.ipp.pt)
159+
160+
- ORCID: <https://orcid.org/0009-0001-2022-7072>
161+
- Professional email: <[email protected]>
162+
- Personal email: <[email protected]>

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
project = 'gen_surv'
1313
copyright = '2025, Diogo Ribeiro'
1414
author = 'Diogo Ribeiro'
15-
release = '0.6.3'
15+
release = '1.0.3'
1616

1717
# -- General configuration ---------------------------------------------------
1818
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

docs/source/index.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,37 @@ Generate datasets directly from the terminal:
6464
python -m gen_surv dataset aft_ln --n 100 > data.csv
6565
```
6666

67+
## Repository Layout
68+
69+
```text
70+
genSurvPy/
71+
├── gen_surv/
72+
│ └── ...
73+
├── tests/
74+
├── examples/
75+
├── docs/
76+
├── scripts/
77+
├── tasks.py
78+
└── TODO.md
79+
```
80+
6781
## 🔗 Project Links
6882

6983
- [Source Code](https://github.com/DiogoRibeiro7/genSurvPy)
70-
- [License](https://github.com/DiogoRibeiro7/genSurvPy/blob/main/LICENSE)
84+
- [License](https://github.com/DiogoRibeiro7/genSurvPy/blob/main/LICENCE)
7185
- [Code of Conduct](https://github.com/DiogoRibeiro7/genSurvPy/blob/main/CODE_OF_CONDUCT.md)
7286

87+
88+
## Citation
89+
90+
If you use **gen_surv** in your work, please cite it using the metadata in
91+
[CITATION.cff](../../CITATION.cff).
92+
93+
## Author
94+
95+
**Diogo Ribeiro**[ESMAD - Instituto Politécnico do Porto](https://esmad.ipp.pt)
96+
97+
- ORCID: <https://orcid.org/0009-0001-2022-7072>
98+
- Professional email: <[email protected]>
99+
- Personal email: <[email protected]>
100+

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "gen_surv"
3-
version = "1.0.5"
3+
version = "1.0.7"
44
description = "A Python package for simulating survival data, inspired by the R package genSurv"
55
authors = ["Diogo Ribeiro <[email protected]>"]
66
license = "MIT"

scripts/check_version_match.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,62 @@
11
#!/usr/bin/env python3
2-
"""Check that pyproject version matches the latest git tag."""
2+
"""Check that pyproject version matches the latest git tag. Optionally fix it by tagging."""
33
from pathlib import Path
44
import subprocess
55
import sys
6+
67
if sys.version_info >= (3, 11):
78
import tomllib as tomli
89
else:
910
import tomli
1011

11-
1212
ROOT = Path(__file__).resolve().parents[1]
1313

14-
1514
def pyproject_version() -> str:
1615
pyproject_path = ROOT / "pyproject.toml"
1716
with pyproject_path.open("rb") as f:
1817
data = tomli.load(f)
1918
return data["tool"]["poetry"]["version"]
2019

21-
2220
def latest_tag() -> str:
2321
try:
2422
tag = subprocess.check_output(
2523
["git", "describe", "--tags", "--abbrev=0"], cwd=ROOT, text=True
2624
).strip()
2725
return tag.lstrip("v")
2826
except subprocess.CalledProcessError:
29-
return "0.0.0"
27+
return ""
3028

29+
def create_tag(version: str) -> None:
30+
print(f"Tagging repository with version: v{version}")
31+
subprocess.run(["git", "tag", f"v{version}"], cwd=ROOT, check=True)
32+
subprocess.run(["git", "push", "origin", f"v{version}"], cwd=ROOT, check=True)
33+
print(f"✅ Git tag v{version} created and pushed.")
3134

3235
def main() -> int:
33-
tag = latest_tag()
36+
fix = "--fix" in sys.argv
3437
version = pyproject_version()
38+
tag = latest_tag()
3539

3640
if not tag:
37-
print("No git tag found", file=sys.stderr)
38-
return 1
41+
print("⚠️ No git tag found.", file=sys.stderr)
42+
if fix:
43+
create_tag(version)
44+
return 0
45+
else:
46+
return 1
3947

4048
if version != tag:
4149
print(
42-
f"Version mismatch: pyproject.toml has {version} but latest tag is {tag}",
50+
f"Version mismatch: pyproject.toml has {version} but latest tag is {tag}",
4351
file=sys.stderr,
4452
)
53+
if fix:
54+
create_tag(version)
55+
return 0
4556
return 1
4657

47-
print(f"Version matches latest tag: {version}")
58+
print(f"✔️ Version matches latest tag: {version}")
4859
return 0
4960

50-
5161
if __name__ == "__main__":
5262
sys.exit(main())

tasks.py

Lines changed: 40 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@
88

99
@task
1010
def test(c: Context) -> None:
11-
"""
12-
Run pytest via Poetry with coverage reporting for the 'gen_surv' package.
11+
"""Run the test suite with coverage reporting.
12+
13+
This task executes ``pytest`` and generates a coverage report.
1314
14-
This task will:
15-
1. Execute 'pytest' through Poetry.
16-
2. Generate a terminal coverage report.
17-
3. Write an XML coverage report to 'coverage.xml'.
15+
Args:
16+
c: Invoke context used to run shell commands.
1817
19-
:param c: Invoke context used to run shell commands.
20-
:raises TypeError: If 'c' is not an Invoke Context.
18+
Raises:
19+
TypeError: If ``c`` is not an Invoke :class:`Context`.
2120
"""
2221
# Ensure we were passed a valid Context object.
2322
if not isinstance(c, Context):
@@ -52,16 +51,16 @@ def test(c: Context) -> None:
5251

5352
@task
5453
def checkversion(c: Context) -> None:
55-
"""Validate that ``pyproject.toml`` matches the latest git tag.
54+
"""Check that ``pyproject.toml`` matches the latest Git tag.
5655
57-
This task runs the ``scripts/check_version_match.py`` helper using Poetry
58-
and reports whether the version numbers are aligned.
56+
This task executes ``scripts/check_version_match.py`` to ensure the version
57+
declared in ``pyproject.toml`` agrees with the most recent tag.
5958
6059
Args:
6160
c: Invoke context used to run shell commands.
6261
63-
Returns:
64-
None
62+
Raises:
63+
TypeError: If ``c`` is not an Invoke :class:`Context`.
6564
"""
6665
if not isinstance(c, Context):
6766
raise TypeError(f"Expected Invoke Context, got {type(c).__name__!r}")
@@ -79,17 +78,13 @@ def checkversion(c: Context) -> None:
7978

8079
@task
8180
def docs(c: Context) -> None:
82-
"""
83-
Build Sphinx documentation for the project using Poetry.
81+
"""Build the Sphinx documentation.
8482
85-
This task will:
86-
1. Run 'sphinx-build' via Poetry.
87-
2. Read source files from 'docs/source'.
88-
3. Output HTML (or other format) into 'docs/build'.
83+
Args:
84+
c: Invoke context used to run shell commands.
8985
90-
:param c: Invoke context, used to run shell commands.
91-
:type c: Context
92-
:raises TypeError: If 'c' is not an Invoke Context.
86+
Raises:
87+
TypeError: If ``c`` is not an Invoke :class:`Context`.
9388
"""
9489
# Verify we have a proper Invoke Context.
9590
if not isinstance(c, Context):
@@ -118,15 +113,13 @@ def docs(c: Context) -> None:
118113

119114
@task
120115
def stubs(c: Context) -> None:
121-
"""
122-
Generate type stubs for the 'gen_surv' package using stubgen and Poetry.
116+
"""Generate type stubs for the ``gen_surv`` package.
123117
124-
This task will:
125-
1. Run 'stubgen' via Poetry to analyze 'gen_surv'.
126-
2. Output the generated stubs into the 'stubs' directory.
118+
Args:
119+
c: Invoke context used to run shell commands.
127120
128-
:param c: Invoke context used to run shell commands.
129-
:raises TypeError: If 'c' is not an Invoke Context.
121+
Raises:
122+
TypeError: If ``c`` is not an Invoke :class:`Context`.
130123
"""
131124
# Verify that 'c' is the correct Invoke Context.
132125
if not isinstance(c, Context):
@@ -155,15 +148,13 @@ def stubs(c: Context) -> None:
155148

156149
@task
157150
def build(c: Context) -> None:
158-
"""
159-
Build the project distributions using Poetry.
151+
"""Build distribution artifacts using Poetry.
160152
161-
This task will:
162-
1. Run 'poetry build' to create source and wheel packages.
163-
2. Place the built artifacts in the 'dist/' directory.
153+
Args:
154+
c: Invoke context used to run shell commands.
164155
165-
:param c: Invoke context used to run shell commands.
166-
:raises TypeError: If 'c' is not an Invoke Context.
156+
Raises:
157+
TypeError: If ``c`` is not an Invoke :class:`Context`.
167158
"""
168159
# Verify that we received a valid Invoke Context.
169160
if not isinstance(c, Context):
@@ -191,16 +182,10 @@ def build(c: Context) -> None:
191182

192183
@task
193184
def publish(c: Context) -> None:
194-
"""
195-
Build and publish the package to PyPI using Poetry.
196-
197-
This task will:
198-
1. Build the distribution via 'poetry publish --build'.
199-
2. Attach to a pseudo-TTY so you can enter credentials or confirm prompts.
200-
3. Not abort immediately if an error occurs; instead, it will print diagnostics.
185+
"""Build and upload the package to PyPI.
201186
202-
:param c: Invoke context, used to run shell commands.
203-
:type c: Context
187+
Args:
188+
c: Invoke context used to run shell commands.
204189
"""
205190
# Run the poetry publish command.
206191
# - warn=True: do not abort on non-zero exit, so we can inspect and report.
@@ -227,17 +212,13 @@ def publish(c: Context) -> None:
227212

228213
@task
229214
def clean(c: Context) -> None:
230-
"""
231-
Remove build artifacts, caches, and generated files.
215+
"""Remove build artifacts and caches.
232216
233-
This task will:
234-
1. Delete the 'dist' and 'build' directories.
235-
2. Remove generated documentation in 'docs/build'.
236-
3. Clear pytest and mypy caches.
237-
4. Delete coverage reports and stub files.
217+
Args:
218+
c: Invoke context used to run shell commands.
238219
239-
:param c: Invoke context used to run shell commands.
240-
:raises TypeError: If 'c' is not an Invoke Context.
220+
Raises:
221+
TypeError: If ``c`` is not an Invoke :class:`Context`.
241222
"""
242223
# Verify the argument is an Invoke Context.
243224
if not isinstance(c, Context):
@@ -276,18 +257,13 @@ def clean(c: Context) -> None:
276257

277258
@task
278259
def gitpush(c: Context) -> None:
279-
"""
280-
Stage all changes, prompt for a commit message, create a signed commit, and push to the remote repository.
260+
"""Commit and push all staged changes.
281261
282-
This task will:
283-
1. Verify that 'c' is an Invoke Context.
284-
2. Run 'git add .' to stage all unstaged changes.
285-
3. Prompt the user for a commit message; abort if empty.
286-
4. Sanitize the message, then run 'git commit -S -m <message>'.
287-
5. Run 'git push' to publish commits.
262+
Args:
263+
c: Invoke context used to run shell commands.
288264
289-
:param c: Invoke Context used to run shell commands.
290-
:raises TypeError: If 'c' is not an Invoke Context.
265+
Raises:
266+
TypeError: If ``c`` is not an Invoke :class:`Context`.
291267
"""
292268
# Verify the argument is a valid Invoke Context.
293269
if not isinstance(c, Context):

0 commit comments

Comments
 (0)