afterpython 0.3.2__py3-none-any.whl → 0.3.4__py3-none-any.whl

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.
@@ -251,7 +251,10 @@ def website(ctx, no_backup: bool):
251
251
  ensure_website_gitignore_rules()
252
252
  except Exception as e:
253
253
  click.echo(f"✗ Error updating project website template: {e}", err=True)
254
- if not no_backup:
254
+ # On a fresh `ap init`, website_path didn't exist beforehand, so no backup
255
+ # was created — skip restore in that case rather than crashing with
256
+ # FileNotFoundError, which would mask the real error above.
257
+ if not no_backup and backup_path.exists():
255
258
  click.echo("Restoring from backup...")
256
259
  if website_path.exists():
257
260
  shutil.rmtree(website_path)
@@ -92,10 +92,20 @@ jobs:
92
92
  uv pip install --system . --group test || uv pip install --system .
93
93
 
94
94
  - name: Run tests with pytest
95
- # Run pytest with verbose output
96
- # Exit code 5 (no tests collected) is treated as success
95
+ # Tolerant by design: if pytest isn't installed, the project has no
96
+ # [dependency-groups] test (the install step fell back to `uv pip
97
+ # install --system .`). Treat that the same as "no tests yet" and
98
+ # pass green — matches the install step's tolerance.
99
+ # When pytest does run, exit code 5 (no tests collected) is success.
100
+ # We capture pytest's exit code before any other command clobbers $?.
97
101
  run: |
98
- pytest -v || if [ $? -eq 5 ]; then exit 0; else exit $?; fi
102
+ if ! command -v pytest >/dev/null 2>&1; then
103
+ echo "pytest not installed (no [dependency-groups] test); skipping."
104
+ exit 0
105
+ fi
106
+ pytest -v
107
+ code=$?
108
+ if [ $code -eq 5 ]; then exit 0; else exit $code; fi
99
109
 
100
110
  # Job 3.2: Test Suite - Pixi Workflow
101
111
  # Pixi-based testing for projects using pixi.toml
@@ -114,7 +124,7 @@ jobs:
114
124
  uses: actions/checkout@v6
115
125
 
116
126
  - name: Set up pixi
117
- uses: prefix-dev/setup-pixi@v0.9.4
127
+ uses: prefix-dev/setup-pixi@v0.9.5
118
128
  with:
119
129
  pixi-version: v0.67.2
120
130
  cache: true
@@ -145,15 +155,21 @@ jobs:
145
155
  run: |
146
156
  uv_result="${{ needs.test-uv.result }}"
147
157
  pixi_result="${{ needs.test-pixi.result }}"
148
- # One should succeed, the other should be skipped
149
- if [ "$uv_result" == "success" ] || [ "$uv_result" == "skipped" ]; then
150
- if [ "$pixi_result" == "success" ] || [ "$pixi_result" == "skipped" ]; then
151
- echo "All tests passed!"
152
- exit 0
153
- fi
158
+ # Invariant: exactly one track runs (use_pixi gate) and must succeed;
159
+ # the other is skipped. Any other combination — both skipped (detect
160
+ # job died), both succeeded (broken gating), or anything failing —
161
+ # is red. The "no tests yet" case is handled inside the running track
162
+ # (pytest step exits 0), so it reports success here, not skipped.
163
+ if [ "$uv_result" == "success" ] && [ "$pixi_result" == "skipped" ]; then
164
+ echo "All tests passed (uv track)."
165
+ exit 0
166
+ elif [ "$pixi_result" == "success" ] && [ "$uv_result" == "skipped" ]; then
167
+ echo "All tests passed (pixi track)."
168
+ exit 0
169
+ else
170
+ echo "Tests did not pass cleanly: uv=$uv_result, pixi=$pixi_result"
171
+ exit 1
154
172
  fi
155
- echo "Tests failed: uv=$uv_result, pixi=$pixi_result"
156
- exit 1
157
173
 
158
174
  # Job 4: Build Verification
159
175
  # Ensures the package can be built successfully
@@ -37,12 +37,13 @@ repos:
37
37
  args:
38
38
  - --config
39
39
  - ./afterpython/ruff.toml
40
- - repo: https://github.com/commitizen-tools/commitizen
41
- rev: v4.13.10
42
- hooks:
43
- - id: commitizen
44
- stages:
45
- - commit-msg
46
- - id: commitizen-branch
47
- stages:
48
- - pre-push
40
+ # NOTE: buggy commitizen, skip it, not useful anyways
41
+ # - repo: https://github.com/commitizen-tools/commitizen
42
+ # rev: v4.16.0
43
+ # hooks:
44
+ # - id: commitizen
45
+ # stages:
46
+ # - commit-msg
47
+ # - id: commitizen-branch
48
+ # stages:
49
+ # - pre-push
@@ -119,7 +119,7 @@ def init_afterpython():
119
119
  },
