Skip to content

Commit d6c1fe2

Browse files
authored
feat(core): add shell_complete implementation for workflows and datasets (#2512)
* add shell_complete implementation for workflows * add how-to guide for enabling renku cli auto-completion * add dataset autocomplete functionality * add sphinx-tabs for better documentation shell integration * remove click_completion
1 parent de098a5 commit d6c1fe2

File tree

16 files changed

+150
-84
lines changed

16 files changed

+150
-84
lines changed

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"sphinx.ext.intersphinx",
4848
"sphinx.ext.viewcode",
4949
"sphinxcontrib.spelling",
50+
"sphinx_tabs.tabs",
5051
]
5152

5253
# Add any paths that contain templates here, relative to this directory.

docs/how-to-guides/hpc.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ By default all workflows are executed by the ``cwltool`` provider, that
1212
exports the workflow to CWL and then uses `cwltool <https://github.com/common-workflow-language/cwltool>`_
1313
to execute the given CWL.
1414

15-
The workflow backend can be changed by using the ``-p/--provider <PROVIDER>``
15+
The workflow backend can be changed by using the ``-p/--provider <PROVIDER>``
1616
command line option. A backend's default configuration can be overridden by
1717
providing the ``-c/--config <config.yaml>`` command line parameter.
1818
The following ``renku`` commands support the above mentioned workflow provider
@@ -27,7 +27,7 @@ simply would run the following command:
2727

2828
.. code-block:: console
2929
30-
$ renku execute -p toil my_plan
30+
$ renku workflow execute -p toil my_plan
3131
3232
Using ``toil`` as a workflow provider has the advantage that it supports running
3333
the workflows on various `high-performance computing <https://toil.readthedocs.io/en/latest/running/hpcEnvironments.html>`_
@@ -57,7 +57,7 @@ Taking the example above, the following command line will execute ``my_plan`` on
5757

5858
.. code-block:: console
5959
60-
$ TOIL_SLURM_ARGS="-A my_account --export=ALL" renku execute -p toil -c provider.yaml my_plan
60+
$ TOIL_SLURM_ARGS="-A my_account --export=ALL" renku workflow execute -p toil -c provider.yaml my_plan
6161
6262
where
6363

docs/how-to-guides/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ aimed at active users of Renku CLI and target specific use-cases or common issue
1313

1414
hpc
1515
provider
16+
shell-integration
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
.. _shell-integration:
2+
3+
Shell integration of Renku CLI
4+
==============================
5+
6+
Renku CLI supports shell auto-completion for Renku commands and their arguments like datasets and workflows.
7+
8+
To activate tab completion for your supported shell run the following command after installing Renku CLI:
9+
10+
.. tabs::
11+
12+
.. tab:: bash
13+
14+
.. code-block:: console
15+
16+
$ eval "$(_RENKU_COMPLETE=bash_source renku)"
17+
18+
.. tab:: fish
19+
20+
.. code-block:: console
21+
22+
$ eval (env _RENKU_COMPLETE=fish_source renku)
23+
24+
.. tab:: zsh
25+
26+
.. code-block:: console
27+
28+
$ eval "$(_RENKU_COMPLETE=zsh_source renku)"
29+
30+
After this not only sub-commands of ``renku`` will be auto-completed using tab, but for example
31+
in case of ``renku workflow execute`` the available ``Plans`` are going to be listed.
32+
33+
.. code-block:: console
34+
35+
$ renku workflow execute run<TAB>
36+
run1 run10 run11 run12 run13 run14 run2 run3 run4 run7 run8
37+
38+
.. note::
39+
40+
Tab completion of available ``Plans`` only works if the user is executing the command
41+
within a Renku project.
42+
43+
44+
For more information on how to set up shell auto-completion, see documentation for the Click library,
45+
which used under the hood by Renku CLI:
46+
`shell completion <https://click.palletsprojects.com/en/8.0.x/shell-completion/>`_

docs/spelling_wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,5 @@ worktrees
249249
yaml
250250
yml
251251
Zenodo
252+
zsh
252253
連句

poetry.lock

