Skip to content

Commit b2ee8cd

Browse files
refactor: display aliases next to the original command when running "ap --help"
1 parent dc884ef commit b2ee8cd

File tree

10 files changed

+104
-36
lines changed

10 files changed

+104
-36
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ First-time maintainers must learn multiple tools and concepts, e.g. [MyST], [Sem
4040

4141
## Core Features
4242
- [x] Write content directly in [MyST Markdown] or [Jupyter Notebook]
43-
- [x] Go from writing to website deployment in minutes — no need to learn any of the underlying tools
44-
- [x] Centralize all your content in a modern, unified project website — from documentation to blog posts
43+
- [x] Go from writing to **website deployment in minutes** — no need to learn any of the underlying tools
44+
- [x] Centralize all your content in a modern, **unified project website** — from documentation to blog posts
45+
- [x] Zero-config orchestration — Pre-configured modern tooling with sane defaults (see [Tech Stack](#tech-stack)), so you can start maintaining packages immediately **without learning each tool**
4546
- [ ] Export content as PDF — for example, combine all blog posts into a single PDF file
4647
- [ ] **⚡ Full-text search** across **ALL** your content in your website — docs, blogs, tutorials, everything
4748
- [ ] **🤖 Embedded AI Chatbot** that answers questions directly using an in-browser LLM — at no cost

afterpython/blog/myst.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ project:
1919
url: https://afterpython.org
2020
copyright: © AfterPython.Org 2025. All rights reserved.
2121
title: ''
22-
description: CLI tool for AfterPython
22+
description: CLI tool to streamline Python package maintenance and generate a dedicated project website
2323
keywords:
2424
- package-maintenance
2525
- project-website
@@ -50,14 +50,14 @@ site:
5050
nav:
5151
- title: AfterPython.Org
5252
url: https://afterpython.org
53-
- title: Guides
54-
url: https://afterpython.afterpython.org/guide
5553
- title: Tutorials
5654
url: https://afterpython.afterpython.org/tutorial
57-
- title: Docs
58-
url: https://afterpython.afterpython.org/doc
5955
- title: Examples
6056
url: https://afterpython.afterpython.org/example
57+
- title: Docs
58+
url: https://afterpython.afterpython.org/doc
59+
- title: Guides
60+
url: https://afterpython.afterpython.org/guide
6161
actions:
6262
- title: ⭐ Star
6363
url: https://github.com/AfterPythonOrg/afterpython

afterpython/cli/commands/commit.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@
1515
@click.option(
1616
"--no-cz", "--no-commitizen", is_flag=True, help="Skip running 'cz commit'"
1717
)
18-
def commit(ctx, no_cz: bool):
18+
@click.option(
19+
"--no-pc",
20+
"--no-pre-commit",
21+
is_flag=True,
22+
help="Skip running pre-commit checks before commit",
23+
)
24+
def commit(ctx, no_cz: bool, no_pc: bool):
1925
"""Run 'cz commit'"""
2026
from afterpython.utils import handle_passthrough_help
2127

@@ -26,6 +32,15 @@ def commit(ctx, no_cz: bool):
2632
show_underlying=True,
2733
)
2834

35+
# Run pre-commit checks first (unless --no-pc is set)
36+
if not no_pc:
37+
result = subprocess.run(["ap", "pc", "run"])
38+
if result.returncode != 0:
39+
click.echo(
40+
"❌ Pre-commit checks failed. Please fix the issues and try again."
41+
)
42+
ctx.exit(1)
43+
2944
if not no_cz:
3045
subprocess.run(["ap", "cz", "commit", *ctx.args])
3146
else:

afterpython/cli/main.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import os
22
import subprocess
3+
from collections import defaultdict
34

45
import click
56
from trogon import tui
67
from dotenv import load_dotenv, find_dotenv
7-
88
import afterpython as ap
99
from afterpython import __version__
1010
from afterpython.cli.commands.init import init
@@ -26,8 +26,60 @@
2626
from afterpython.cli.commands.init_branch_rules import init_branch_rules
2727

2828

29+
class AliasGroup(click.Group):
30+
"""Custom group that displays command aliases together."""
31+
32+
def __init__(self, *args, **kwargs):
33+
super().__init__(*args, **kwargs)
34+
self._aliases = defaultdict(list) # Maps primary command -> list of aliases
35+
self._alias_to_primary = {} # Maps alias -> primary command name
36+
37+
def add_command(self, cmd, name=None):
38+
"""Track aliases when the same command is added with different names."""
39+
name = name or cmd.name
40+
41+
# Check if this command object was already added under a different name
42+
for existing_name, existing_cmd in self.commands.items():
43+
if existing_cmd is cmd and existing_name != name:
44+
# This is an alias
45+
self._aliases[existing_name].append(name)
46+
self._alias_to_primary[name] = existing_name
47+
break
48+
49+
super().add_command(cmd, name)
50+
51+
def format_commands(self, ctx, formatter):
52+
"""Format commands with aliases shown together."""
53+
commands = []
54+
for subcommand in self.list_commands(ctx):
55+
# Skip aliases - they'll be shown with their primary command
56+
if subcommand in self._alias_to_primary:
57+
continue
58+
59+
cmd = self.get_command(ctx, subcommand)
60+
if cmd is None:
61+
continue
62+
63+
# Skip hidden commands
64+
if cmd.hidden:
65+
continue
66+
67+
help_text = cmd.get_short_help_str(limit=formatter.width)
68+
69+
# Build command name with aliases
70+
aliases = self._aliases.get(subcommand, [])
71+
if aliases:
72+
subcommand = f"{subcommand}, {', '.join(aliases)}"
73+
74+
commands.append((subcommand, help_text))
75+
76+
if commands:
77+
with formatter.section("Commands"):
78+
formatter.write_dl(commands)
79+
80+
2981
@tui(command="tui", help="Open terminal UI")
30-
@click.group(context_settings={"help_option_names": ["-h", "--help"]})
82+
@click.group(cls=AliasGroup, context_settings={"help_option_names": ["-h", "--help"]})
3183
@click.pass_context
3284
@click.version_option(version=__version__)
3385
def afterpython_group(ctx):
@@ -65,7 +117,6 @@ def afterpython_group(ctx):
65117
afterpython_group.add_command(clean)
66118
afterpython_group.add_command(pre_commit)
67119
afterpython_group.add_command(pre_commit, name="pc")
68-
afterpython_group.add_command(pre_commit, name="precommit")
69120
afterpython_group.add_command(commitizen)
70121
afterpython_group.add_command(commitizen, name="cz")
71122
afterpython_group.add_command(commit)

afterpython/doc/myst.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ project:
2020
# To autogenerate a Table of Contents, run "myst init --write-toc"
2121
copyright: © AfterPython.Org 2025. All rights reserved.
2222
# title:
23-
description: CLI tool for AfterPython
23+
description: CLI tool to streamline Python package maintenance and generate a dedicated project website
2424
keywords:
2525
- package-maintenance
2626
- project-website
@@ -64,14 +64,14 @@ site:
6464
nav:
6565
- title: AfterPython.Org
6666
url: https://afterpython.org
67-
- title: Guides
68-
url: https://afterpython.afterpython.org/guide
6967
- title: Tutorials
7068
url: https://afterpython.afterpython.org/tutorial
71-
- title: Examples
72-
url: https://afterpython.afterpython.org/example
7369
- title: Blogs
7470
url: https://afterpython.afterpython.org/blog
71+
- title: Examples
72+
url: https://afterpython.afterpython.org/example
73+
- title: Guides
74+
url: https://afterpython.afterpython.org/guide
7575
actions:
7676
- title: ⭐ Star
7777
url: https://github.com/AfterPythonOrg/afterpython

afterpython/doc/overview.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
---
2323
## Why use `afterpython`
2424
- Write content directly in [MyST Markdown] or [Jupyter Notebook]
25-
- Go from writing to website deployment in minutes — no need to learn any of the underlying tools
26-
- Centralize all your content in a modern, unified project website — from documentation to blog posts
25+
- Go from writing to **website deployment in minutes** — no need to learn any of the underlying tools
26+
- Centralize all your content in a modern, **unified project website** — from documentation to blog posts
27+
- Zero-config orchestration — Pre-configured modern tooling with sane defaults (see [](overview.md#tech-stack)), so you can start maintaining packages immediately **without learning each tool**
2728
- 🚧 Export content as PDF — for example, combine all blog posts into a single PDF file
2829
- 🚧 **⚡ Full-text search** across **ALL** your content in your website — docs, blogs, tutorials, everything
2930
- 🚧 **🤖 Embedded AI Chatbot** that answers questions directly using an in-browser LLM — at no cost

afterpython/example/myst.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ project:
1919
url: https://afterpython.org
2020
copyright: © AfterPython.Org 2025. All rights reserved.
2121
title: ''
22-
description: CLI tool for AfterPython
22+
description: CLI tool to streamline Python package maintenance and generate a dedicated project website
2323
keywords:
2424
- package-maintenance
2525
- project-website
@@ -50,14 +50,14 @@ site:
5050
nav:
5151
- title: AfterPython.Org
5252
url: https://afterpython.org
53-
- title: Guides
54-
url: https://afterpython.afterpython.org/guide
5553
- title: Tutorials
5654
url: https://afterpython.afterpython.org/tutorial
57-
- title: Docs
58-
url: https://afterpython.afterpython.org/doc
5955
- title: Blogs
6056
url: https://afterpython.afterpython.org/blog
57+
- title: Docs
58+
url: https://afterpython.afterpython.org/doc
59+
- title: Guides
60+
url: https://afterpython.afterpython.org/guide
6161
actions:
6262
- title: ⭐ Star
6363
url: https://github.com/AfterPythonOrg/afterpython

afterpython/guide/myst.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ project:
1919
url: https://afterpython.org
2020
copyright: © AfterPython.Org 2025. All rights reserved.
2121
title: ''
22-
description: CLI tool for AfterPython
22+
description: CLI tool to streamline Python package maintenance and generate a dedicated project website
2323
keywords:
2424
- package-maintenance
2525
- project-website
@@ -52,12 +52,12 @@ site:
5252
url: https://afterpython.org
5353
- title: Tutorials
5454
url: https://afterpython.afterpython.org/tutorial
55-
- title: Docs
56-
url: https://afterpython.afterpython.org/doc
57-
- title: Examples
58-
url: https://afterpython.afterpython.org/example
5955
- title: Blogs
6056
url: https://afterpython.afterpython.org/blog
57+
- title: Examples
58+
url: https://afterpython.afterpython.org/example
59+
- title: Docs
60+
url: https://afterpython.afterpython.org/doc
6161
actions:
6262
- title: ⭐ Star
6363
url: https://github.com/AfterPythonOrg/afterpython

afterpython/tutorial/myst.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ project:
1919
url: https://afterpython.org
2020
copyright: © AfterPython.Org 2025. All rights reserved.
2121
title: ''
22-
description: CLI tool for AfterPython
22+
description: CLI tool to streamline Python package maintenance and generate a dedicated project website
2323
keywords:
2424
- package-maintenance
2525
- project-website
@@ -50,14 +50,14 @@ site:
5050
nav:
5151
- title: AfterPython.Org
5252
url: https://afterpython.org
53-
- title: Guides
54-
url: https://afterpython.afterpython.org/guide
55-
- title: Docs
56-
url: https://afterpython.afterpython.org/doc
57-
- title: Examples
58-
url: https://afterpython.afterpython.org/example
5953
- title: Blogs
6054
url: https://afterpython.afterpython.org/blog
55+
- title: Examples
56+
url: https://afterpython.afterpython.org/example
57+
- title: Docs
58+
url: https://afterpython.afterpython.org/doc
59+
- title: Guides
60+
url: https://afterpython.afterpython.org/guide
6161
actions:
6262
- title: ⭐ Star
6363
url: https://github.com/AfterPythonOrg/afterpython

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "afterpython"
33
version = "0.1.0.dev8"
4-
description = "CLI tool for AfterPython"
4+
description = "CLI tool to streamline Python package maintenance and generate a dedicated project website"
55
license = "Apache-2.0"
66
authors = [
77
{ name = "Stephen Yau", email = "softwareentrepreneer+afterpython@gmail.com" },

0 commit comments

Comments
 (0)