Skip to content

Commit a20b6fd

Browse files
committed
Recommend pyproject.toml be used for command-lines not bin.src
1 parent a70e672 commit a20b6fd

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

python/cli.rst

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,24 @@ Read more in the `argparse documentation`_.
3333

3434
.. _argparse documentation: https://docs.python.org/3/library/argparse.html
3535

36+
.. _add_callable_cli_command_to_your_package:
37+
3638
Add a Callable CLI Command To Your Package
3739
==========================================
3840

39-
To create a callable command at the top level of your package create a folder called ``bin.src``.
40-
It should contain two files:
41+
If your callable command is implemented as described in :doc:`stack/argparse-script-topic-type` with a single function loading from the package implementing the script, you can define the script in the `standard Python package approach using <https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#creating-executable-scripts>`_ ``pyproject.toml``.
42+
For example, this:
43+
44+
.. code-block:: toml
45+
46+
[project.scripts]
47+
exampleScript = "lsst.example.scripts.exampleScript:main"
48+
49+
will result in a executable file appearing in ``bin/exampleScript`` that will import ``main`` from ``lsst.example.scripts.exampleScript`` and call it.
50+
This is the recommended way to define callable commands and all newly-written scripts should be defined this way.
51+
52+
If your script is monolithic and includes the implementation directly in the callable script and you cannot reorganize the code, you must instead write the command to a ``bin.src`` directory at the top level.
53+
The directory should contain:
4154

4255
1. ``SConscript`` with contents:
4356

@@ -47,8 +60,7 @@ It should contain two files:
4760
from lsst.sconsUtils import scripts
4861
scripts.BasicSConscript.shebang()
4962
50-
2. A file that has the name of the CLI command the user will call.
51-
This file should contain as little implementation as possible.
52-
The ideal simplest case is to import an implementation function and call it.
53-
This makes the implementation testable and reusable.
63+
2. A file for each command that has the name of the CLI command the user will call.
64+
This file should have a Python shebang (``#!``) in the first line.
5465

66+
It is possible for a package to define some scripts in ``pyproject.toml`` and some scripts in ``bin.src`` but it is an error if a script is defined in both places.

stack/argparse-script-topic-type.rst

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,9 @@ autoprogram_ generates all the content that is described by the :doc:`script top
6060

6161
To use the autoprogram_ directive, your script needs to be set up in a particular fashion:
6262

63-
- The script needs to be in the ``bin.src`` directory of a package, but the script file must defer its implementation to a module *inside* the package's Python modules.
63+
- The script needs to be defined such that the implementation is in a module *inside* the package's Python modules, with the script function specified in the package's ``pyproject.toml`` (see :doc:`python/add_callable_cli_command_to_your_package` for more information).
6464

65-
For example, a script file :file:`bin.src/exampleScript.py` might be structured like this:
66-
67-
.. code-block:: python
68-
69-
#! /usr/bin/env python
70-
71-
from lsst.example.scripts.exampleScript import main
72-
73-
74-
if __name__ == "__main__":
75-
main()
65+
For example, a script file might be implemented as a ``main`` function found in ``lsst.example.scripts.exampleScript`` and be defined as a command line program called ``exampleScript``.
7666

7767
- The `argparse.ArgumentParser` instance must be generated by an argument-less function.
7868
This is critical for letting the autoprogram_ directive get a copy of the `~argparse.ArgumentParser` instance to introspect the command-line interface:

0 commit comments

Comments
 (0)