afterpython 0.1.0.dev11__tar.gz → 0.1.0.dev15__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.
Files changed (55) hide show
  1. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/PKG-INFO +1 -1
  2. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/pyproject.toml +1 -1
  3. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/bump.py +9 -0
  4. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/init.py +22 -26
  5. afterpython-0.1.0.dev15/src/afterpython/templates/cz-template.toml +8 -0
  6. afterpython-0.1.0.dev15/src/afterpython/templates/pre-commit-config-template.yaml +48 -0
  7. afterpython-0.1.0.dev15/src/afterpython/tools/commitizen.py +13 -0
  8. afterpython-0.1.0.dev15/src/afterpython/tools/pre_commit.py +37 -0
  9. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/tools/pyproject.py +36 -0
  10. afterpython-0.1.0.dev11/src/afterpython/tools/commitizen.py +0 -52
  11. afterpython-0.1.0.dev11/src/afterpython/tools/pre_commit.py +0 -60
  12. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/README.md +0 -0
  13. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/__init__.py +0 -0
  14. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/_io/toml.py +0 -0
  15. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/_io/yaml.py +0 -0
  16. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/_paths.py +0 -0
  17. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/_typing.py +0 -0
  18. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/builders/__init__.py +0 -0
  19. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/builders/metadata.py +0 -0
  20. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/builders/molab.py +0 -0
  21. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/__init__.py +0 -0
  22. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/add.py +0 -0
  23. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/build.py +0 -0
  24. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/check.py +0 -0
  25. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/clean.py +0 -0
  26. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/commit.py +0 -0
  27. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/commitizen.py +0 -0
  28. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/dev.py +0 -0
  29. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/format.py +0 -0
  30. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/init_branch_rules.py +0 -0
  31. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/install.py +0 -0
  32. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/lock.py +0 -0
  33. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/pre_commit.py +0 -0
  34. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/preview.py +0 -0
  35. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/release.py +0 -0
  36. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/remove.py +0 -0
  37. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/start.py +0 -0
  38. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/sync.py +0 -0
  39. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/commands/update.py +0 -0
  40. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/cli/main.py +0 -0
  41. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/const.py +0 -0
  42. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/main.py +0 -0
  43. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/pcu.py +0 -0
  44. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/templates/ci-workflow-template.yml +0 -0
  45. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/templates/dependabot-template.yml +0 -0
  46. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/templates/deploy-workflow-template.yml +0 -0
  47. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/templates/release-workflow-template.yml +0 -0
  48. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/templates/ruff-template.toml +0 -0
  49. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/tools/_afterpython.py +0 -0
  50. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/tools/_git.py +0 -0
  51. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/tools/branch_rules.py +0 -0
  52. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/tools/github_actions.py +0 -0
  53. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/tools/myst.py +0 -0
  54. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/utils.py +0 -0
  55. {afterpython-0.1.0.dev11 → afterpython-0.1.0.dev15}/src/afterpython/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afterpython
