|
55 | 55 | "with the digit 3, platform overrides are permitted, and regular Python " + |
56 | 56 | "options may follow. " + |
57 | 57 | "!G!py -3!W! is the equivalent of the !G!python3!W! command."), |
| 58 | + (f"{EXE_NAME} exec !B!<any of the above>!W!\n", |
| 59 | + "Equivalent to any of the above launch options, and the requested runtime " + |
| 60 | + "will be installed if needed."), |
58 | 61 | ] |
59 | 62 |
|
60 | 63 |
|
@@ -519,14 +522,19 @@ def show_usage(cls): |
519 | 522 | else: |
520 | 523 | usage_docs = PYMANAGER_USAGE_DOCS |
521 | 524 |
|
522 | | - usage_docs = usage_docs + [ |
523 | | - ( |
524 | | - f"{EXE_NAME} " + getattr(COMMANDS[cmd], "USAGE_LINE", cmd), |
525 | | - getattr(COMMANDS[cmd], "HELP_LINE", "") |
526 | | - ) |
527 | | - for cmd in sorted(COMMANDS) |
528 | | - if cmd[:1].isalpha() |
529 | | - ] |
| 525 | + usage_docs = list(usage_docs) |
| 526 | + for cmd in sorted(COMMANDS): |
| 527 | + if not cmd[:1].isalpha(): |
| 528 | + continue |
| 529 | + try: |
| 530 | + usage_docs.append( |
| 531 | + ( |
| 532 | + f"{EXE_NAME} " + getattr(COMMANDS[cmd], "USAGE_LINE", cmd), |
| 533 | + COMMANDS[cmd].HELP_LINE |
| 534 | + ) |
| 535 | + ) |
| 536 | + except AttributeError: |
| 537 | + pass |
530 | 538 |
|
531 | 539 | usage_docs = [(f" {x.lstrip()}", y) for x, y in usage_docs] |
532 | 540 |
|
@@ -637,10 +645,12 @@ def get_install_to_run(self, tag=None, script=None, *, windowed=False): |
637 | 645 |
|
638 | 646 | class ListCommand(BaseCommand): |
639 | 647 | CMD = "list" |
640 | | - HELP_LINE = ("Shows installed Python runtimes, optionally filtering by " + |
| 648 | + HELP_LINE = ("Show installed Python runtimes, optionally filtering by " + |
641 | 649 | "!B!<FILTER>!W!.") |
642 | 650 | USAGE_LINE = "list !B![<FILTER>]!W!" |
643 | 651 | HELP_TEXT = r"""!G!List command!W! |
| 652 | +Shows installed Python runtimes, optionally filtered or formatted. |
| 653 | +
|
644 | 654 | > py list !B![options] [<FILTER> ...]!W! |
645 | 655 |
|
646 | 656 | !G!Options:!W! |
@@ -718,6 +728,8 @@ class InstallCommand(BaseCommand): |
718 | 728 | "update existing installs.") |
719 | 729 | USAGE_LINE = "install !B!<TAG>!W!" |
720 | 730 | HELP_TEXT = r"""!G!Install command!W! |
| 731 | +Downloads new Python runtimes and sets up shortcuts and other registration. |
| 732 | +
|
721 | 733 | > py install !B![options] <TAG> [<TAG>] ...!W! |
722 | 734 |
|
723 | 735 | !G!Options:!W! |
@@ -797,12 +809,16 @@ class UninstallCommand(BaseCommand): |
797 | 809 | "!B!--purge!W! to clean up all runtimes and cached files.") |
798 | 810 | USAGE_LINE = "uninstall !B!<TAG>!W!" |
799 | 811 | HELP_TEXT = r"""!G!Uninstall command!W! |
| 812 | +Removes one or more runtimes from your machine. |
| 813 | +
|
800 | 814 | > py uninstall !B![options] <TAG> [<TAG>] ...!W! |
801 | 815 |
|
802 | 816 | !G!Options:!W! |
803 | | - --purge Remove all runtimes, shortcuts, and cached files. Ignores tags. |
804 | | - --by-id Require TAG to exactly match the install ID. (For advanced use.) |
805 | | - !B!<TAG> <TAG>!W! ... One or more runtimes to uninstall (Company\Tag format) |
| 817 | + --purge Remove all runtimes, shortcuts, and cached files. Ignores tags. |
| 818 | + --by-id Require TAG to exactly match the install ID. (For advanced use.) |
| 819 | + !B!<TAG> <TAG>!W! ... One or more runtimes to uninstall (Company\Tag format) |
| 820 | + Each tag will only remove a single runtime, even if it matches |
| 821 | + more than one. |
806 | 822 |
|
807 | 823 | !B!EXAMPLE:!W! Uninstall Python 3.12 32-bit |
808 | 824 | > py uninstall 3.12-32 |
@@ -838,6 +854,8 @@ class HelpCommand(BaseCommand): |
838 | 854 | HELP_LINE = "Show help for Python installation manager commands" |
839 | 855 | USAGE_LINE = "help !B![<CMD>]!W!" |
840 | 856 | HELP_TEXT = r"""!G!Help command!W! |
| 857 | +Shows help for specific commands. |
| 858 | +
|
841 | 859 | > py help !B![<CMD>] ...!W! |
842 | 860 |
|
843 | 861 | !G!Options:!W! |
@@ -882,6 +900,36 @@ def execute(self): |
882 | 900 | LOGGER.print(f"The command !R!{' '.join(args)}!W! was not recognized.") |
883 | 901 |
|
884 | 902 |
|
| 903 | +# This command exists solely to provide help. |
| 904 | +# When it is specified, it gets handled in main.cpp |
| 905 | +class ExecCommand(BaseCommand): |
| 906 | + CMD = "exec" |
| 907 | + HELP_TEXT = f"""!G!Execute command!W! |
| 908 | +Launches the specified (or default) runtime. This command is optional when |
| 909 | +launching through !G!py!W!, as the default behaviour is to launch a runtime. |
| 910 | +When used explicitly, this command will automatically install the requested |
| 911 | +runtime if it is not available. |
| 912 | +
|
| 913 | +> {EXE_NAME} exec -V:!B!<TAG>!W! ... |
| 914 | +> {EXE_NAME} exec -3!B!<VERSION>!W! ... |
| 915 | +> {EXE_NAME} exec ... |
| 916 | +> py [ -V:!B!<TAG>!W! | -3!B!<VERSION>!W! ] ... |
| 917 | +
|
| 918 | +!G!Options:!W! |
| 919 | + -V:!B!<TAG>!W! Launch runtime identified by !B!<TAG>!W!, which should include |
| 920 | + the company name if not !B!PythonCore!W!. Regular Python options |
| 921 | + may follow this option. The runtime will be installed if needed. |
| 922 | + -3!B!<VERSION>!W! Equivalent to -V:PythonCore\3!B!<VERSION>!W!. The version must |
| 923 | + begin with a '3', platform overrides are permitted, and regular |
| 924 | + Python options may follow. The runtime will be installed if needed. |
| 925 | +""" |
| 926 | + |
| 927 | + def __init__(self, args, root=None): |
| 928 | + # Essentially disable argument processing for this command |
| 929 | + super().__init__(args[:1], root) |
| 930 | + self.args = args[1:] |
| 931 | + |
| 932 | + |
885 | 933 | class DefaultConfig(BaseCommand): |
886 | 934 | CMD = "__no_command" |
887 | 935 | _create_log_file = False |
|
0 commit comments