afterpython 0.3.19__tar.gz → 0.4.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.
- {afterpython-0.3.19 → afterpython-0.4.1}/PKG-INFO +24 -20
- {afterpython-0.3.19 → afterpython-0.4.1}/README.md +5 -5
- {afterpython-0.3.19 → afterpython-0.4.1}/pyproject.toml +23 -21
- {afterpython-0.3.19 → afterpython-0.4.1}/pyproject.toml.orig +24 -29
- afterpython-0.4.1/src/afterpython/_typing.py +4 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/__init__.py +2 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/build_pdoc.py +7 -0
- afterpython-0.4.1/src/afterpython/builders/comments_json.py +107 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/marimo_notebook.py +7 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/build.py +5 -3
- afterpython-0.4.1/src/afterpython/cli/commands/bump.py +333 -0
- afterpython-0.4.1/src/afterpython/cli/commands/changelog.py +45 -0
- afterpython-0.4.1/src/afterpython/cli/commands/check.py +43 -0
- afterpython-0.4.1/src/afterpython/cli/commands/commit_msg.py +115 -0
- afterpython-0.4.1/src/afterpython/cli/commands/init.py +406 -0
- afterpython-0.3.19/src/afterpython/cli/commands/commitizen.py → afterpython-0.4.1/src/afterpython/cli/commands/lint.py +7 -10
- afterpython-0.3.19/src/afterpython/cli/commands/pre_commit.py → afterpython-0.4.1/src/afterpython/cli/commands/prek.py +8 -8
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/release.py +39 -10
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/start.py +6 -4
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/update.py +8 -7
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/main.py +9 -9
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/const.py +1 -1
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/pcu.py +45 -40
- afterpython-0.4.1/src/afterpython/templates/afterpython-template.toml +39 -0
- afterpython-0.4.1/src/afterpython/templates/ci-workflow-template.yml +251 -0
- afterpython-0.4.1/src/afterpython/templates/cliff-template.toml +111 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/templates/deploy-workflow-template.yml +14 -18
- afterpython-0.4.1/src/afterpython/templates/pdoc/custom.css +37 -0
- afterpython-0.4.1/src/afterpython/templates/pdoc/frame.html.jinja2 +21 -0
- afterpython-0.4.1/src/afterpython/templates/pdoc/syntax-highlighting.css +155 -0
- afterpython-0.4.1/src/afterpython/templates/pdoc/theme.css +44 -0
- afterpython-0.4.1/src/afterpython/templates/pre-commit-config-template.yaml +68 -0
- afterpython-0.4.1/src/afterpython/templates/release-workflow-template.yml +107 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/templates/ruff-template.toml +8 -1
- afterpython-0.4.1/src/afterpython/templates/ty-template.toml +19 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/tools/_afterpython.py +31 -21
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/tools/_git.py +56 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/tools/branch_rules.py +3 -1
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/tools/myst.py +36 -19
- afterpython-0.4.1/src/afterpython/tools/prek.py +94 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/utils.py +1 -1
- afterpython-0.3.19/src/afterpython/_typing.py +0 -4
- afterpython-0.3.19/src/afterpython/cli/commands/bump.py +0 -118
- afterpython-0.3.19/src/afterpython/cli/commands/check.py +0 -36
- afterpython-0.3.19/src/afterpython/cli/commands/commit.py +0 -52
- afterpython-0.3.19/src/afterpython/cli/commands/init.py +0 -161
- afterpython-0.3.19/src/afterpython/templates/ci-workflow-template.yml +0 -220
- afterpython-0.3.19/src/afterpython/templates/cz-template.toml +0 -7
- afterpython-0.3.19/src/afterpython/templates/pdoc/frame.html.jinja2 +0 -7
- afterpython-0.3.19/src/afterpython/templates/pre-commit-config-template.yaml +0 -49
- afterpython-0.3.19/src/afterpython/templates/release-workflow-template.yml +0 -56
- afterpython-0.3.19/src/afterpython/tools/commitizen.py +0 -13
- afterpython-0.3.19/src/afterpython/tools/pre_commit.py +0 -37
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/__init__.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/_io/toml.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/_io/yaml.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/_paths.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/content_json.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/faq_json.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/index_md.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/jupyter_notebook.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/llms_txt.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/markdown.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/metadata.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/builders/url_md.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/__init__.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/add.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/clean.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/dev.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/format.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/init_branch_rules.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/install.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/lock.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/preview.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/remove.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/serve.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/cli/commands/sync.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/main.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/py.typed +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/templates/dependabot-template.yml +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/tools/github_actions.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/tools/pyproject.py +0 -0
- {afterpython-0.3.19 → afterpython-0.4.1}/src/afterpython/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: afterpython
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: CLI tool to streamline Python package maintenance and generate a dedicated project website
|
|
5
5
|
Keywords: package-maintenance,project-website,static-site-generator,developer-tools,documentation,cli-tool,ci/cd,mystmd,semantic-release,python-packaging
|
|
6
6
|
Author: Stephen Yau
|
|
@@ -11,27 +11,31 @@ Classifier: Intended Audience :: Developers
|
|
|
11
11
|
Classifier: Topic :: Software Development :: Build Tools
|
|
12
12
|
Classifier: Topic :: Software Development :: Documentation
|
|
13
13
|
Classifier: Typing :: Typed
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
-
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
17
|
+
Requires-Dist: click>=8.5.1
|
|
18
18
|
Requires-Dist: trogon>=0.6.0
|
|
19
|
-
Requires-Dist: httpx2>=2.
|
|
20
|
-
Requires-Dist: tomlkit>=0.15.
|
|
19
|
+
Requires-Dist: httpx2>=2.16.0
|
|
20
|
+
Requires-Dist: tomlkit>=0.15.2
|
|
21
21
|
Requires-Dist: ruamel-yaml>=0.19.1
|
|
22
|
-
Requires-Dist: gitpython>=3.1
|
|
23
|
-
Requires-Dist: python-dotenv>=1.2.
|
|
24
|
-
Requires-Dist: pyproject-metadata>=0.
|
|
25
|
-
Requires-Dist: jupytext>=1.19.
|
|
26
|
-
Requires-Dist: mystmd>=1.
|
|
22
|
+
Requires-Dist: gitpython>=3.2.1
|
|
23
|
+
Requires-Dist: python-dotenv>=1.2.4
|
|
24
|
+
Requires-Dist: pyproject-metadata>=0.12.1
|
|
25
|
+
Requires-Dist: jupytext>=1.19.6
|
|
26
|
+
Requires-Dist: mystmd>=1.12.0
|
|
27
27
|
Requires-Dist: pdoc>=16.0.0
|
|
28
|
-
Requires-Dist: ruff>=0.
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-
|
|
28
|
+
Requires-Dist: ruff>=0.17.4
|
|
29
|
+
Requires-Dist: prek>=0.5.10
|
|
30
|
+
Requires-Dist: ty>=0.0.99
|
|
31
|
+
Requires-Dist: git-cliff>=2.14.2
|
|
32
|
+
Requires-Dist: questionary>=2.1.1
|
|
33
|
+
Requires-Dist: marimo[recommended,lsp]>=0.25.2 ; extra == 'marimo'
|
|
34
|
+
Requires-Python: >=3.13
|
|
32
35
|
Project-URL: homepage, https://afterpython.afterpython.org
|
|
33
36
|
Project-URL: repository, https://github.com/AfterPythonOrg/afterpython
|
|
34
37
|
Project-URL: documentation, https://afterpython.afterpython.org/doc
|
|
38
|
+
Provides-Extra: marimo
|
|
35
39
|
Description-Content-Type: text/markdown
|
|
36
40
|
|
|
37
41
|
# AfterPython: Python Package Maintenance Toolkit and Project Website Generator
|
|
@@ -41,8 +45,8 @@ Description-Content-Type: text/markdown
|
|
|
41
45
|
[](https://pypi.org/project/afterpython)
|
|
42
46
|

|
|
43
47
|
[](https://github.com/AfterPythonOrg/afterpython/discussions)
|
|
44
|
-
[](https://deepwiki.com/AfterPythonOrg/afterpython)
|
|
45
48
|
[](https://codewiki.google/github.com/afterpythonorg/afterpython?utm_source=badge&utm_medium=github&utm_campaign=github.com/afterpythonorg/afterpython)
|
|
49
|
+
<!--[](https://deepwiki.com/AfterPythonOrg/afterpython)-->
|
|
46
50
|
<!--  -->
|
|
47
51
|
<!-- [](https://pixi.sh) -->
|
|
48
52
|
|
|
@@ -59,10 +63,10 @@ Description-Content-Type: text/markdown
|
|
|
59
63
|
[Scikit-Learn]: https://scikit-learn.org
|
|
60
64
|
[WebLLM]: https://webllm.mlc.ai/
|
|
61
65
|
[project-website-template]: https://github.com/AfterPythonOrg/project-website-template
|
|
62
|
-
[commitizen]: https://github.com/commitizen-tools/commitizen
|
|
63
66
|
[uv]: https://docs.astral.sh/uv/
|
|
64
67
|
[ruff]: https://docs.astral.sh/ruff/
|
|
65
|
-
|
|
68
|
+
[ty]: https://docs.astral.sh/ty/
|
|
69
|
+
[git-cliff]: https://git-cliff.org/
|
|
66
70
|
|
|
67
71
|
## Problem
|
|
68
72
|
Going from **writing Python code to publishing and maintaining a package** is **time-consuming**.
|
|
@@ -125,10 +129,10 @@ ap tui
|
|
|
125
129
|
- [pre-commit]
|
|
126
130
|
- [GitHub Actions]
|
|
127
131
|
- [pdoc]
|
|
128
|
-
- [commitizen]
|
|
129
132
|
- [uv]
|
|
130
133
|
- [ruff]
|
|
134
|
+
- [ty]
|
|
131
135
|
- [pagefind]
|
|
132
136
|
- [WebLLM]
|
|
133
|
-
|
|
137
|
+
- [git-cliff]
|
|
134
138
|
<!-- - [pixi] -->
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
[](https://pypi.org/project/afterpython)
|
|
6
6
|

|
|
7
7
|
[](https://github.com/AfterPythonOrg/afterpython/discussions)
|
|
8
|
-
[](https://deepwiki.com/AfterPythonOrg/afterpython)
|
|
9
8
|
[](https://codewiki.google/github.com/afterpythonorg/afterpython?utm_source=badge&utm_medium=github&utm_campaign=github.com/afterpythonorg/afterpython)
|
|
9
|
+
<!--[](https://deepwiki.com/AfterPythonOrg/afterpython)-->
|
|
10
10
|
<!--  -->
|
|
11
11
|
<!-- [](https://pixi.sh) -->
|
|
12
12
|
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
[Scikit-Learn]: https://scikit-learn.org
|
|
24
24
|
[WebLLM]: https://webllm.mlc.ai/
|
|
25
25
|
[project-website-template]: https://github.com/AfterPythonOrg/project-website-template
|
|
26
|
-
[commitizen]: https://github.com/commitizen-tools/commitizen
|
|
27
26
|
[uv]: https://docs.astral.sh/uv/
|
|
28
27
|
[ruff]: https://docs.astral.sh/ruff/
|
|
29
|
-
|
|
28
|
+
[ty]: https://docs.astral.sh/ty/
|
|
29
|
+
[git-cliff]: https://git-cliff.org/
|
|
30
30
|
|
|
31
31
|
## Problem
|
|
32
32
|
Going from **writing Python code to publishing and maintaining a package** is **time-consuming**.
|
|
@@ -89,10 +89,10 @@ ap tui
|
|
|
89
89
|
- [pre-commit]
|
|
90
90
|
- [GitHub Actions]
|
|
91
91
|
- [pdoc]
|
|
92
|
-
- [commitizen]
|
|
93
92
|
- [uv]
|
|
94
93
|
- [ruff]
|
|
94
|
+
- [ty]
|
|
95
95
|
- [pagefind]
|
|
96
96
|
- [WebLLM]
|
|
97
|
-
|
|
97
|
+
- [git-cliff]
|
|
98
98
|
<!-- - [pixi] -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "afterpython"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
description = "CLI tool to streamline Python package maintenance and generate a dedicated project website"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
readme = "README.md"
|
|
@@ -22,32 +22,37 @@ classifiers = [
|
|
|
22
22
|
"Topic :: Software Development :: Build Tools",
|
|
23
23
|
"Topic :: Software Development :: Documentation",
|
|
24
24
|
"Typing :: Typed",
|
|
25
|
-
"Programming Language :: Python :: 3.11",
|
|
26
|
-
"Programming Language :: Python :: 3.12",
|
|
27
25
|
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Programming Language :: Python :: 3.15",
|
|
28
28
|
]
|
|
29
|
-
requires-python = ">=3.
|
|
29
|
+
requires-python = ">=3.13"
|
|
30
30
|
dependencies = [
|
|
31
|
-
"click>=8.1
|
|
31
|
+
"click>=8.5.1",
|
|
32
32
|
"trogon>=0.6.0",
|
|
33
|
-
"httpx2>=2.
|
|
34
|
-
"tomlkit>=0.15.
|
|
33
|
+
"httpx2>=2.16.0",
|
|
34
|
+
"tomlkit>=0.15.2",
|
|
35
35
|
"ruamel-yaml>=0.19.1",
|
|
36
|
-
"gitpython>=3.1
|
|
37
|
-
"python-dotenv>=1.2.
|
|
38
|
-
"pyproject-metadata>=0.
|
|
39
|
-
"jupytext>=1.19.
|
|
40
|
-
"mystmd>=1.
|
|
36
|
+
"gitpython>=3.2.1",
|
|
37
|
+
"python-dotenv>=1.2.4",
|
|
38
|
+
"pyproject-metadata>=0.12.1",
|
|
39
|
+
"jupytext>=1.19.6",
|
|
40
|
+
"mystmd>=1.12.0",
|
|
41
41
|
"pdoc>=16.0.0",
|
|
42
|
-
"ruff>=0.
|
|
43
|
-
"
|
|
44
|
-
"
|
|
42
|
+
"ruff>=0.17.4",
|
|
43
|
+
"prek>=0.5.10",
|
|
44
|
+
"ty>=0.0.99",
|
|
45
|
+
"git-cliff>=2.14.2",
|
|
46
|
+
"questionary>=2.1.1",
|
|
45
47
|
]
|
|
46
48
|
|
|
47
49
|
[[project.authors]]
|
|
48
50
|
name = "Stephen Yau"
|
|
49
51
|
email = "softwareentrepreneer+afterpython@gmail.com"
|
|
50
52
|
|
|
53
|
+
[project.optional-dependencies]
|
|
54
|
+
marimo = ["marimo[recommended,lsp]>=0.25.2"]
|
|
55
|
+
|
|
51
56
|
[project.urls]
|
|
52
57
|
homepage = "https://afterpython.afterpython.org"
|
|
53
58
|
repository = "https://github.com/AfterPythonOrg/afterpython"
|
|
@@ -58,15 +63,12 @@ ap = "afterpython.main:run_cli"
|
|
|
58
63
|
pcu = "afterpython.main:run_pcu"
|
|
59
64
|
|
|
60
65
|
[build-system]
|
|
61
|
-
requires = ["uv_build>=0.
|
|
66
|
+
requires = ["uv_build>=0.13.7,<0.14.0"]
|
|
62
67
|
build-backend = "uv_build"
|
|
63
68
|
|
|
64
|
-
[tool.uv]
|
|
65
|
-
exclude-newer = "14 days"
|
|
66
|
-
|
|
67
69
|
[tool.uv.build-backend]
|
|
68
70
|
module-name = "afterpython"
|
|
69
71
|
module-root = "src"
|
|
70
72
|
|
|
71
|
-
[tool.
|
|
72
|
-
|
|
73
|
+
[tool.ruff]
|
|
74
|
+
extend = "afterpython/ruff.toml"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "afterpython"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
description = "CLI tool to streamline Python package maintenance and generate a dedicated project website"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
authors = [
|
|
@@ -25,32 +25,33 @@ classifiers = [
|
|
|
25
25
|
"Topic :: Software Development :: Build Tools",
|
|
26
26
|
"Topic :: Software Development :: Documentation",
|
|
27
27
|
"Typing :: Typed",
|
|
28
|
-
"Programming Language :: Python :: 3.11",
|
|
29
|
-
"Programming Language :: Python :: 3.12",
|
|
30
28
|
"Programming Language :: Python :: 3.13",
|
|
31
|
-
|
|
29
|
+
"Programming Language :: Python :: 3.14",
|
|
30
|
+
"Programming Language :: Python :: 3.15",
|
|
32
31
|
]
|
|
33
|
-
requires-python = ">=3.
|
|
32
|
+
requires-python = ">=3.13"
|
|
34
33
|
dependencies = [
|
|
35
|
-
"click>=8.1
|
|
34
|
+
"click>=8.5.1",
|
|
36
35
|
"trogon>=0.6.0",
|
|
37
|
-
"httpx2>=2.
|
|
38
|
-
"tomlkit>=0.15.
|
|
36
|
+
"httpx2>=2.16.0",
|
|
37
|
+
"tomlkit>=0.15.2",
|
|
39
38
|
"ruamel-yaml>=0.19.1",
|
|
40
|
-
"gitpython>=3.1
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
# "jinja2>=3.1.6",
|
|
46
|
-
"mystmd>=1.10.1",
|
|
39
|
+
"gitpython>=3.2.1",
|
|
40
|
+
"python-dotenv>=1.2.4",
|
|
41
|
+
"pyproject-metadata>=0.12.1",
|
|
42
|
+
"jupytext>=1.19.6",
|
|
43
|
+
"mystmd>=1.12.0",
|
|
47
44
|
"pdoc>=16.0.0",
|
|
48
|
-
"ruff>=0.
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
45
|
+
"ruff>=0.17.4",
|
|
46
|
+
"prek>=0.5.10",
|
|
47
|
+
"ty>=0.0.99",
|
|
48
|
+
"git-cliff>=2.14.2",
|
|
49
|
+
"questionary>=2.1.1",
|
|
52
50
|
]
|
|
53
51
|
|
|
52
|
+
[project.optional-dependencies]
|
|
53
|
+
marimo = ["marimo[recommended,lsp]>=0.25.2"]
|
|
54
|
+
|
|
54
55
|
[project.urls]
|
|
55
56
|
homepage = "https://afterpython.afterpython.org"
|
|
56
57
|
repository = "https://github.com/AfterPythonOrg/afterpython"
|
|
@@ -60,22 +61,16 @@ documentation = "https://afterpython.afterpython.org/doc"
|
|
|
60
61
|
ap = "afterpython.main:run_cli"
|
|
61
62
|
pcu = "afterpython.main:run_pcu"
|
|
62
63
|
|
|
63
|
-
# [tool.uv]
|
|
64
|
-
# override-dependencies = ["platformdirs>=4.5.0", "nodeenv>=1.9.1"]
|
|
65
|
-
|
|
66
64
|
[build-system]
|
|
67
|
-
requires = ["uv_build>=0.
|
|
65
|
+
requires = ["uv_build>=0.13.7,<0.14.0"]
|
|
68
66
|
build-backend = "uv_build"
|
|
69
67
|
|
|
70
68
|
[tool.uv]
|
|
71
|
-
exclude-newer = "14 days"
|
|
69
|
+
# exclude-newer = "14 days"
|
|
72
70
|
|
|
73
71
|
[tool.uv.build-backend]
|
|
74
72
|
module-name = "afterpython"
|
|
75
73
|
module-root = "src"
|
|
76
74
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
[tool.pyright]
|
|
81
|
-
typeCheckingMode = "basic"
|
|
75
|
+
[tool.ruff]
|
|
76
|
+
extend = "afterpython/ruff.toml"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from afterpython.builders.build_pdoc import build_pdoc
|
|
2
|
+
from afterpython.builders.comments_json import build_comments_json
|
|
2
3
|
from afterpython.builders.content_json import build_content_json
|
|
3
4
|
from afterpython.builders.faq_json import build_faq_json
|
|
4
5
|
from afterpython.builders.index_md import (
|
|
@@ -13,6 +14,7 @@ from afterpython.builders.metadata import build_metadata
|
|
|
13
14
|
from afterpython.builders.url_md import build_url_md
|
|
14
15
|
|
|
15
16
|
__all__ = (
|
|
17
|
+
"build_comments_json",
|
|
16
18
|
"build_content_json",
|
|
17
19
|
"build_faq_json",
|
|
18
20
|
"build_jupyter_notebooks",
|
|
@@ -19,9 +19,15 @@ def build_pdoc(base_path: str) -> None:
|
|
|
19
19
|
project logo appears in the top-left of every API page and links
|
|
20
20
|
back to the project website root (matches MyST's UX).
|
|
21
21
|
"""
|
|
22
|
+
from afterpython._io.toml import _from_tomlkit
|
|
23
|
+
from afterpython.tools._afterpython import read_afterpython
|
|
24
|
+
|
|
22
25
|
package_dir = find_package_directory()
|
|
23
26
|
output_dir = ap.paths.build_path / "api_reference"
|
|
24
27
|
template_dir = ap.paths.templates_path / "pdoc"
|
|
28
|
+
# e.g. "google"; unset leaves it to pdoc (a module's __docformat__, else restructuredtext)
|
|
29
|
+
website = _from_tomlkit(read_afterpython().get("website", {}))
|
|
30
|
+
docformat = website.get("api_reference_docformat")
|
|
25
31
|
|
|
26
32
|
click.echo("Building api_reference/...")
|
|
27
33
|
|
|
@@ -45,6 +51,7 @@ def build_pdoc(base_path: str) -> None:
|
|
|
45
51
|
f"{base_path}/",
|
|
46
52
|
"--template-directory",
|
|
47
53
|
str(template_dir),
|
|
54
|
+
*(["--docformat", str(docformat)] if docformat else []),
|
|
48
55
|
str(package_dir),
|
|
49
56
|
],
|
|
50
57
|
env=env,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
import afterpython as ap
|
|
9
|
+
|
|
10
|
+
GISCUS_API = "https://giscus.app/api/discussions/categories"
|
|
11
|
+
DEFAULT_CATEGORY = "Announcements"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _read_comments_config() -> dict:
|
|
15
|
+
from afterpython._io.toml import _from_tomlkit
|
|
16
|
+
from afterpython.tools._afterpython import read_afterpython
|
|
17
|
+
|
|
18
|
+
website = _from_tomlkit(read_afterpython().get("website", {}))
|
|
19
|
+
return dict(website.get("comments", {}))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _get_github_repo() -> str | None:
|
|
23
|
+
"""Return "owner/repo" from pyproject.toml's repository URL, or the git remote."""
|
|
24
|
+
from afterpython.tools._git import get_github_url
|
|
25
|
+
from afterpython.tools.pyproject import read_metadata
|
|
26
|
+
|
|
27
|
+
url = str(read_metadata().urls.get("repository", "")) or get_github_url() or ""
|
|
28
|
+
match = re.search(r"github\.com[/:]([^/]+)/([^/]+?)(?:\.git)?/?$", url)
|
|
29
|
+
return f"{match[1]}/{match[2]}" if match else None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _fetch_giscus_categories(repo: str) -> dict:
|
|
33
|
+
"""Fetch the repo and category IDs giscus needs. Raises click.ClickException on failure."""
|
|
34
|
+
import httpx2
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
response = httpx2.get(GISCUS_API, params={"repo": repo}, timeout=10.0)
|
|
38
|
+
except httpx2.HTTPError as e:
|
|
39
|
+
raise click.ClickException(f"could not reach giscus.app ({e})") from e
|
|
40
|
+
try:
|
|
41
|
+
data = response.json()
|
|
42
|
+
except ValueError:
|
|
43
|
+
data = {}
|
|
44
|
+
if response.status_code != 200 or "repositoryId" not in data:
|
|
45
|
+
error = data.get("error") or f"HTTP {response.status_code}"
|
|
46
|
+
raise click.ClickException(error)
|
|
47
|
+
return data
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def build_comments_json():
|
|
51
|
+
"""Build comments.json for the giscus comment section on content pages.
|
|
52
|
+
|
|
53
|
+
Reads [website.comments] in afterpython.toml. The website template only
|
|
54
|
+
shows comments when comments.json exists, so a disabled or failed setup
|
|
55
|
+
just leaves it out. Never fails the build.
|
|
56
|
+
"""
|
|
57
|
+
stale = ap.paths.website_path / "static" / "comments.json"
|
|
58
|
+
stale.unlink(missing_ok=True)
|
|
59
|
+
|
|
60
|
+
config = _read_comments_config()
|
|
61
|
+
if not config.get("enabled", False):
|
|
62
|
+
click.echo("Comments are disabled, skip building comments.json")
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
def warn(reason: str):
|
|
66
|
+
click.secho(f"Warning: skip comments, {reason}", fg="yellow")
|
|
67
|
+
|
|
68
|
+
repo = _get_github_repo()
|
|
69
|
+
if not repo:
|
|
70
|
+
warn(
|
|
71
|
+
"no GitHub repository found "
|
|
72
|
+
"(set [project.urls] repository in pyproject.toml)"
|
|
73
|
+
)
|
|
74
|
+
return
|
|
75
|
+
|
|
76
|
+
category = str(config.get("category") or DEFAULT_CATEGORY)
|
|
77
|
+
try:
|
|
78
|
+
data = _fetch_giscus_categories(repo)
|
|
79
|
+
except click.ClickException as e:
|
|
80
|
+
warn(
|
|
81
|
+
f"giscus is not ready for {repo}: {e.message}\n"
|
|
82
|
+
f" 1. Enable Discussions: https://github.com/{repo}/settings\n"
|
|
83
|
+
" 2. Install the giscus app: https://github.com/apps/giscus\n"
|
|
84
|
+
" Or set [website.comments] enabled = false in afterpython.toml"
|
|
85
|
+
)
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
category_id = next(
|
|
89
|
+
(c["id"] for c in data.get("categories", []) if c["name"] == category), None
|
|
90
|
+
)
|
|
91
|
+
if not category_id:
|
|
92
|
+
names = ", ".join(c["name"] for c in data.get("categories", []))
|
|
93
|
+
warn(
|
|
94
|
+
f'Discussions category "{category}" not found in {repo} '
|
|
95
|
+
f"(available: {names or 'none'})"
|
|
96
|
+
)
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
click.echo(f"Building comments.json ({repo}, {category})...")
|
|
100
|
+
comments = {
|
|
101
|
+
"repo": repo,
|
|
102
|
+
"repoId": data["repositoryId"],
|
|
103
|
+
"category": category,
|
|
104
|
+
"categoryId": category_id,
|
|
105
|
+
}
|
|
106
|
+
with open(ap.paths.build_path / "comments.json", "w") as f:
|
|
107
|
+
json.dump(comments, f, indent=2)
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import re
|
|
5
|
+
import shutil
|
|
5
6
|
import subprocess
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from typing import Literal
|
|
@@ -48,6 +49,12 @@ def _export_marimo(
|
|
|
48
49
|
execute: bool = False,
|
|
49
50
|
):
|
|
50
51
|
"""Run `marimo export` to produce HTML at `output_html`."""
|
|
52
|
+
# marimo is an optional dependency (the `marimo` extra)
|
|
53
|
+
if shutil.which("marimo") is None:
|
|
54
|
+
raise click.ClickException(
|
|
55
|
+
f"marimo is required to build {source.name} (a marimo notebook), "
|
|
56
|
+
'install it with: uv add --dev "afterpython[marimo]"'
|
|
57
|
+
)
|
|
51
58
|
output_html.parent.mkdir(parents=True, exist_ok=True)
|
|
52
59
|
subcommand = "html-wasm" if mode == "wasm" else "html"
|
|
53
60
|
cmd = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from collections.abc import Callable
|
|
3
|
+
from collections.abc import Callable, Iterable
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
@@ -17,6 +17,7 @@ from click.exceptions import Exit
|
|
|
17
17
|
|
|
18
18
|
import afterpython as ap
|
|
19
19
|
from afterpython.builders import (
|
|
20
|
+
build_comments_json,
|
|
20
21
|
build_content_json,
|
|
21
22
|
build_faq_json,
|
|
22
23
|
build_jupyter_notebooks,
|
|
@@ -137,6 +138,7 @@ def prebuild():
|
|
|
137
138
|
create_placeholder_index_md_files()
|
|
138
139
|
build_metadata()
|
|
139
140
|
build_faq_json()
|
|
141
|
+
build_comments_json()
|
|
140
142
|
build_marimo_readme(mode=_get_readme_py_mode())
|
|
141
143
|
build_markdown()
|
|
142
144
|
build_jupyter_notebooks()
|
|
@@ -147,7 +149,7 @@ def postbuild(dev_build: bool = False):
|
|
|
147
149
|
source: Path,
|
|
148
150
|
destination: Path,
|
|
149
151
|
is_copy: bool = True,
|
|
150
|
-
ignore_copy: Callable[[str, list[str]],
|
|
152
|
+
ignore_copy: Callable[[str, list[str]], Iterable[str]] | None = None,
|
|
151
153
|
):
|
|
152
154
|
"""
|
|
153
155
|
Move or copy files from source to destination.
|
|
@@ -156,7 +158,7 @@ def postbuild(dev_build: bool = False):
|
|
|
156
158
|
source: Source path
|
|
157
159
|
destination: Destination path
|
|
158
160
|
is_copy: If True, copy files (merge with existing). If False, move files (replace destination)
|
|
159
|
-
ignore_copy: Optional ignore function for copytree, takes (directory, contents) and returns
|
|
161
|
+
ignore_copy: Optional ignore function for copytree, takes (directory, contents) and returns the names to ignore
|
|
160
162
|
"""
|
|
161
163
|
if not source.exists():
|
|
162
164
|
return
|