Skip to content

Commit 049fdb5

Browse files
committed
Getting started on context dependent completion
Focusing on projects and servers so far, just to see if works.
1 parent 8ef523f commit 049fdb5

File tree

1 file changed

+64
-29
lines changed

1 file changed

+64
-29
lines changed

faculty_cli/cli.py

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import uuid
3131
from distutils.version import StrictVersion
3232
import click
33+
from click.shell_completion import CompletionItem
3334
import faculty
3435
import faculty.config
3536
import requests
@@ -402,6 +403,35 @@ def _format_datetime(timestamp):
402403
return timestamp.strftime("%Y-%m-%d %H:%M")
403404

404405

406+
def _complete_project_values(ctx, param, incomplete):
407+
"""Complete the values for project names."""
408+
return [
409+
CompletionItem(project.name, help=project.id)
410+
for project in _list_projects()
411+
if project.name.startswith(incomplete)
412+
]
413+
414+
415+
def _complete_server_values(ctx, param, incomplete):
416+
"""Complete the values for server name names.
417+
418+
This function relies on having a "project" variable also
419+
requested in the given context, and if there isn't one,
420+
no suggestions are returned.
421+
"""
422+
if "project" not in ctx.params:
423+
return []
424+
425+
project_id = _resolve_project(ctx.params["project"])
426+
return [
427+
CompletionItem(server.name, help=server.id)
428+
for server in _get_servers(
429+
project_id=project_id, status=ServerStatus.RUNNING
430+
)
431+
if server.name.startswith(incomplete)
432+
]
433+
434+
405435
class FacultyCLIGroup(click.Group):
406436
def __call__(self, *args, **kwargs):
407437
try:
@@ -501,7 +531,12 @@ def server():
501531

502532

