From a7cb476aa4b58a0d6034799c8b468b1458cb326d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Fri, 5 Jan 2024 16:50:21 +0100 Subject: [PATCH 01/12] Adds support for trogon. Most vara-* commands now support `tui` as a subcommand which opens a text-based UI for selecting command line parameters. --- requirements.txt | 1 + varats/setup.py | 1 + varats/varats/tools/driver_artefacts.py | 2 ++ varats/varats/tools/driver_build_setup.py | 4 +++- varats/varats/tools/driver_casestudy.py | 2 ++ varats/varats/tools/driver_config.py | 2 ++ varats/varats/tools/driver_container.py | 5 ++++- varats/varats/tools/driver_develop.py | 2 ++ varats/varats/tools/driver_gen_benchbuild_config.py | 2 ++ varats/varats/tools/driver_paper_config.py | 2 ++ varats/varats/tools/driver_run.py | 2 ++ 11 files changed, 23 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d1b506d98..879f6a914 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,6 +30,7 @@ rich>=12.6 scikit-learn>=1.2.2 seaborn>=0.13.0 tabulate>=0.9 +trogon>=0.5.0 types-PyYAML types-requests types-tabulate diff --git a/varats/setup.py b/varats/setup.py index 1986b251d..e035621f6 100644 --- a/varats/setup.py +++ b/varats/setup.py @@ -42,6 +42,7 @@ "scikit-learn>=1.2.2", "seaborn>=0.13.0", "tabulate>=0.9", + "trogon>=0.5.0", "varats-core>=13.0.5", "wllvm>=1.3.1", ], diff --git a/varats/varats/tools/driver_artefacts.py b/varats/varats/tools/driver_artefacts.py index 69632fbcd..c1b1d36b2 100644 --- a/varats/varats/tools/driver_artefacts.py +++ b/varats/varats/tools/driver_artefacts.py @@ -13,6 +13,7 @@ import click import yaml from rich.progress import Progress +from trogon import tui from varats.data.discover_reports import initialize_reports from varats.paper.paper_config import get_paper_config @@ -36,6 +37,7 @@ LOG = logging.getLogger(__name__) +@tui() @click.group( help="Manage artefacts.", context_settings={"help_option_names": ['-h', '--help']} diff --git a/varats/varats/tools/driver_build_setup.py b/varats/varats/tools/driver_build_setup.py index 78e2dbbe1..78f9633c2 100644 --- a/varats/varats/tools/driver_build_setup.py +++ b/varats/varats/tools/driver_build_setup.py @@ -6,6 +6,7 @@ import click from plumbum import colors +from trogon import tui from varats.containers.containers import ( ImageBase, @@ -89,6 +90,7 @@ def show_major_release_prompt( return +@tui() @click.group(context_settings={"help_option_names": ['-h', '--help']}) def main() -> None: """Build VaRA on cli.""" @@ -170,7 +172,7 @@ def update(research_tool: str) -> None: @click.option( "--build-type", type=EnumChoice(BuildType, case_sensitive=False), - default=BuildType.DEV, + default="DEV", help="Build type to use for the tool build configuration." ) @click.option( diff --git a/varats/varats/tools/driver_casestudy.py b/varats/varats/tools/driver_casestudy.py index 2f40a8409..0b245b920 100644 --- a/varats/varats/tools/driver_casestudy.py +++ b/varats/varats/tools/driver_casestudy.py @@ -8,6 +8,7 @@ import click from plumbum import FG, colors, local +from trogon import tui from varats.base.sampling_method import NormalSamplingMethod from varats.data.discover_reports import initialize_reports @@ -86,6 +87,7 @@ def create_plot_type_choice() -> TypedChoice[tp.Type[Plot]]: return TypedChoice(Plot.PLOTS) +@tui() @click.group() @configuration_lookup_error_handler def main() -> None: diff --git a/varats/varats/tools/driver_config.py b/varats/varats/tools/driver_config.py index 2023f8b31..55744f108 100644 --- a/varats/varats/tools/driver_config.py +++ b/varats/varats/tools/driver_config.py @@ -11,10 +11,12 @@ import click import yaml from benchbuild.utils.settings import ConfigDumper, Configuration +from trogon import tui from varats.utils.settings import vara_cfg, save_config +@tui() @click.group("vara-config") def main() -> None: """ diff --git a/varats/varats/tools/driver_container.py b/varats/varats/tools/driver_container.py index c55801bbf..2dcbf4527 100644 --- a/varats/varats/tools/driver_container.py +++ b/varats/varats/tools/driver_container.py @@ -8,6 +8,7 @@ import typing as tp import click +from trogon import tui from varats.containers.containers import ( create_base_images, @@ -26,6 +27,7 @@ LOG = logging.Logger(__name__) +@tui() @click.group( help="Manage base container images.", context_settings={"help_option_names": ['-h', '--help']} @@ -144,7 +146,8 @@ def delete( "-t", "--tool", type=click.Choice([*get_supported_research_tool_names(), "none"]), - default=lambda: vara_cfg()["container"]["research_tool"].value or "none", + required=True, + # default=lambda: vara_cfg()["container"]["research_tool"].value or "none", prompt="Select a research tool to activate.", help="The research tool to activate." ) diff --git a/varats/varats/tools/driver_develop.py b/varats/varats/tools/driver_develop.py index 4e6942f45..9cc8d72e5 100644 --- a/varats/varats/tools/driver_develop.py +++ b/varats/varats/tools/driver_develop.py @@ -3,6 +3,7 @@ import typing as tp import click +from trogon import tui from varats.tools.research_tools import development as dev from varats.tools.research_tools.research_tool import SubProject @@ -13,6 +14,7 @@ from varats.ts_utils.cli_util import initialize_cli_tool +@tui() @click.group(context_settings={"help_option_names": ['-h', '--help']}) @click.option( "-p", diff --git a/varats/varats/tools/driver_gen_benchbuild_config.py b/varats/varats/tools/driver_gen_benchbuild_config.py index 3edd5e726..1e9199061 100644 --- a/varats/varats/tools/driver_gen_benchbuild_config.py +++ b/varats/varats/tools/driver_gen_benchbuild_config.py @@ -6,6 +6,7 @@ import typing as tp import click +from trogon import tui from varats.tools.bb_config import ( create_new_bb_config, @@ -18,6 +19,7 @@ LOG = logging.getLogger(__name__) +@tui() @click.command() @click.option( "--bb-root", diff --git a/varats/varats/tools/driver_paper_config.py b/varats/varats/tools/driver_paper_config.py index d37dcb055..2a231fff9 100644 --- a/varats/varats/tools/driver_paper_config.py +++ b/varats/varats/tools/driver_paper_config.py @@ -9,6 +9,7 @@ from pathlib import Path import click +from trogon import tui from varats.paper.paper_config import get_paper_config from varats.ts_utils.cli_util import cli_list_choice, initialize_cli_tool @@ -23,6 +24,7 @@ LOG = logging.getLogger(__name__) +@tui() @click.group("vara-pc") def main() -> None: """ diff --git a/varats/varats/tools/driver_run.py b/varats/varats/tools/driver_run.py index 7c6ac4e0e..7749909be 100644 --- a/varats/varats/tools/driver_run.py +++ b/varats/varats/tools/driver_run.py @@ -19,6 +19,7 @@ from benchbuild.utils.settings import to_yaml from plumbum import local from plumbum.commands import ProcessExecutionError +from trogon import tui from varats.paper.case_study import CaseStudy from varats.paper.paper_config import get_paper_config @@ -81,6 +82,7 @@ def __validate_project_parameters( return value +@tui() @click.command(context_settings={"help_option_names": ['-h', '--help']}) @click.option('-v', '--verbose', count=True) @click.option("--slurm", is_flag=True, help="Run experiments on slurm.") From 151e562ec2322829f238e677de973a9ee754d0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 11:34:53 +0100 Subject: [PATCH 02/12] vara-art: make artefacts a click.Choice --- varats/varats/tools/driver_artefacts.py | 54 ++++++++++++++----------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/varats/varats/tools/driver_artefacts.py b/varats/varats/tools/driver_artefacts.py index c1b1d36b2..46bb3a940 100644 --- a/varats/varats/tools/driver_artefacts.py +++ b/varats/varats/tools/driver_artefacts.py @@ -27,17 +27,25 @@ from varats.projects.discover_projects import initialize_projects from varats.tables.discover_tables import initialize_tables from varats.ts_utils.cli_util import initialize_cli_tool +from varats.ts_utils.click_param_types import TypedChoice from varats.ts_utils.html_util import ( CSS_IMAGE_MATRIX, CSS_COMMON, html_page, CSS_TABLE, ) +from varats.utils.exceptions import ConfigurationLookupError LOG = logging.getLogger(__name__) +initialize_projects() +initialize_reports() +initialize_tables() +initialize_plots() +initialize_artefact_types() -@tui() + +@tui() # type: ignore @click.group( help="Manage artefacts.", context_settings={"help_option_names": ['-h', '--help']} @@ -49,15 +57,10 @@ def main() -> None: `vara-art` """ initialize_cli_tool() - initialize_projects() - initialize_reports() - initialize_tables() - initialize_plots() - initialize_artefact_types() # function name `list` would shadow built-in `list` -@main.command( +@main.command( # type: ignore name="list", help="List all artefacts of the current paper config." ) def list_() -> None: @@ -68,49 +71,52 @@ def list_() -> None: print(f"{artefact.name} [{artefact.ARTEFACT_TYPE}]") -@main.command(help="Show detailed information about artefacts.") -@click.argument("name") -def show(name: str) -> None: +def _create_artefact_choice() -> TypedChoice['Artefact']: + try: + paper_config = get_paper_config() + except ConfigurationLookupError: + empty_art_dict: tp.Dict[str, 'Artefact'] = {} + return TypedChoice(empty_art_dict) + value_dict = {art.name: art for art in load_artefacts(paper_config)} + return TypedChoice(value_dict) + + +@main.command(help="Show detailed information about artefacts.") # type: ignore +@click.argument("name", type=_create_artefact_choice()) +def show(name: Artefact) -> None: """ Show detailed information about artefacts. Args: - name: the name of the artefact + name: the artefact to display """ - paper_config = get_paper_config() - if (artefact := load_artefacts(paper_config).get_artefact(name)): - print(f"Artefact '{name}':") - print(textwrap.indent(yaml.dump(artefact.get_dict()), ' ')) - else: - print(f"There is no artefact with the name {name}.") + print(textwrap.indent(yaml.dump(name.get_dict()), ' ')) -@main.command( +@main.command( # type: ignore help="Generate artefacts. By default, all artefacts are generated." ) @click.option( "--only", + type=_create_artefact_choice(), multiple=True, help="Only generate artefacts with the given names." ) -def generate(only: tp.Optional[str]) -> None: +def generate(only: tp.List[Artefact]) -> None: """ Generate artefacts. By default, all artefacts are generated. Args: - only: generate only this artefact + only: generate only these artefacts """ if not Artefact.base_output_dir().exists(): Artefact.base_output_dir().mkdir(parents=True) artefacts: tp.Iterable[Artefact] if only: - artefacts = [ - art for art in load_artefacts(get_paper_config()) - if art.name in only - ] + artefacts = only else: artefacts = load_artefacts(get_paper_config()) From 7bbbed4bed1271b224bc6dfec954c73840cdc8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 11:35:18 +0100 Subject: [PATCH 03/12] mypy: Ignore missing imports for trogon --- mypy.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mypy.ini b/mypy.ini index ea82a4ec7..d244ea161 100644 --- a/mypy.ini +++ b/mypy.ini @@ -67,6 +67,9 @@ ignore_missing_imports = True ignore_missing_imports = True ignore_errors = True +[mypy-trogon.*] +ignore_missing_imports = True + [mypy-varats.gui.views.*] ignore_errors = True From 10f920fb0b639f24ec176ba6fad5a2d79ea2c8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 12:49:18 +0100 Subject: [PATCH 04/12] vara-cs: make project sleection a click.Choice --- varats/varats/tools/driver_casestudy.py | 44 ++++++++++++++----------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/varats/varats/tools/driver_casestudy.py b/varats/varats/tools/driver_casestudy.py index 99281e5fc..d1cc42b05 100644 --- a/varats/varats/tools/driver_casestudy.py +++ b/varats/varats/tools/driver_casestudy.py @@ -44,6 +44,7 @@ from varats.project.project_util import ( get_local_project_git_path, get_primary_project_source, + get_loaded_vara_projects, ) from varats.projects.discover_projects import initialize_projects from varats.provider.release.release_provider import ReleaseType @@ -88,17 +89,22 @@ def create_plot_type_choice() -> TypedChoice[tp.Type[Plot]]: return TypedChoice(Plot.PLOTS) -@tui() +def create_project_choice() -> click.Choice: + initialize_projects() + projects = [proj.NAME for proj in get_loaded_vara_projects()] + return click.Choice(projects) + + +@tui() # type: ignore @click.group() @configuration_lookup_error_handler def main() -> None: """Allow easier management of case studies.""" initialize_cli_tool() - initialize_projects() initialize_reports() -@main.command("status") +@main.command("status") # type: ignore @click.argument("experiment_type", type=create_experiment_type_choice()) @click.option( "--filter-regex", @@ -157,8 +163,8 @@ def __casestudy_status( ) -@main.group("gen") -@click.option("--project", "-p", required=True) +@main.group("gen") # type: ignore +@click.option("--project", "-p", type=create_project_choice(), required=True) @click.option( "--override", "-or", @@ -197,7 +203,7 @@ def __casestudy_gen( ignore_blocked: bool, merge_stage: tp.Optional[str], new_stage: bool, update: bool ) -> None: - """Generate or extend a CaseStudy Sub commands can be chained to for example + """Generate or extend a CaseStudy subcommands can be chained to for example sample revisions but also add the latest.""" ctx.ensure_object(dict) ctx.obj['project'] = project @@ -269,7 +275,7 @@ def set_merge_stage(stage: CSStage) -> None: ctx.obj['case_study'] = case_study -@__casestudy_gen.command("select_latest") +@__casestudy_gen.command("select_latest") # type: ignore @click.pass_context def __gen_latest(ctx: click.Context) -> None: """Add the latest revision of the project to the CS.""" @@ -287,7 +293,7 @@ def __gen_latest(ctx: click.Context) -> None: store_case_study(case_study, ctx.obj['path']) -@__casestudy_gen.command("select_specific") +@__casestudy_gen.command("select_specific") # type: ignore @click.argument("revisions", nargs=-1) @click.pass_context def __gen_specific(ctx: click.Context, revisions: tp.List[str]) -> None: @@ -303,7 +309,7 @@ def __gen_specific(ctx: click.Context, revisions: tp.List[str]) -> None: store_case_study(ctx.obj['case_study'], ctx.obj['path']) -@__casestudy_gen.command("select_sample") +@__casestudy_gen.command("select_sample") # type: ignore @click.argument( "distribution", type=click.Choice([ @@ -358,7 +364,7 @@ def __gen_sample( store_case_study(ctx.obj['case_study'], ctx.obj['path']) -@__casestudy_gen.command("select_revs-per-year") +@__casestudy_gen.command("select_revs-per-year") # type: ignore @click.argument("revs-per-year", type=int) @click.option( "--separate", is_flag=True, help="Separate years into different Stages" @@ -434,7 +440,7 @@ def set_plot(selected_plot: Plot) -> None: return click.command(cmd_name)(command_definition) -@__casestudy_gen.command("select_plot", cls=SmoothPlotCLI) +@__casestudy_gen.command("select_plot", cls=SmoothPlotCLI) # type: ignore @click.option( "--boundary-gradient", type=int, @@ -452,7 +458,7 @@ def __gen_smooth_plot(ctx: click.Context, boundary_gradient: int) -> None: ctx.obj['boundary_gradient'] = boundary_gradient -@__casestudy_gen.command("select_release") +@__casestudy_gen.command("select_release") # type: ignore @click.argument("release_type", type=EnumChoice(ReleaseType, False)) @click.pass_context def __gen_release(ctx: click.Context, release_type: ReleaseType) -> None: @@ -470,7 +476,7 @@ def __gen_release(ctx: click.Context, release_type: ReleaseType) -> None: store_case_study(ctx.obj['case_study'], ctx.obj['path']) -@__casestudy_gen.command("select_bug") +@__casestudy_gen.command("select_bug") # type: ignore @click.option( "--experiment-type", type=TypedChoice({ @@ -497,7 +503,7 @@ def __gen_bug_commits( store_case_study(ctx.obj['case_study'], ctx.obj['path']) -@main.command("package") +@main.command("package") # type: ignore @click.argument( "experiment_names", type=create_experiment_type_choice(), nargs=-1 ) @@ -542,7 +548,7 @@ def __casestudy_package( ) -@main.command("view") +@main.command("view") # type: ignore @click.option( "--experiment-type", type=create_experiment_type_choice(), @@ -700,7 +706,7 @@ def result_file_to_list_entry( return commit_hash -@main.group() +@main.group() # type: ignore @click.option( "--case-studies", "-cs", @@ -746,7 +752,7 @@ def __delete_report_file_paths(report_files: tp.List[ReportFilepath]) -> None: parent_dir.rmdir() -@cleanup.command("all") +@cleanup.command("all") # type: ignore @click.option( "--error", is_flag=True, help="remove only reports from failed experiments" ) @@ -771,7 +777,7 @@ def _remove_all_result_files(ctx: click.Context, error: bool) -> None: __delete_report_file_paths(revision_files) -@cleanup.command("old") +@cleanup.command("old") # type: ignore @click.pass_context def _remove_old_result_files(ctx: click.Context) -> None: """Remove result files of wich a newer version exists.""" @@ -795,7 +801,7 @@ def _remove_old_result_files(ctx: click.Context) -> None: __delete_report_file_paths(old_revision_files) -@cleanup.command("regex") +@cleanup.command("regex") # type: ignore @click.option( "--filter-regex", "-f", From 0be946b509abd53d0a521eaadb8ca2e4c3aa3968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 14:43:30 +0100 Subject: [PATCH 05/12] vara-pc: make paper configs a click.Choice and simplify paper config handling. Many of the checks are not necessary anymore because our config management takes care of managing folders much better. --- varats/varats/tools/driver_paper_config.py | 129 ++++++--------------- 1 file changed, 33 insertions(+), 96 deletions(-) diff --git a/varats/varats/tools/driver_paper_config.py b/varats/varats/tools/driver_paper_config.py index 2a231fff9..8ead8f34d 100644 --- a/varats/varats/tools/driver_paper_config.py +++ b/varats/varats/tools/driver_paper_config.py @@ -24,7 +24,7 @@ LOG = logging.getLogger(__name__) -@tui() +@tui() # type: ignore @click.group("vara-pc") def main() -> None: """ @@ -34,85 +34,56 @@ def main() -> None: """ initialize_cli_tool() - if vara_cfg()["paper_config"]["folder"].value is None: - # Setup default paper config path when none exists - vara_cfg()["paper_config"]["folder"] = str( - Path('paper_configs').absolute() - ) - save_config() - -def _get_paper_configs(pc_folder_path: Path) -> tp.List[str]: +def _get_paper_configs() -> tp.List[str]: paper_configs: tp.List[str] = [] - for folder in pc_folder_path.iterdir(): + for folder in Path(vara_cfg()["paper_config"]["folder"].value).iterdir(): paper_configs.append(folder.name) return sorted(paper_configs) -@main.command("create") -@click.argument("paper_config", type=click.Path()) +@main.command("create") # type: ignore +@click.argument("paper_config") def _pc_create(paper_config: str) -> None: - """paper_config: - Path to the new paper config. - Relative paths are interpreted relative to the current - `paper_config/folder`.""" - pc_path: Path = Path(paper_config) - if not pc_path.is_absolute(): - current_folder = vara_cfg()["paper_config"]["folder"].value - if current_folder is None: - pc_path = Path( - vara_cfg()["config_file"].value - ).parent / "paper_configs" / pc_path - else: - pc_path = Path(current_folder) / pc_path + """Create a new paper config.""" + pc_folder_path = Path(vara_cfg()["paper_config"]["folder"].value) + pc_path = pc_folder_path / paper_config if pc_path.exists(): LOG.error( - f"Cannot create paper config at: {pc_path} " - "(Path already exists)." + f"Cannot create paper config at: {pc_path} (Path already exists)." ) return - folder = pc_path.parent - current_config = pc_path.name - - LOG.info( - f"Creating new paper config {current_config} at location {folder}." - ) + LOG.info(f"Creating new paper config {paper_config} at location {pc_path}.") pc_path.mkdir(parents=True) - vara_cfg()["paper_config"]["folder"] = str(folder) - vara_cfg()["paper_config"]["current_config"] = str(current_config) + # automatically select new paper config + vara_cfg()["paper_config"]["current_config"] = paper_config save_config() -@main.command("select") -@click.option("--paper-config", type=click.Path()) -def _pc_set(paper_config: tp.Optional[Path]) -> None: +def create_pc_choice() -> click.Choice: + paper_configs = _get_paper_configs() + return click.Choice(paper_configs) + + +@main.command("select") # type: ignore +@click.option("--paper-config", type=create_pc_choice(), required=True) +def _pc_set(paper_config: tp.Optional[str]) -> None: if not paper_config: - pc_folder_path = Path( - get_value_or_default( - vara_cfg()["paper_config"], "folder", - str(get_varats_base_folder()) - ) - ) - if not (pc_folder_path.exists() and pc_folder_path.is_dir()): - LOG.error( - f"Paper config folder not set: {pc_folder_path} " - "(Path does not exist or is no directory)." - ) - return + pc_folder_path = Path(vara_cfg()["paper_config"]["folder"].value) - paper_configs = _get_paper_configs(pc_folder_path) + paper_configs = _get_paper_configs() if not paper_configs: - LOG.error(f"Could not find paper configs in: {pc_folder_path}") + LOG.error(f"Could not find any paper configs.") return - raw_pc_path = None + selected_paper_config = None def set_pc_path(choice: str) -> None: - nonlocal raw_pc_path - raw_pc_path = choice + nonlocal selected_paper_config + selected_paper_config = choice current_config = None try: @@ -129,51 +100,17 @@ def set_pc_path(choice: str) -> None: ) except EOFError: return - if raw_pc_path is None: + if selected_paper_config is None: raise AssertionError("Choice should always return a value") - paper_config = Path(raw_pc_path) - - paper_config = Path(paper_config) - if not paper_config.is_absolute(): - paper_config = Path( - vara_cfg()["paper_config"]["folder"].value - ) / paper_config + paper_config = selected_paper_config - if not (paper_config.exists() and paper_config.is_dir()): - LOG.error( - f"Not a paper config: {paper_config} " - "(Path does not exist or is no directory)." - ) - return - - folder = paper_config.parent - current_config = paper_config.name - - LOG.info( - f"Current paper config is now {current_config} at location {folder}." - ) - vara_cfg()["paper_config"]["folder"] = str(folder) - vara_cfg()["paper_config"]["current_config"] = str(current_config) + LOG.info(f"Current paper config is now {paper_config}.") + vara_cfg()["paper_config"]["current_config"] = paper_config save_config() -@main.command("list") -@click.option( - "--paper-config-path", - help="Path to the paper config folder.", - type=click.Path() -) -def _pc_list(paper_config_path: tp.Optional[Path]) -> None: - if not paper_config_path: - paper_config_path = Path(vara_cfg()["paper_config"]["folder"].value) - - if not (paper_config_path.exists() and paper_config_path.is_dir()): - LOG.error( - f"Paper config folder not found: {paper_config_path} " - "(Path does not exist or is no directory)." - ) - return - +@main.command("list") # type: ignore +def _pc_list() -> None: print("Found the following paper_configs:") current_config = None try: @@ -182,7 +119,7 @@ def _pc_list(paper_config_path: tp.Optional[Path]) -> None: # No paper config specified in the varats config file pass - for paper_config in _get_paper_configs(paper_config_path): + for paper_config in _get_paper_configs(): if current_config and paper_config == current_config: print(f"{paper_config} *") else: From ae9e77df3b546d1b0b9877d94d6f5a796c6303b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 14:48:09 +0100 Subject: [PATCH 06/12] suppress mypy errors --- varats/varats/tools/driver_build_setup.py | 10 +++++----- varats/varats/tools/driver_config.py | 6 +++--- varats/varats/tools/driver_container.py | 14 ++++++++++---- varats/varats/tools/driver_develop.py | 14 +++++++------- .../varats/tools/driver_gen_benchbuild_config.py | 2 +- varats/varats/tools/driver_run.py | 2 +- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/varats/varats/tools/driver_build_setup.py b/varats/varats/tools/driver_build_setup.py index 78f9633c2..06684dc60 100644 --- a/varats/varats/tools/driver_build_setup.py +++ b/varats/varats/tools/driver_build_setup.py @@ -90,14 +90,14 @@ def show_major_release_prompt( return -@tui() +@tui() # type: ignore @click.group(context_settings={"help_option_names": ['-h', '--help']}) def main() -> None: """Build VaRA on cli.""" initialize_cli_tool() -@main.command() +@main.command() # type: ignore def config() -> None: """Only create a VaRA-TS config file.""" save_config() @@ -125,7 +125,7 @@ def config() -> None: required=False, help="Tool install folder." ) -@main.command() +@main.command() # type: ignore def init( version: tp.Optional[int], install_prefix: tp.Optional[Path], source_location: tp.Optional[Path], research_tool: str @@ -138,7 +138,7 @@ def init( @click.argument( "research_tool", type=click.Choice(get_supported_research_tool_names()) ) -@main.command() +@main.command() # type: ignore def update(research_tool: str) -> None: """Update a research tool and all its components.""" tool = get_research_tool(research_tool) @@ -180,7 +180,7 @@ def update(research_tool: str) -> None: default=True, help="Show a prompt to check for major version updates." ) -@main.command() +@main.command() # type: ignore def build( research_tool: str, build_type: BuildType, build_folder_suffix: tp.Optional[str], source_location: tp.Optional[Path], diff --git a/varats/varats/tools/driver_config.py b/varats/varats/tools/driver_config.py index 55744f108..b43a4e828 100644 --- a/varats/varats/tools/driver_config.py +++ b/varats/varats/tools/driver_config.py @@ -16,7 +16,7 @@ from varats.utils.settings import vara_cfg, save_config -@tui() +@tui() # type: ignore @click.group("vara-config") def main() -> None: """ @@ -54,7 +54,7 @@ def __dump_config_to_string(config: Configuration) -> str: ) -@main.command("set") +@main.command("set") # type: ignore @click.argument("config_values", nargs=-1, metavar="KEY=VALUE") def __config_set(config_values: tp.List[str]) -> None: """ @@ -80,7 +80,7 @@ def __config_set(config_values: tp.List[str]) -> None: save_config() -@main.command("show") +@main.command("show") # type: ignore @click.argument("config_options", nargs=-1) def __config_show(config_options: tp.Optional[tp.List[str]]) -> None: """ diff --git a/varats/varats/tools/driver_container.py b/varats/varats/tools/driver_container.py index 2dcbf4527..296077125 100644 --- a/varats/varats/tools/driver_container.py +++ b/varats/varats/tools/driver_container.py @@ -27,7 +27,7 @@ LOG = logging.Logger(__name__) -@tui() +@tui() # type: ignore @click.group( help="Manage base container images.", context_settings={"help_option_names": ['-h', '--help']} @@ -38,7 +38,9 @@ def main() -> None: bb_cfg() -@main.command(help="Build base containers for the current research tool.") +@main.command( + help="Build base containers for the current research tool." +) # type: ignore @click.option( "--debug", is_flag=True, help="Debug failed image builds interactively." ) @@ -103,7 +105,9 @@ def build( export_base_images() -@main.command(help="Delete base containers for the current research tool.") +@main.command( + help="Delete base containers for the current research tool." +) # type: ignore @click.option( "--build-type", type=EnumChoice(BuildType, case_sensitive=False), @@ -141,7 +145,9 @@ def delete( delete_base_images() -@main.command(help="Select the research tool to be used in base containers.") +@main.command( + help="Select the research tool to be used in base containers." +) # type: ignore @click.option( "-t", "--tool", diff --git a/varats/varats/tools/driver_develop.py b/varats/varats/tools/driver_develop.py index 9cc8d72e5..cc56169ff 100644 --- a/varats/varats/tools/driver_develop.py +++ b/varats/varats/tools/driver_develop.py @@ -14,7 +14,7 @@ from varats.ts_utils.cli_util import initialize_cli_tool -@tui() +@tui() # type: ignore @click.group(context_settings={"help_option_names": ['-h', '--help']}) @click.option( "-p", @@ -57,7 +57,7 @@ def __project_selector(sub_project: SubProject) -> None: context.obj["project_list"] = project_list -@main.command(help="Create a new branch.") +@main.command(help="Create a new branch.") # type: ignore @click.argument("branch_name", type=str) @click.pass_context def new_branch(context: click.Context, branch_name: str) -> None: @@ -65,7 +65,7 @@ def new_branch(context: click.Context, branch_name: str) -> None: dev.create_new_branch_for_projects(branch_name, context.obj["project_list"]) -@main.command(help="Checkout a branch.") +@main.command(help="Checkout a branch.") # type: ignore @click.argument("branch_name", type=str) @click.pass_context def checkout(context: click.Context, branch_name: str) -> None: @@ -75,28 +75,28 @@ def checkout(context: click.Context, branch_name: str) -> None: ) -@main.command(help="Git pull the research tool's repository.") +@main.command(help="Git pull the research tool's repository.") # type: ignore @click.pass_context def pull(context: click.Context) -> None: """Git pull the research tool's repository.""" dev.pull_projects(context.obj["project_list"]) -@main.command(help="Git push the research tool's repository.") +@main.command(help="Git push the research tool's repository.") # type: ignore @click.pass_context def push(context: click.Context) -> None: """Git push the research tool's repository.""" dev.push_projects(context.obj["project_list"]) -@main.command(help="Show git status for a research tool.") +@main.command(help="Show git status for a research tool.") # type: ignore @click.pass_context def status(context: click.Context) -> None: """Show git status for a research tool.""" dev.show_status_for_projects(context.obj["project_list"]) -@main.command(help="List all remote feature branches.") +@main.command(help="List all remote feature branches.") # type: ignore @click.pass_context def f_branches(context: click.Context) -> None: """List all remote feature branches.""" diff --git a/varats/varats/tools/driver_gen_benchbuild_config.py b/varats/varats/tools/driver_gen_benchbuild_config.py index 1e9199061..c4b2c3963 100644 --- a/varats/varats/tools/driver_gen_benchbuild_config.py +++ b/varats/varats/tools/driver_gen_benchbuild_config.py @@ -19,7 +19,7 @@ LOG = logging.getLogger(__name__) -@tui() +@tui() # type: ignore @click.command() @click.option( "--bb-root", diff --git a/varats/varats/tools/driver_run.py b/varats/varats/tools/driver_run.py index 7749909be..6b582e115 100644 --- a/varats/varats/tools/driver_run.py +++ b/varats/varats/tools/driver_run.py @@ -82,7 +82,7 @@ def __validate_project_parameters( return value -@tui() +@tui() # type: ignore @click.command(context_settings={"help_option_names": ['-h', '--help']}) @click.option('-v', '--verbose', count=True) @click.option("--slurm", is_flag=True, help="Run experiments on slurm.") From 282b31ce8a92c1a07f9c197f75adde63430fda4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 14:51:25 +0100 Subject: [PATCH 07/12] suppress mypy errors --- varats/varats/tools/driver_casestudy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/varats/varats/tools/driver_casestudy.py b/varats/varats/tools/driver_casestudy.py index d1cc42b05..5699db27e 100644 --- a/varats/varats/tools/driver_casestudy.py +++ b/varats/varats/tools/driver_casestudy.py @@ -401,7 +401,7 @@ def get_command(self, ctx: click.Context, generator_cls = PlotGenerator.GENERATORS[cmd_name] - @click.pass_context + @click.pass_context # type: ignore def command_template(context: click.Context, **kwargs: tp.Any) -> None: # extract common arguments and plot config from context plot_config: PlotConfig = PlotConfig(False) From b2f457a3142cbefd6a6e8814d022c1524c3cdb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 16:16:54 +0100 Subject: [PATCH 08/12] Revert trogon support for vara-run --- varats/varats/tools/driver_run.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/varats/varats/tools/driver_run.py b/varats/varats/tools/driver_run.py index 6b582e115..7c6ac4e0e 100644 --- a/varats/varats/tools/driver_run.py +++ b/varats/varats/tools/driver_run.py @@ -19,7 +19,6 @@ from benchbuild.utils.settings import to_yaml from plumbum import local from plumbum.commands import ProcessExecutionError -from trogon import tui from varats.paper.case_study import CaseStudy from varats.paper.paper_config import get_paper_config @@ -82,7 +81,6 @@ def __validate_project_parameters( return value -@tui() # type: ignore @click.command(context_settings={"help_option_names": ['-h', '--help']}) @click.option('-v', '--verbose', count=True) @click.option("--slurm", is_flag=True, help="Run experiments on slurm.") From b7aaf86b04540473af0a37a02626ca9492123531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 16:17:13 +0100 Subject: [PATCH 09/12] Fix vara-gen-bbconfig tui support --- varats/varats/tools/driver_gen_benchbuild_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/varats/varats/tools/driver_gen_benchbuild_config.py b/varats/varats/tools/driver_gen_benchbuild_config.py index c4b2c3963..9fd82bc58 100644 --- a/varats/varats/tools/driver_gen_benchbuild_config.py +++ b/varats/varats/tools/driver_gen_benchbuild_config.py @@ -20,7 +20,7 @@ @tui() # type: ignore -@click.command() +@click.group(invoke_without_command=True) @click.option( "--bb-root", type=click.Path(), From cb8f8f1f2bb7ce35beca37962ac9d7166a95e14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 16:20:04 +0100 Subject: [PATCH 10/12] vara-pc select: paper config is optional --- tests/tools/test_driver_paper_config.py | 2 +- varats/varats/tools/driver_paper_config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tools/test_driver_paper_config.py b/tests/tools/test_driver_paper_config.py index c61c76de8..4281a48ee 100644 --- a/tests/tools/test_driver_paper_config.py +++ b/tests/tools/test_driver_paper_config.py @@ -54,7 +54,7 @@ def test_vara_pc_select(self): vara_cfg()["paper_config"]["current_config"] = "foo" load_paper_config() result = runner.invoke(driver_paper_config.main, ["select"], input="1") - assert not result.exception + self.assertFalse(result.exception) self.assertEqual( "0. bar\n1. baz\n2. foo *\n" "Choose a number to select a paper config (default=0): ", diff --git a/varats/varats/tools/driver_paper_config.py b/varats/varats/tools/driver_paper_config.py index 8ead8f34d..9aa7e4099 100644 --- a/varats/varats/tools/driver_paper_config.py +++ b/varats/varats/tools/driver_paper_config.py @@ -69,7 +69,7 @@ def create_pc_choice() -> click.Choice: @main.command("select") # type: ignore -@click.option("--paper-config", type=create_pc_choice(), required=True) +@click.option("--paper-config", type=create_pc_choice()) def _pc_set(paper_config: tp.Optional[str]) -> None: if not paper_config: pc_folder_path = Path(vara_cfg()["paper_config"]["folder"].value) From 6fe789493db94fdd455ac7b183b4e1d849dba0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Sat, 6 Jan 2024 16:24:57 +0100 Subject: [PATCH 11/12] Fix vara-art show --- varats/varats/tools/driver_artefacts.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/varats/varats/tools/driver_artefacts.py b/varats/varats/tools/driver_artefacts.py index 46bb3a940..c914ffb49 100644 --- a/varats/varats/tools/driver_artefacts.py +++ b/varats/varats/tools/driver_artefacts.py @@ -82,15 +82,16 @@ def _create_artefact_choice() -> TypedChoice['Artefact']: @main.command(help="Show detailed information about artefacts.") # type: ignore -@click.argument("name", type=_create_artefact_choice()) -def show(name: Artefact) -> None: +@click.argument("artefact", type=_create_artefact_choice()) +def show(artefact: Artefact) -> None: """ Show detailed information about artefacts. Args: - name: the artefact to display + artefact: the artefact to display """ - print(textwrap.indent(yaml.dump(name.get_dict()), ' ')) + print(f"Artefact '{artefact.name}':") + print(textwrap.indent(yaml.dump(artefact.get_dict()), ' ')) @main.command( # type: ignore From 9ed24246399055e521bfe7a358b1ac3f7f6a6305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6hm?= Date: Wed, 10 Jan 2024 08:46:50 +0100 Subject: [PATCH 12/12] Fix artefact driver test. The reason for the failing test was that the CLI parameters are generated at parse-time. Since the test modified the available choices of such an option, we need to reload the driver module for that change to take effect at the CLI level. --- tests/tools/test_driver_artefacts.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/tools/test_driver_artefacts.py b/tests/tools/test_driver_artefacts.py index 354fc0a64..39409b535 100644 --- a/tests/tools/test_driver_artefacts.py +++ b/tests/tools/test_driver_artefacts.py @@ -1,16 +1,16 @@ """Test artefacts config tool.""" -import traceback +import importlib import unittest from click.testing import CliRunner +import varats.tools.driver_artefacts as driver_artefacts from tests.helper_utils import run_in_test_environment, UnitTestFixtures from varats.data.discover_reports import initialize_reports from varats.paper.paper_config import get_paper_config, load_paper_config from varats.paper_mgmt.artefacts import Artefact, load_artefacts from varats.plots.discover_plots import initialize_plots from varats.tables.discover_tables import initialize_tables -from varats.tools import driver_artefacts from varats.utils.settings import vara_cfg @@ -32,6 +32,7 @@ def test_artefacts_generate(self) -> None: # setup config vara_cfg()['paper_config']['current_config'] = "test_artefacts_driver" load_paper_config() + importlib.reload(driver_artefacts) artefacts = load_artefacts(get_paper_config()).artefacts base_output_dir = Artefact.base_output_dir() @@ -59,8 +60,9 @@ def test_artefacts_list(self) -> None: # setup config vara_cfg()['paper_config']['current_config'] = "test_artefacts_driver" load_paper_config() + importlib.reload(driver_artefacts) - # vara-art generate + # vara-art list runner = CliRunner() result = runner.invoke(driver_artefacts.main, ["list"]) self.assertEqual(0, result.exit_code, result.exception) @@ -76,6 +78,16 @@ def test_artefacts_show(self) -> None: # setup config vara_cfg()['paper_config']['current_config'] = "test_artefacts_driver" load_paper_config() + importlib.reload(driver_artefacts) + + # vara-art list + runner = CliRunner() + result = runner.invoke(driver_artefacts.main, ["list"]) + self.assertEqual(0, result.exit_code, result.exception) + self.assertEqual( + "Paper Config Overview [plot]\nCorrelation Table [table]\n" + "CS Overview (xz) [plot]\nRepo Churn (all) [plot]\n", result.stdout + ) expected = r"""Artefact 'Paper Config Overview': artefact_type: plot @@ -91,7 +103,7 @@ def test_artefacts_show(self) -> None: """ - # vara-art generate + # vara-art show runner = CliRunner() result = runner.invoke( driver_artefacts.main, ["show", "Paper Config Overview"]