Lines changed: 24 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ calamus = "<0.4,>=0.3.13"
6464
check-manifest = { version = "<0.48,>=0.37", optional = true }
6565
circus = { version = "==0.17.1", optional = true }
6666
click = "<8.0.2,>=7.0"
67-
click-completion = "<=0.5.3,>=0.5.0"
6867
click-option-group = "<0.6.0,>=0.5.2"
6968
click-plugins = "==1.1.1"
7069
coverage = { version = "<6.2,>=4.5.3", optional = true }
@@ -135,6 +134,7 @@ rq-scheduler = { version = "==0.11.0", optional = true }
135134
sentry-sdk = { version = "<1.4.4,>=0.7.4", extras = ["flask"], optional = true }
136135
sphinxcontrib-spelling = { version = "7.*", optional = true }
137136
sphinx-rtd-theme = { version = "<1.1,>=0.5.0", optional = true }
137+
sphinx-tabs = { version = "==3.2.0", optional = true }
138138
tabulate = "<0.8.10,>=0.7.7"
139139
toil = { version = "==5.5.0", optional = true }
140140
tqdm = "<4.62.4,>=4.48.1"
@@ -189,7 +189,7 @@ tests = [
189189
"responses",
190190
]
191191
toil = ["toil"]
192-
docs = ["renku-sphinx-theme", "sphinx-rtd-theme", "sphinxcontrib-spelling"]
192+
docs = ["renku-sphinx-theme", "sphinx-rtd-theme", "sphinxcontrib-spelling", "sphinx-tabs"]
193193
all = [
194194
"apispec",
195195
"apispec-webframeworks",
@@ -230,6 +230,7 @@ all = [
230230
"sentry-sdk",
231231
"sphinxcontrib-spelling",
232232
"sphinx-rtd-theme",
233+
"sphinx-tabs",
233234
"toil",
234235
"walrus",
235236
]

renku/cli/__init__.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
Options:
3535
--version Print version number.
3636
--global-config-path Print global application's config path.
37-
--install-completion Install completion for the current shell.
3837
--path <path> Location of a Renku repository.
3938
[default: (dynamic)]
4039
--external-storage / -S, --no-external-storage
@@ -66,7 +65,6 @@
6665
from pathlib import Path
6766

6867
import click
69-
import click_completion
7068
import yaml
7169
from click_plugins import with_plugins
7270

@@ -94,7 +92,7 @@
9492
from renku.cli.update import update
9593
from renku.cli.workflow import workflow
9694
from renku.core.commands.echo import WARNING
97-
from renku.core.commands.options import install_completion, option_external_storage_requested
95+
from renku.core.commands.options import option_external_storage_requested
9896
from renku.core.commands.version import check_version, print_version
9997
from renku.core.errors import UsageError
10098
from renku.core.utils.git import default_path
@@ -116,9 +114,6 @@ def get_entry_points(name: str):
116114
return all_entry_points.get(name, [])
117115

118116

119-
#: Monkeypatch Click application.
120-
click_completion.init()
121-
122117
WARNING_UNPROTECTED_COMMANDS = ["clone", "init", "help", "login", "logout", "service", "credentials"]
123118

124119

@@ -160,14 +155,6 @@ def is_allowed_command(ctx):
160155
is_eager=True,
161156
help=print_global_config_path.__doc__,
162157
)
163-
@click.option(
164-
"--install-completion",
165-
is_flag=True,
166-
callback=install_completion,
167-
expose_value=False,
168-
is_eager=True,
169-
help=install_completion.__doc__,
170-
)
171158
@click.option(
172159
"--path", show_default=True, metavar="<path>", default=default_path, help="Location of a Renku repository."
173160
)

renku/cli/dataset.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,16 @@
431431
from renku.core.commands.format.datasets import DATASETS_COLUMNS, DATASETS_FORMATS
432432

433433

434+
def _complete_datasets(ctx, param, incomplete):
435+
from renku.core.commands.dataset import search_datasets
436+
437+
try:
438+
result = search_datasets().build().execute(name=incomplete)
439+
return result.output
440+
except Exception:
441+
return []
442+
443+
434444
@click.group()
435445
def dataset():
436446
"""Dataset commands."""
@@ -508,7 +518,7 @@ def create(name, title, description, creators, metadata, keyword):
508518

509519