503533
@server.command(name="list")
504-
@click.argument("project", required=False, metavar="PROJECT")
534+
@click.argument(
535+
"project",
536+
required=False,
537+
metavar="PROJECT",
538+
shell_complete=_complete_project_values,
539+
)
505540
@click.option(
506541
"-a",
507542
"--all",
@@ -574,7 +609,7 @@ def list_servers(project, all, verbose):
574609

575610

576611
@server.command(name="open")
577-
@click.argument("project")
612+
@click.argument("project", shell_complete=_complete_project_values)
578613
@click.option("--server", is_flag=False, help="Name or ID of server to use.")
579614
def open_(project, server):
580615
"""Open a Faculty server in your browser."""
@@ -599,7 +634,7 @@ def open_(project, server):
599634

600635

601636
@server.command()
602-
@click.argument("project")
637+
@click.argument("project", shell_complete=_complete_project_values)
603638
@click.option(
604639
"--cores",
605640
type=float,
@@ -698,8 +733,8 @@ def new(
698733

699734

700735
@server.command()
701-
@click.argument("project")
702-
@click.argument("server")
736+
@click.argument("project", shell_complete=_complete_project_values)
737+
@click.argument("server", shell_complete=_complete_server_values)
703738
def terminate(project, server):
704739
"""Terminate a Faculty server."""
705740
_, server_id = _resolve_server(project, server, ensure_running=False)
@@ -754,8 +789,8 @@ def instance_types(verbose):
754789

755790

756791
@server.command()
757-
@click.argument("project")
758-
@click.argument("server")
792+
@click.argument("project", shell_complete=_complete_project_values)
793+
@click.argument("server", shell_complete=_complete_server_values)
759794
def ssh_details(project, server):
760795
"""Echo the username, hostname and SSH port for a Faculty server.
761796
@@ -778,8 +813,8 @@ def ssh_details(project, server):
778813

779814

780815
@cli.command(context_settings={"ignore_unknown_options": True})
781-
@click.argument("project")
782-
@click.argument("server")
816+
@click.argument("project", shell_complete=_complete_project_values)
817+
@click.argument("server", shell_complete=_complete_server_values)
783818
@click.argument("ssh_opts", nargs=-1, type=click.UNPROCESSED)
784819
def shell(project, server, ssh_opts):
785820
"""Open a shell on a Faculty server.
@@ -816,7 +851,7 @@ def environment():
816851

817852

818853
@environment.command(name="list")
819-
@click.argument("project")
854+
@click.argument("project", shell_complete=_complete_project_values)
820855
@click.option(
821856
"-v",
822857
"--verbose",
@@ -845,8 +880,8 @@ def list_environments(project, verbose):
845880

846881

847882
@environment.command()
848-
@click.argument("project")
849-
@click.argument("server")
883+
@click.argument("project", shell_complete=_complete_project_values)
884+
@click.argument("server", shell_complete=_complete_server_values)
850885
@click.argument("environment")
851886
def apply(project, server, environment):
852887
"""Apply an environment to the server."""
@@ -886,7 +921,7 @@ def _get_hound_url(server):
886921

887922

888923
@environment.command()
889-
@click.argument("project")
924+
@click.argument("project", shell_complete=_complete_project_values)
890925
@click.argument("server")
891926
def status(project, server):
892927
"""Get the execution status for an environment."""
@@ -917,7 +952,7 @@ def status(project, server):
917952

918953

919954
@environment.command()
920-
@click.argument("project")
955+
@click.argument("project", shell_complete=_complete_project_values)
921956
@click.argument("server")
922957
@click.option(
923958
"--step",
@@ -966,7 +1001,7 @@ def job():
9661001

9671002

9681003
@job.command(name="list")
969-
@click.argument("project")
1004+
@click.argument("project", shell_complete=_complete_project_values)
9701005
@click.option(
9711006
"-v", "--verbose", is_flag=True, help="Print extra information about jobs."
9721007
)
@@ -994,7 +1029,7 @@ def list_jobs(project, verbose):
9941029

9951030

9961031
@job.command(name="list-runs")
997-
@click.argument("project")
1032+
@click.argument("project", shell_complete=_complete_project_values)
9981033
@click.argument("job")
9991034
@click.option(
10001035
"-v", "--verbose", is_flag=True, help="Print extra information about runs."
@@ -1056,7 +1091,7 @@ def list_runs():
10561091

10571092

10581093
@job.command(name="run")
1059-
@click.argument("project")
1094+
@click.argument("project", shell_complete=_complete_project_values)
10601095
@click.argument("job")
10611096
@click.argument(
10621097
"parameter_values",
@@ -1117,7 +1152,7 @@ def run_job(project, job, parameter_values, num_subruns):
11171152

11181153

11191154
@job.command("logs")
1120-
@click.argument("project")
1155+
@click.argument("project", shell_complete=_complete_project_values)
11211156
@click.argument("job")
11221157
@click.argument("run", type=faculty_cli.parse.parse_run_identifier)
11231158
def job_run_logs(project, job, run):
@@ -1174,7 +1209,7 @@ def file():
11741209

11751210

11761211
@file.command()
1177-
@click.argument("project")
1212+
@click.argument("project", shell_complete=_complete_project_values)
11781213
@click.argument("local")
11791214
@click.argument("remote")
11801215
@click.option("--server", is_flag=False, help="Name or ID of server to use.")
@@ -1207,7 +1242,7 @@ def put(project, local, remote, server):
12071242

12081243

12091244
@file.command()
1210-
@click.argument("project")
1245+
@click.argument("project", shell_complete=_complete_project_values)
12111246
@click.argument("remote")
12121247
@click.argument("local")
12131248
@click.option("--server", is_flag=False, help="Name or ID of server to use.")
@@ -1273,7 +1308,7 @@ def _rsync(project, local, remote, server, rsync_opts, up):
12731308
@file.command(
12741309
name="sync-up", context_settings={"ignore_unknown_options": True}
12751310
)
1276-
@click.argument("project")
1311+
@click.argument("project", shell_complete=_complete_project_values)
12771312
@click.argument("local")
12781313
@click.argument("remote")
12791314
@click.argument("rsync_opts", nargs=-1, type=click.UNPROCESSED)
@@ -1290,7 +1325,7 @@ def sync_up(project, local, remote, server, rsync_opts):
12901325
@file.command(
12911326
name="sync-down", context_settings={"ignore_unknown_options": True}
12921327
)
1293-
@click.argument("project")
1328+
@click.argument("project", shell_complete=_complete_project_values)
12941329
@click.argument("remote")
12951330
@click.argument("local")
12961331
@click.argument("rsync_opts", nargs=-1, type=click.UNPROCESSED)
@@ -1305,7 +1340,7 @@ def sync_down(project, remote, local, server, rsync_opts):
13051340

13061341

13071342
@file.command()
1308-
@click.argument("project")
1343+
@click.argument("project", shell_complete=_complete_project_values)
13091344
@click.argument("path")
13101345
def ls(project, path):
13111346
"""List files and directories on Faculty workspace."""
@@ -1342,7 +1377,7 @@ def datasets():
13421377

13431378

13441379
@datasets.command(name="get")
1345-
@click.argument("project")
1380+
@click.argument("project", shell_complete=_complete_project_values)
13461381
@click.argument("project_path")
13471382
@click.argument("local_path")
13481383
def dataset_get(project, project_path, local_path):
@@ -1357,7 +1392,7 @@ def dataset_get(project, project_path, local_path):
13571392

13581393

13591394
@datasets.command(name="put")
1360-
@click.argument("project")
1395+
@click.argument("project", shell_complete=_complete_project_values)
13611396
@click.argument("local_path")
13621397
@click.argument("project_path")
13631398
def dataset_put(project, local_path, project_path):
@@ -1370,7 +1405,7 @@ def dataset_put(project, local_path, project_path):
13701405

13711406

13721407
@datasets.command()
1373-
@click.argument("project")
1408+
@click.argument("project", shell_complete=_complete_project_values)
13741409
@click.argument("source_path")
13751410
@click.argument("destination_path")
13761411
def mv(project, source_path, destination_path):
@@ -1385,7 +1420,7 @@ def mv(project, source_path, destination_path):
13851420

13861421

13871422
@datasets.command()
1388-
@click.argument("project")
1423+
@click.argument("project", shell_complete=_complete_project_values)
13891424
@click.argument("source_path")
13901425
@click.argument("destination_path")
13911426
@click.option(
@@ -1411,7 +1446,7 @@ def cp(project, source_path, destination_path, recursive):
14111446

14121447

14131448
@datasets.command()
1414-
@click.argument("project")
1449+
@click.argument("project", shell_complete=_complete_project_values)
14151450
@click.argument("project_path")
14161451
@click.option(
14171452
"--recursive",
@@ -1433,7 +1468,7 @@ def rm(project, project_path, recursive):
14331468

14341469

14351470
@datasets.command(name="ls")
1436-
@click.argument("project")
1471+
@click.argument("project", shell_complete=_complete_project_values)
14371472
@click.option(
14381473
"--prefix",
14391474
default="/",

0 commit comments

Comments
 (0)