Skip to content

Commit

Permalink
Fix completion-related breakage
Browse files Browse the repository at this point in the history
Click introduced a new API in 8.1 and made it backwards-incompatible.
They also changed the invocation with 8.0.

Documentation was updated to include the new way to get the completion,
along with some examples for Linux distributions that support the major
version 7 or 8 of click.

To support most click versions, the completion was changed to work from
click 7.0 onwards, by conditionally changing the argument handed to the
"option" decorator. Additionally, the completion function now simply
uses kwargs, support the different calling conventions throughout the
versions.

Since it isn't yet known if there will be more breakage in future
versions, this commit limits the allowed / supported versions of click
to less than 8.2, which is expected to be the next release.

Thanks to @poggenpower for finding this.

Fixes #17
Fixes #18
  • Loading branch information
svalouch committed May 5, 2022
1 parent 2b3a676 commit 423a484
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 11 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,24 @@ All notable changes to this project will be documented in this file.
- Mention checksum algorithm.
- List all known commands as well as reserved ones.
- Describe plant communication, which has not been tested yet.
- CLI invocation: Bash-completion activation changed with newer versions of `Click`.

### Features

- `Command` has new functions `is_write` and `is_response` to help working with received frames.
- `Command` learned about `READ_PERIODICALLY`, but it has not been tested yet.
- `Command` learned about the `PLANT_` equivalents of the other commands.

### Bugfixes

- CLI: Implement support for `Click 8.1` caused by API changes related to custom completions (Issue #17, PR #18).

### Dependency changes

- `Click`: Version `7.0` is the new minimum, it supported custom completion functions for the first time
- `Click`: Version `8.1` is the new maximum, to guard against API changes during unconditionally updating the
dependencies.

## Release 0.0.3 - 2021-05-22

### Breaking changes
Expand Down
10 changes: 7 additions & 3 deletions docs/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ The library comes with a CLI tool called ``rctclient`` that offers some useful s
The tool is only installed if the `click <https://click.palletsprojects.com/>`_ module's present. If installing from
`pip`, the requirement can be pulled in by specifying ``rctclient[cli]``.

For certain parameters, the tool supports shell completion. Read more about this at the `click documentation
<https://click.palletsprojects.com/en/7.x/bashcomplete/#activation>`_. For Bash, the completion can be activated using
the following command: ``eval "$(_RCTCLIENT_COMPLETE=source_bash rctclient)"``
For certain parameters, the tool supports shell completion. Depending on your version of *Click*, there are different
ways to enable the completion:

* ``< 8.0.0``: ``eval "$(_RCTCLIENT_COMPLETE=source_bash rctclient)"`` (e.g. Debian 11, Ubuntu 20.04)
* ``>= 8.0.0``: ``eval "$(_RCTCLIENT_COMPLETE=bash_source rctclient)"`` (e.g. Arch, Fedora 35+, Gentoo)

Read more about this at the `click documentation <https://click.palletsprojects.com/en/7.x/bashcomplete/#activation>`_.

.. click:: rctclient.cli:cli
:prog: rctclient
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

extras_require={
'cli': [
'click',
'click>=7.0<8.2',
],
'tests': [
'mypy',
Expand Down
17 changes: 10 additions & 7 deletions src/rctclient/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,20 @@ def cli(ctx, debug: bool, frame_debug: bool) -> None:
log.info('rctclient CLI starting')


def autocomplete_registry_name(_ctx, _args: List, incomplete: str) -> List[str]:
def autocomplete_registry_name(*args, **kwargs) -> List[str]: # pylint: disable=unused-argument
'''
Provides autocompletion for the object IDs name parameter.
:param _ctx: Click context (ignored).
:param _args: Arguments (ignored).
:param incomplete: Incomplete (or empty) string from the user.
:return: A list of names that either start with `incomplete` or all if `incomplete` is empty.
'''
return R.prefix_complete_name(incomplete)
if 'incomplete' not in kwargs:
kwargs['incomplete'] = ''
return R.prefix_complete_name(kwargs['incomplete'])

if click.__version__ >= '8.1.0':
autocomp_registry = {'shell_complete': autocomplete_registry_name}
else:
autocomp_registry = {'autocompletion': autocomplete_registry_name}


def receive_frame(sock: socket.socket, timeout: int = 2) -> ReceiveFrame:
Expand Down Expand Up @@ -102,8 +106,7 @@ def receive_frame(sock: socket.socket, timeout: int = 2) -> ReceiveFrame:
@click.option('-h', '--host', required=True, type=click.STRING, help='Host address or IP of the device',
metavar='<host>')
@click.option('-i', '--id', type=click.STRING, help='Object ID to query, of the form "0xXXXX"', metavar='<ID>')
@click.option('-n', '--name', help='Object name to query', type=click.STRING, metavar='<name>',
autocompletion=autocomplete_registry_name)
@click.option('-n', '--name', help='Object name to query', type=click.STRING, metavar='<name>', **autocomp_registry)
@click.option('-v', '--verbose', is_flag=True, default=False, help='Enable verbose output')
def read_value(ctx, port: int, host: str, id: Optional[str], name: Optional[str], verbose: bool) -> None:
'''
Expand Down

0 comments on commit 423a484

Please sign in to comment.