120
120
  "website": {
121
121
  "url": "",
122
- "favicon": "favicon.svg",
122
+ "favicon": "favicon.ico",
123
123
  "logo": "logo.svg",
124
124
  "logo_dark": "logo.svg",
125
125
  "thumbnail": "thumbnail.png",
afterpython/tools/myst.py CHANGED
@@ -182,7 +182,9 @@ def init_myst():
182
182
 
183
183
  # find any existing node.js version and use it, if no, install the Node.js version specified in NODEENV_VERSION
184
184
  node_env: NodeEnv = find_node_env()
185
- subprocess.run(["npm", "install", "-g", "pnpm"], env=node_env, check=True)
185
+ # Pin to pnpm major version — `npm install -g pnpm` (unpinned) caused a
186
+ # silent 9→10 jump that broke `ap init` via ERR_PNPM_IGNORED_BUILDS.
187
+ subprocess.run(["npm", "install", "-g", "pnpm@11"], env=node_env, check=True)
186
188
  for content_type in CONTENT_TYPES:
187
189
  path = ap.paths.afterpython_path / content_type
188
190
  print(f"Initializing MyST Markdown (mystmd) in {path.name}/ directory ...")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afterpython
3
- Version: 0.3.2
3
+ Version: 0.3.4
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
@@ -17,17 +17,17 @@ Classifier: Programming Language :: Python :: 3.13
17
17
  Requires-Dist: click>=8.2.1
18
18
  Requires-Dist: trogon>=0.6.0
19
19
  Requires-Dist: httpx>=0.28.1
20
- Requires-Dist: tomlkit>=0.14.0
20
+ Requires-Dist: tomlkit>=0.15.0
21
21
  Requires-Dist: ruamel-yaml>=0.19.1
22
22
  Requires-Dist: gitpython>=3.1.50
23
23
  Requires-Dist: python-dotenv>=1.2.2
24
24
  Requires-Dist: pyproject-metadata>=0.11.0
25
- Requires-Dist: jupytext>=1.19.1
25
+ Requires-Dist: jupytext>=1.19.2
26
26
  Requires-Dist: mystmd>=1.9.0
27
27
  Requires-Dist: pdoc>=16.0.0
28
28
  Requires-Dist: ruff>=0.15.12
29
29
  Requires-Dist: pre-commit>=4.6.0
30
- Requires-Dist: commitizen>=4.13.10
30
+ Requires-Dist: commitizen>=4.16.0
31
31
  Requires-Python: >=3.11
32
32
  Project-URL: homepage, https://afterpython.afterpython.org
33
33
  Project-URL: repository, https://github.com/AfterPythonOrg/afterpython
@@ -35,31 +35,31 @@ afterpython/cli/commands/remove.py,sha256=Fl79JSI9IdHyzYflocXxcxgBkBPkNFAW98Yuij
35
35
  afterpython/cli/commands/serve.py,sha256=L0LIhMGByQA_mNTOAGHQTQ8TcBfi5sgmO1_iGI24QgI,822
36
36
  afterpython/cli/commands/start.py,sha256=q4rUkIllOO8wJQ9ABtsx-dqkW1yC0vltAtSkiHN_GH4,4002
37
37
  afterpython/cli/commands/sync.py,sha256=Av67jsCBxhh1skixihPgNyvZMUsh_j0pQGmG4EoR_A8,6318
38
- afterpython/cli/commands/update.py,sha256=CM3CZJsSRdiyeWl19Dx5eyYeXK5w7jU0hpC4x9ENuB4,9154
38
+ afterpython/cli/commands/update.py,sha256=082K1rg-ctCuKB_E7g_p-UWkTA9hoC65yhkIrtLZQ18,9408
39
39
  afterpython/cli/main.py,sha256=-9eQiIrUViSvof-Ic2RHF3AVZharPSQh9sJ7tkhvf6Q,5042
40
40
  afterpython/const.py,sha256=B_yUBmHPyu98aOibwt7idWbhKNBBed0TeYXNBd8tPTk,157
41
41
  afterpython/main.py,sha256=w0z6mTib3u4p2HxMrk-tIJlZtur7uRaqsbE0ewlYlSs,490
42
42
  afterpython/pcu.py,sha256=EoEhSzFZ49b5qc9KH2RLxIHSzY8YFM5uhtw07chcrr8,6093
43
43
  afterpython/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- afterpython/templates/ci-workflow-template.yml,sha256=NSuPjSgo9l70a1IwUuasvgKk-Kbyunk66ZXcUGDzBQU,6150
44
+ afterpython/templates/ci-workflow-template.yml,sha256=B3Rn5Ta1Bot1jKQ8ALBqQI8BDQ8mwIhpIA_umnXJ9oc,7115
45
45
  afterpython/templates/cz-template.toml,sha256=2qwbQLb0nbZaA63oWXFFzvzPNBsFZHATL1C2rdNdjjs,185
46
46
  afterpython/templates/dependabot-template.yml,sha256=CBQEgh8EsXw2X7IqzGtFI7lVT9liF6PW4DvGLB0X2LY,1136
47
47
  afterpython/templates/deploy-workflow-template.yml,sha256=L3dSB0WdUvuW2C65MqxkMNbUFCU8-eGvfS_wUj2etNU,2397
48
48
  afterpython/templates/pdoc/frame.html.jinja2,sha256=GX4pNSuYC4Fq9hvZ01WyaBQes4FyNDOx5Ra4MNLr0eg,250
49
- afterpython/templates/pre-commit-config-template.yaml,sha256=FfQb0mVWouGmV62uCF5WO18hodZhGt-PfybB6m9nsAM,917
49
+ afterpython/templates/pre-commit-config-template.yaml,sha256=3QkZekg2kK04-Dp8nGc9AsqEdpnh10EcdD6pBhyKpRQ,988
50
50
  afterpython/templates/release-workflow-template.yml,sha256=3YBkgrqmi--uznslpMxPz7Vj7L4_NPlhDxgwYBt-Ui8,1606
51
51
  afterpython/templates/ruff-template.toml,sha256=lNCd4EthoLScr4cyVEgGUH4xK5CfIX3f9I3zkJHAYgg,1008
52
- afterpython/tools/_afterpython.py,sha256=IgzUG8ihdaqrqLIma8yy6pVtC2ldt4jyWOf6FQWnKCU,4345
52
+ afterpython/tools/_afterpython.py,sha256=a82taUWoY8yXmzE1m25zV0-vwmyglp5X7G2Erjz3oLw,4345
53
53
  afterpython/tools/_git.py,sha256=aO-qDEQ4OevD_B74DYKK4nQKYeiaS1BXmYc8paJRfbQ,3772
54
54
  afterpython/tools/branch_rules.py,sha256=ciQ2H2YBnoCZu_plyVeIHzf2FcAILRFhpjzOR2_IfJg,3159
55
55
  afterpython/tools/commitizen.py,sha256=ZO1qHmzUU0myd85tncv76WtIR7DB_AoQGSUvaf78Ohg,438
56
56
  afterpython/tools/github_actions.py,sha256=0xzOc41QF1PKagD1CW7BAt_Rugy0KCEx_KfcrPKVl3c,3168
57
- afterpython/tools/myst.py,sha256=2VO-gD25PbGSD8-v1sLI1v3Q9loahRd3ednKrW4_Utc,8113
57
+ afterpython/tools/myst.py,sha256=VunqoTxWE6y9LXYPBh_JvLMW8kqGMGBkqYkhr_bLvj8,8269
58
58
  afterpython/tools/pre_commit.py,sha256=oNsrUkPI13rSSBSyhyTTKPnQGhDxLIPYhxu6kL0fDmo,1206
59
59
  afterpython/tools/pyproject.py,sha256=hz-DOf-pkGBF2m_RqEZipAaO-NDbsLxrrc65LWAIwLA,3698
60
60
  afterpython/utils.py,sha256=fVa3jIzCvhn7QA7N0M6d_pvojpPFrN-hae8trUYhPKU,11701
61
61
  afterpython/version.py,sha256=hihRV1S-gc1m46OaXD32ikkEkqzs-Gtq7AcAqOQV-wY,1603
62
- afterpython-0.3.2.dist-info/WHEEL,sha256=-unyBNsdNo6Y_XVO25zjvxasG_uUFN_fBd_kLyKE-Fk,81
63
- afterpython-0.3.2.dist-info/entry_points.txt,sha256=roa0PDgBueM1JPbRG0G2OSxzaN394OUL_oS9iEwVLBc,80
64
- afterpython-0.3.2.dist-info/METADATA,sha256=Rhe3BEDPDmJrHdwZtiNQwa6EJ71P975ErqSNeLLrerE,6181
65
- afterpython-0.3.2.dist-info/RECORD,,
62
+ afterpython-0.3.4.dist-info/WHEEL,sha256=fWriCkzqm-pffF5af4gJC9iI5FMFaJTuN9UxxxzOmdY,81
63
+ afterpython-0.3.4.dist-info/entry_points.txt,sha256=roa0PDgBueM1JPbRG0G2OSxzaN394OUL_oS9iEwVLBc,80
64
+ afterpython-0.3.4.dist-info/METADATA,sha256=xlwC3Jg5207-ZdUEyYj6LWz3qUjzOmxQBLTssubXcf8,6180
65
+ afterpython-0.3.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.11.12
2
+ Generator: uv 0.11.14
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any