510520
@dataset.command()
511-
@click.argument("name")
521+
@click.argument("name", shell_complete=_complete_datasets)
512522
@click.option("-t", "--title", default=None, type=click.STRING, help="Title of the dataset.")
513523
@click.option("-d", "--description", default=None, type=click.STRING, help="Dataset's description.")
514524
@click.option(
@@ -570,7 +580,7 @@ def edit(name, title, description, creators, metadata, keyword):
570580

571581

572582
@dataset.command("show")
573-
@click.argument("name")
583+
@click.argument("name", shell_complete=_complete_datasets)
574584
def show(name):
575585
"""Show metadata of a dataset."""
576586
from renku.core.commands.dataset import show_dataset
@@ -607,8 +617,8 @@ def show(name):
607617

608618

609619
@dataset.command()
610-
@click.argument("name")
611-
@click.argument("urls", nargs=-1)
620+
@click.argument("name", shell_complete=_complete_datasets)
621+
@click.argument("urls", type=click.Path(), nargs=-1)
612622
@click.option("-e", "--external", is_flag=True, help="Creates a link to external data.")
613623
@click.option("--force", is_flag=True, help="Allow adding otherwise ignored files.")
614624
@click.option("-o", "--overwrite", is_flag=True, help="Overwrite existing files.")
@@ -640,7 +650,7 @@ def add(name, urls, external, force, overwrite, create, sources, destination, re
640650

641651

642652
@dataset.command("ls-files")
643-
@click.argument("names", nargs=-1)
653+
@click.argument("names", nargs=-1, shell_complete=_complete_datasets)
644654
@click.option(
645655
"--creators",
646656
help="Filter files which where authored by specific creators. Multiple creators are specified by comma.",
@@ -671,7 +681,7 @@ def ls_files(names, creators, include, exclude, format, columns):
671681

672682

673683
@dataset.command()
674-
@click.argument("name")
684+
@click.argument("name", shell_complete=_complete_datasets)
675685
@click.option("-I", "--include", multiple=True, help="Include files matching given pattern.")
676686
@click.option("-X", "--exclude", multiple=True, help="Exclude files matching given pattern.")
677687
@click.option("-y", "--yes", is_flag=True, help="Confirm unlinking of all files.")
@@ -695,7 +705,7 @@ def remove(name):
695705

696706

697707
@dataset.command("tag")
698-
@click.argument("name")
708+
@click.argument("name", shell_complete=_complete_datasets)
699709
@click.argument("tag")
700710
@click.option("-d", "--description", default="", help="A description for this tag")
701711
@click.option("--force", is_flag=True, help="Allow overwriting existing tags.")
@@ -708,7 +718,7 @@ def tag(name, tag, description, force):
708718

709719

710720
@dataset.command("rm-tags")
711-
@click.argument("name")
721+
@click.argument("name", shell_complete=_complete_datasets)
712722
@click.argument("tags", nargs=-1)
713723
def remove_tags(name, tags):
714724
"""Remove tags from a dataset."""
@@ -719,7 +729,7 @@ def remove_tags(name, tags):
719729

720730

721731
@dataset.command("ls-tags")
722-
@click.argument("name")
732+
@click.argument("name", shell_complete=_complete_datasets)
723733
@click.option("--format", type=click.Choice(DATASET_TAGS_FORMATS), default="tabular", help="Choose an output format.")
724734
def ls_tags(name, format):
725735
"""List all tags of a dataset."""
@@ -776,7 +786,7 @@ def wrapper(f):
776786

777787

778788
@dataset.command("export")
779-
@click.argument("name")
789+
@click.argument("name", shell_complete=_complete_datasets)
780790
@export_provider_argument()
781791
@click.option("-p", "--publish", is_flag=True, help="Automatically publish exported dataset.")
782792
@click.option("-t", "--tag", help="Dataset tag to export")
@@ -817,7 +827,7 @@ def import_(uri, name, extract, yes):
817827

818828

819829
@dataset.command("update")
820-
@click.argument("names", nargs=-1)
830+
@click.argument("names", nargs=-1, shell_complete=_complete_datasets)
821831
@click.option(
822832
"--creators",
823833
help="Filter files which where authored by specific creators. Multiple creators are specified by comma.",

0 commit comments

Comments
 (0)