3
- Version: 0.1.0.dev11
3
+ Version: 0.1.0.dev15
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "afterpython"
3
- version = "0.1.0.dev11"
3
+ version = "0.1.0.dev15"
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 = [
@@ -1,6 +1,9 @@
1
1
  import subprocess
2
2
 
3
3
  import click
4
+ from click.exceptions import Exit
5
+
6
+ from afterpython.utils import has_pixi
4
7
 
5
8
 
6
9
  @click.command(
@@ -86,3 +89,9 @@ def bump(ctx, release: bool, pre: bool):
86
89
  args = ["--prerelease", prerelease_type, *ctx.args]
87
90
 
88
91
  subprocess.run(["ap", "cz", "bump", *args])
92
+
93
+ # Update pixi.lock after version bump (editable install requires lock refresh)
94
+ if has_pixi():
95
+ result = subprocess.run(["pixi", "install"], check=False)
96
+ if result.returncode != 0:
97
+ raise Exit(result.returncode)
@@ -7,38 +7,13 @@ import afterpython as ap
7
7
 
8
8
 
9
9
  def init_ruff_toml():
10
- from afterpython.tools.pre_commit import update_pre_commit
11
-
12
- afterpython_path = ap.paths.afterpython_path
13
- ruff_toml_path = afterpython_path / "ruff.toml"
10
+ ruff_toml_path = ap.paths.afterpython_path / "ruff.toml"
14
11
  if ruff_toml_path.exists():
15
12
  click.echo(f"Ruff configuration file {ruff_toml_path} already exists")
16
13
  return
17
14
  ruff_template_path = ap.paths.templates_path / "ruff-template.toml"
18
15
  shutil.copy(ruff_template_path, ruff_toml_path)
19
16
  click.echo(f"Created {ruff_toml_path}")
20
- # add ruff-pre-commit hook to .pre-commit-config.yaml
21
- data_update = {
22
- "repos": [
23
- {
24
- "repo": "https://github.com/astral-sh/ruff-pre-commit",
25
- "rev": "v0.14.6",
26
- "hooks": [
27
- {
28
- "id": "ruff-check",
29
- "stages": ["pre-commit"],
30
- "args": ["--config", "./afterpython/ruff.toml"],
31
- },
32
- {
33
- "id": "ruff-format",
34
- "stages": ["pre-commit"],
35
- "args": ["--config", "./afterpython/ruff.toml"],
36
- },
37
- ],
38
- },
39
- ]
40
- }
41
- update_pre_commit(data_update)
42
17
 
43
18
 
44
19
  def init_website():
@@ -46,6 +21,24 @@ def init_website():
46
21
  subprocess.run(["ap", "update", "website"])
47
22
 
48
23
 
24
+ def init_py_typed():
25
+ from afterpython.tools.pyproject import find_package_directory
26
+
27
+ try:
28
+ package_dir = find_package_directory()
29
+ except FileNotFoundError:
30
+ click.echo(
31
+ "Could not find package directory (__init__.py not found), skipping py-typed initialization"
32
+ )
33
+ return
34
+ py_typed_path = package_dir / "py.typed"
35
+ if py_typed_path.exists():
36
+ click.echo(f"py.typed file already exists at {py_typed_path}")
37
+ return
38
+ py_typed_path.touch()
39
+ click.echo(f"Created {py_typed_path}")
40
+
41
+
49
42
  @click.command()
50
43
  @click.option(
51
44
  "--yes",
@@ -85,6 +78,9 @@ def init(ctx, yes):
85
78
 
86
79
  init_website()
87
80
 
81
+ # TODO: add type checking related stuff here
82
+ init_py_typed()
83
+
88
84
  create_workflow("deploy")
89
85
  create_workflow("ci")
90
86
 
@@ -0,0 +1,8 @@
1
+ [tool.commitizen]
2
+ name = "cz_conventional_commits"
3
+ # name = "cz_customize"
4
+ tag_format = "v$version"
5
+ version_scheme = "pep440"
6
+ version_provider = "uv"
7
+ update_changelog_on_bump = false
8
+ major_version_zero = true
@@ -0,0 +1,48 @@
1
+ default_install_hook_types:
2
+ - pre-commit
3
+ - commit-msg
4
+ - pre-push
5
+ exclude: ^afterpython/_website/
6
+ repos:
7
+ - repo: https://github.com/pre-commit/pre-commit-hooks
8
+ rev: v6.0.0
9
+ hooks:
10
+ - id: trailing-whitespace
11
+ stages:
12
+ - pre-commit
13
+ - id: end-of-file-fixer
14
+ stages:
15
+ - pre-commit
16
+ - id: check-yaml
17
+ stages:
18
+ - pre-commit
19
+ - id: check-toml
20
+ stages:
21
+ - pre-commit
22
+ - id: check-added-large-files
23
+ stages:
24
+ - pre-commit
25
+ - repo: https://github.com/astral-sh/ruff-pre-commit
26
+ rev: v0.14.6
27
+ hooks:
28
+ - id: ruff-check
29
+ stages:
30
+ - pre-commit
31
+ args:
32
+ - --config
33
+ - ./afterpython/ruff.toml
34
+ - id: ruff-format
35
+ stages:
36
+ - pre-commit
37
+ args:
38
+ - --config
39
+ - ./afterpython/ruff.toml
40
+ - repo: https://github.com/commitizen-tools/commitizen
41
+ rev: v4.10.0
42
+ hooks:
43
+ - id: commitizen
44
+ stages:
45
+ - commit-msg
46
+ - id: commitizen-branch
47
+ stages:
48
+ - pre-push
@@ -0,0 +1,13 @@
1
+ import shutil
2
+
3
+ import afterpython as ap
4
+
5
+
6
+ def init_commitizen():
7
+ commitizen_toml_path = ap.paths.afterpython_path / "cz.toml"
8
+ if commitizen_toml_path.exists():
9
+ print(f"Commitizen configuration file {commitizen_toml_path} already exists")
10
+ return
11
+ cz_template_path = ap.paths.templates_path / "cz-template.toml"
12
+ shutil.copy(cz_template_path, commitizen_toml_path)
13
+ print(f"Created {commitizen_toml_path}")
@@ -0,0 +1,37 @@
1
+ import shutil
2
+ import subprocess
3
+
4
+ import afterpython as ap
5
+ from afterpython._io.yaml import read_yaml, write_yaml
6
+
7
+
8
+ def install_pre_commit():
9
+ # installed in .git/hooks
10
+ subprocess.run(["ap", "pre-commit", "install", "--install-hooks"], check=True)
11
+
12
+
13
+ def update_pre_commit(data_update: dict):
14
+ from afterpython.utils import deep_merge
15
+
16
+ pre_commit_path = ap.paths.afterpython_path / ".pre-commit-config.yaml"
17
+ if not pre_commit_path.exists():
18
+ raise FileNotFoundError(
19
+ f".pre-commit-config.yaml not found at {pre_commit_path}"
20
+ )
21
+ existing_data = read_yaml(pre_commit_path)
22
+ existing_data = deep_merge(existing_data, data_update)
23
+ write_yaml(pre_commit_path, existing_data)
24
+ install_pre_commit()
25
+
26
+
27
+ def init_pre_commit():
28
+ pre_commit_path = ap.paths.afterpython_path / ".pre-commit-config.yaml"
29
+ if pre_commit_path.exists():
30
+ print(f".pre-commit-config.yaml already exists at {pre_commit_path}")
31
+ return
32
+ pre_commit_template_path = (
33
+ ap.paths.templates_path / "pre-commit-config-template.yaml"
34
+ )
35
+ shutil.copy(pre_commit_template_path, pre_commit_path)
36
+ print(f"Created {pre_commit_path}")
37
+ install_pre_commit()
@@ -6,6 +6,7 @@ if TYPE_CHECKING:
6
6
  from tomlkit.toml_document import TOMLDocument
7
7
 
8
8
  import asyncio
9
+ from pathlib import Path
9
10
 
10
11
  from pyproject_metadata import StandardMetadata
11
12
 
@@ -27,6 +28,41 @@ def read_metadata() -> StandardMetadata:
27
28
  return StandardMetadata.from_pyproject(read_pyproject())
28
29
 
29
30
 
31
+ def find_package_directory() -> Path:
32
+ """Find the user's package directory.
33
+
34
+ Supports both common Python project layouts:
35
+ - src layout: user_project/src/package_name/__init__.py
36
+ - flat layout: user_project/package_name/__init__.py
37
+
38
+ Returns:
39
+ Path to the package directory containing __init__.py
40
+
41
+ Raises:
42
+ FileNotFoundError: If package directory cannot be found in either layout
43
+ """
44
+ metadata = read_metadata()
45
+ package_name = metadata.name
46
+ project_root = ap.paths.user_path
47
+
48
+ # Try src layout first (recommended layout)
49
+ src_layout_dir = project_root / "src" / package_name
50
+ if (src_layout_dir / "__init__.py").exists():
51
+ return src_layout_dir
52
+
53
+ # Try flat layout
54
+ flat_layout_dir = project_root / package_name
55
+ if (flat_layout_dir / "__init__.py").exists():
56
+ return flat_layout_dir
57
+
58
+ # Package not found in either location
59
+ raise FileNotFoundError(
60
+ f"Could not find package '{package_name}' in either src layout "
61
+ f"({src_layout_dir}) or flat layout ({flat_layout_dir}). "
62
+ f"Expected to find __init__.py in one of these locations."
63
+ )
64
+
65
+
30
66
  def init_pyproject():
31
67
  """Initialize pyproject.toml with sensible defaults
32
68
  - add [build-system] section with uv build backend (same as `uv init --package`)
@@ -1,52 +0,0 @@
1
- import afterpython as ap
2
-
3
- commitizen_default = {
4
- "tool": {
5
- "commitizen": {
6
- "name": "cz_conventional_commits",
7
- "tag_format": "v$version",
8
- "version_scheme": "pep440",
9
- "version_provider": "uv",
10
- "update_changelog_on_bump": False,
11
- "major_version_zero": True,
12
- }
13
- }
14
- }
15
-
16
-
17
- commitizen_pre_commit_hook = {
18
- "repos": [
19
- {
20
- "repo": "https://github.com/commitizen-tools/commitizen",
21
- "rev": "v4.10.0",
22
- "hooks": [
23
- {
24
- "id": "commitizen",
25
- "stages": ["commit-msg"],
26
- },
27
- {
28
- "id": "commitizen-branch",
29
- "stages": ["pre-push"],
30
- },
31
- ],
32
- },
33
- ]
34
- }
35
-
36
-
37
- def init_commitizen():
38
- from afterpython._io.toml import write_toml
39
- from afterpython.tools.pre_commit import update_pre_commit
40
-
41
- afterpython_path = ap.paths.afterpython_path
42
- commitizen_toml_path = afterpython_path / "cz.toml"
43
- if commitizen_toml_path.exists():
44
- print(f"Commitizen configuration file {commitizen_toml_path} already exists")
45
- return
46
-
47
- # Create commitizen configuration with default values
48
- write_toml(commitizen_toml_path, commitizen_default)
49
- print(f"Created {commitizen_toml_path}")
50
-
51
- # add commitizen hook to .pre-commit-config.yaml
52
- update_pre_commit(commitizen_pre_commit_hook)
@@ -1,60 +0,0 @@
1
- import subprocess
2
-
3
- import afterpython as ap
4
- from afterpython._io.yaml import read_yaml, write_yaml
5
-
6
- pre_commit_default = {
7
- # default is only ["pre-commit"], without changing the default,
8
- # we need to explicitly pass in --hook-type whenever we run "pre-commit install --hook-type ..."
9
- "default_install_hook_types": ["pre-commit", "commit-msg", "pre-push"],
10
- "exclude": "^afterpython/_website/", # do not check the project website template
11
- "repos": [
12
- {
13
- "repo": "https://github.com/pre-commit/pre-commit-hooks",
14
- "rev": "v6.0.0",
15
- "hooks": [
16
- {"id": "trailing-whitespace", "stages": ["pre-commit"]},
17
- {"id": "end-of-file-fixer", "stages": ["pre-commit"]},
18
- {"id": "check-yaml", "stages": ["pre-commit"]},
19
- {"id": "check-toml", "stages": ["pre-commit"]},
20
- {"id": "check-added-large-files", "stages": ["pre-commit"]},
21
- ],
22
- },
23
- # {
24
- # "repo": "https://github.com/astral-sh/uv-pre-commit",
25
- # "rev": "0.9.8",
26
- # "hooks": [
27
- # {"id": "uv-lock"}, # Update the uv lockfile
28
- # ]
29
- # },
30
- ],
31
- }
32
-
33
-
34
- def install_pre_commit():
35
- # installed in .git/hooks
36
- subprocess.run(["ap", "pre-commit", "install", "--install-hooks"], check=True)
37
-
38
-
39
- def update_pre_commit(data_update: dict):
40
- from afterpython.utils import deep_merge
41
-
42
- pre_commit_path = ap.paths.afterpython_path / ".pre-commit-config.yaml"
43
- if not pre_commit_path.exists():
44
- raise FileNotFoundError(
45
- f".pre-commit-config.yaml not found at {pre_commit_path}"
46
- )
47
- existing_data = read_yaml(pre_commit_path)
48
- existing_data = deep_merge(existing_data, data_update)
49
- write_yaml(pre_commit_path, existing_data)
50
- install_pre_commit()
51
-
52
-
53
- def init_pre_commit():
54
- pre_commit_path = ap.paths.afterpython_path / ".pre-commit-config.yaml"
55
- if pre_commit_path.exists():
56
- print(f".pre-commit-config.yaml already exists at {pre_commit_path}")
57
- return
58
- write_yaml(pre_commit_path, pre_commit_default)
59
- print(f"Created {pre_commit_path}")
60
- install_pre_commit()