ChrisBuilds / terminaltexteffects

TerminalTextEffects (TTE) is a terminal visual effects engine, application, and Python library.
https://chrisbuilds.github.io/terminaltexteffects/
MIT License
2.82k stars 49 forks source link

Add support for `--version` argument/switch #15

Closed TurtleWilly closed 3 months ago

TurtleWilly commented 4 months ago

As the title says. For book-keeping on an installation it's usually nice to have a --version argument/switch which, when used, simply would dump the version of the script. Right now the version only seems to be "exposed" via the pyproject.toml file it seems.

$ tte --version
usage: terminaltexteffects [-h] [--input-file INPUT_FILE] [--tab-width (int > 0)] [--xterm-colors] [--no-color] [--wrap-text] [--frame-rate FRAME_RATE] [--canvas-width CANVAS_WIDTH]
                           [--canvas-height CANVAS_HEIGHT] [--ignore-terminal-dimensions]
                           {beams,binarypath,blackhole,bouncyballs,bubbles,burn,colorshift,crumble,decrypt,errorcorrect,expand,fireworks,middleout,orbittingvolley,overflow,pour,print,rain,randomsequence,rings,scattered,slice,slide,spotlights,spray,swarm,synthgrid,unstable,vhstape,waves,wipe}
                           ...
terminaltexteffects: error: the following arguments are required: {beams,binarypath,blackhole,bouncyballs,bubbles,burn,colorshift,crumble,decrypt,errorcorrect,expand,fireworks,middleout,orbittingvolley,overflow,pour,print,rain,randomsequence,rings,scattered,slice,slide,spotlights,spray,swarm,synthgrid,unstable,vhstape,waves,wipe}

😢

Something like this would be better/ more useful:

$ tte --version
tte 0.10.1

Additional note: the help text states usage: terminaltexteffects … while the command seems to be installed as tte, so the help text probably should state usage: tte …. Preferably it would automatically determine this based on the calling command name, e.g. the user my have installed/ moved it to a different name (e.g. could happen when one creates a tte.pyz zippapp). I think skipping the "prog" parameter for argparse.ArgumentParser() would do that?

ChrisBuilds commented 4 months ago

You're making a lot of sense. I've added these changes. There is now a version switch and the help output has been updated to reflect the current calling convention. These will be present in the next release. Here's a preview, ignore the version number itself as it's installed as an editable package on my dev station.

image

image

image

TurtleWilly commented 4 months ago

It's not entirely working for me yet, because now it depends on some mysterious "package metadata" that doesn't seem to exists (may be generated by a PIP installation?)

Running as zipapp (which I prefer in my installation):

$ cd /Volumes/Temporary/terminaltexteffects-main 
$ mkdir zipapptempdir
$ cp -r terminaltexteffects zipapptempdir/

$ cat >zipapptempdir/__main__.py <<__EOF__
import sys

if sys.version_info < (3, 8):
    print('tte requires python 3.8 or better.')
    sys.exit(2)

from terminaltexteffects import __main__ as ttemain

if __name__ == '__main__':
    sys.exit(ttemain.main())

__EOF__

$ find zipapptempdir -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete -o -type f -name '.DS_Store' -delete && \
    python3.12 -m zipapp --output tte.pyz --compress --python /usr/local/bin/python3.12 zipapptempdir

# Now fails (worked with older versions)
$ ./tte.pyz --version
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 397, in from_name
    return next(cls.discover(name=name))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Volumes/Temporary/terminaltexteffects-main/./tte.pyz/__main__.py", line 10, in <module>
  File "/Volumes/Temporary/terminaltexteffects-main/./tte.pyz/terminaltexteffects/__main__.py", line 27, in main
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 888, in version
    return distribution(distribution_name).version
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 861, in distribution
    return Distribution.from_name(distribution_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 399, in from_name
    raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: No package metadata was found for terminaltexteffects

Likewise, just running from the source code directory:

$ cd /Volumes/Temporary/terminaltexteffects-main 
$ PYTHONPATH=. python3.12 /Volumes/Temporary/terminaltexteffects-main/terminaltexteffects/__main__.py --version
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 397, in from_name
    return next(cls.discover(name=name))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Volumes/Temporary/terminaltexteffects-main/terminaltexteffects/__main__.py", line 80, in <module>
    main()
  File "/Volumes/Temporary/terminaltexteffects-main/terminaltexteffects/__main__.py", line 27, in main
    version="TerminalTextEffects " + importlib.metadata.version("terminaltexteffects"),
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 888, in version
    return distribution(distribution_name).version
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 861, in distribution
    return Distribution.from_name(distribution_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 399, in from_name
    raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: No package metadata was found for terminaltexteffects
ChrisBuilds commented 4 months ago

The current solution for identifying the version relies on 'importlib.metadata'. I hadn't considered that this method requires the package to be properly installed. Given TTE has a supported system application use case, I'll make the appropriate changes to remove this requirement. Thanks.

ChrisBuilds commented 3 months ago

Fixed in 0.11.0.