From 64adaf5002df6e316db9da9b54ee6cea9633a4fd Mon Sep 17 00:00:00 2001 From: Qingmin Duanmu Date: Tue, 3 Dec 2024 21:56:42 +0800 Subject: [PATCH 1/5] chore: update pyproject.toml entrypoints to cli root command --- pyproject.toml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bd9dd5fc..ff684c97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,12 +19,7 @@ repository = 'https://github.com/RedHatProductSecurity/trestle-bot' [tool.poetry.scripts] -trestlebot-init = "trestlebot.entrypoints.init:main" -trestlebot-autosync = "trestlebot.entrypoints.autosync:main" -trestlebot-rules-transform = "trestlebot.entrypoints.rule_transform:main" -trestlebot-create-cd = "trestlebot.entrypoints.create_cd:main" -trestlebot-sync-upstreams = "trestlebot.entrypoints.sync_upstreams:main" -trestlebot-create-ssp = "trestlebot.entrypoints.create_ssp:main" +trestlebot = "trestlebot.cli.root:root_cmd" [tool.poetry.dependencies] python = '^3.8.1' From 6e7024315f75851e6bd76affc8544ea4eac933ea Mon Sep 17 00:00:00 2001 From: Qingmin Duanmu Date: Fri, 20 Dec 2024 21:09:08 +0800 Subject: [PATCH 2/5] fix: update e2e test to use new commands --- tests/e2e/e2e_testutils.py | 9 ++++++++- tests/e2e/test_e2e_compdef.py | 20 +++++++++++--------- tests/e2e/test_e2e_ssp.py | 10 +++++----- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/tests/e2e/e2e_testutils.py b/tests/e2e/e2e_testutils.py index d11acf1f..0a1b4702 100644 --- a/tests/e2e/e2e_testutils.py +++ b/tests/e2e/e2e_testutils.py @@ -143,7 +143,7 @@ def build_test_command( "--pod", E2ETestRunner.TRESTLEBOT_TEST_POD_NAME, "--entrypoint", - f"trestlebot-{command_name}", + "trestlebot", "--restart", "never", ] @@ -160,9 +160,16 @@ def build_test_command( "-w", "/trestle", self.trestlebot_image, + ] + ) + command_nodes = command_name.split() + command.extend( + command_nodes + + [ *args_dict_to_list(command_args), ] ) + return command def invoke_command( diff --git a/tests/e2e/test_e2e_compdef.py b/tests/e2e/test_e2e_compdef.py index 31840409..98c7441f 100644 --- a/tests/e2e/test_e2e_compdef.py +++ b/tests/e2e/test_e2e_compdef.py @@ -36,8 +36,8 @@ "success/happy path", { "branch": "test", - "markdown-path": "md_comp", - "rules-view-path": RULES_VIEW_DIR, + "markdown-dir": "md_comp", + "rules-view-dir": RULES_VIEW_DIR, "committer-name": "test", "committer-email": "test@email.com", }, @@ -46,8 +46,8 @@ "success/happy path with model skipping", { "branch": "test", - "rules-view-path": RULES_VIEW_DIR, - "markdown-path": "md_comp", + "rules-view-dir": RULES_VIEW_DIR, + "markdown-dir": "md_comp", "committer-name": "test", "committer-email": "test", "skip-items": test_comp_name, @@ -101,7 +101,7 @@ def test_rules_transform_e2e( "component-title": "test-comp", "compdef-name": "test-compdef", "component-description": "test", - "markdown-path": "markdown", + "markdown-dir": "markdown", "branch": "test", "committer-name": "test", "committer-email": "test@email.com", @@ -114,7 +114,7 @@ def test_rules_transform_e2e( "component-title": "test-comp", "compdef-name": "test-compdef", "component-description": "test", - "markdown-path": "markdown", + "markdown-dir": "markdown", "branch": "test", "committer-name": "test", "committer-email": "test@email.com", @@ -129,7 +129,7 @@ def test_create_cd_e2e( test_name: str, command_args: Dict[str, str], ) -> None: - """Test the trestlebot create-cd command.""" + """Test the trestlebot create compdef command.""" logger.info(f"Running test: {test_name}") tmp_repo_str, _ = tmp_repo @@ -139,7 +139,9 @@ def test_create_cd_e2e( _ = setup_for_profile(tmp_repo_path, test_prof, "") load_from_json(tmp_repo_path, test_filter_prof, test_filter_prof, Profile) - command = e2e_runner.build_test_command(tmp_repo_str, "create-cd", command_args) + command = e2e_runner.build_test_command( + tmp_repo_str, "create compdef", command_args + ) exit_code, _, _ = e2e_runner.invoke_command(command, tmp_repo_path) assert exit_code == SUCCESS_EXIT_CODE @@ -151,7 +153,7 @@ def test_create_cd_e2e( FileContentType.JSON, ) assert comp_path.exists() - assert (tmp_repo_path / command_args["markdown-path"]).exists() + assert (tmp_repo_path / command_args["markdown-dir"]).exists() assert ( tmp_repo_path / RULES_VIEW_DIR diff --git a/tests/e2e/test_e2e_ssp.py b/tests/e2e/test_e2e_ssp.py index 6406e9b6..c63c8369 100644 --- a/tests/e2e/test_e2e_ssp.py +++ b/tests/e2e/test_e2e_ssp.py @@ -47,11 +47,11 @@ def valid_args_dict() -> Dict[str, str]: return { "branch": "test", - "markdown-path": test_ssp_md, + "markdown-dir": test_ssp_md, "oscal-model": "ssp", "committer-name": "test", "committer-email": "test@email.com", - "ssp-index": "ssp-index.json", + "ssp-index-file": "ssp-index.json", } @@ -87,12 +87,12 @@ def test_ssp_editing_e2e( # Get command arguments for the test branch = valid_args_dict["branch"] - markdown_path = valid_args_dict["markdown-path"] + markdown_path = valid_args_dict["markdown-dir"] committer_name = valid_args_dict["committer-name"] committer_email = valid_args_dict["committer-email"] create_args: Dict[str, str] = { - "markdown-path": markdown_path, + "markdown-dir": markdown_path, "branch": branch, "committer-name": committer_name, "committer-email": committer_email, @@ -102,7 +102,7 @@ def test_ssp_editing_e2e( } create_command = e2e_runner.build_test_command( tmp_repo_str, - "create-ssp", + "create ssp", create_args, ) exit_code, _, _ = e2e_runner.invoke_command(create_command) From abcd7ebbf87464e46f7161bb991b8963d70a4784 Mon Sep 17 00:00:00 2001 From: Hannah Braswell <135030802+hbraswelrh@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:03:26 -0500 Subject: [PATCH 3/5] fix: update create command for e2e testing Changes made to use compdef_name reference instead of profile_name for model filter --- trestlebot/cli/commands/create.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trestlebot/cli/commands/create.py b/trestlebot/cli/commands/create.py index f37d5104..13871278 100644 --- a/trestlebot/cli/commands/create.py +++ b/trestlebot/cli/commands/create.py @@ -110,7 +110,7 @@ def compdef_cmd( transformer: ToRulesYAMLTransformer = ToRulesYAMLTransformer() model_filter: ModelFilter = ModelFilter( - [], [profile_name, component_title, f"{const.RULE_PREFIX}*"] + [], [compdef_name, component_title, f"{const.RULE_PREFIX}*"] ) rule_transform_task: RuleTransformTask = RuleTransformTask( From d701aab315e9f2ee6873ac9c324663681141e493 Mon Sep 17 00:00:00 2001 From: Qingmin Duanmu Date: Mon, 23 Dec 2024 09:35:46 +0800 Subject: [PATCH 4/5] fix: a typo in autosync command --- trestlebot/cli/commands/autosync.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trestlebot/cli/commands/autosync.py b/trestlebot/cli/commands/autosync.py index 87d607a5..19df0bb4 100644 --- a/trestlebot/cli/commands/autosync.py +++ b/trestlebot/cli/commands/autosync.py @@ -94,7 +94,7 @@ def autosync_cmd(ctx: click.Context, **kwargs: Any) -> None: authored_object: AuthoredObjectBase = types.get_authored_object( oscal_model, working_dir, - kwargs.get("ssp_index_path", ""), + kwargs.get("ssp_index_file", ""), ) # Assuming an edit has occurred assemble would be run before regenerate. From 2c2df3d589750ac1a8af763b139a2e21b70bb59c Mon Sep 17 00:00:00 2001 From: Qingmin Duanmu Date: Mon, 23 Dec 2024 11:08:37 +0800 Subject: [PATCH 5/5] fix: sys.exit with errorcode when exceptions --- tests/e2e/test_e2e_ssp.py | 7 ++- tests/trestlebot/cli/test_autosync_cmd.py | 4 +- trestlebot/cli/commands/autosync.py | 72 ++++++++++++----------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/tests/e2e/test_e2e_ssp.py b/tests/e2e/test_e2e_ssp.py index c63c8369..07940949 100644 --- a/tests/e2e/test_e2e_ssp.py +++ b/tests/e2e/test_e2e_ssp.py @@ -191,6 +191,9 @@ def test_ssp_e2e_editing_failure( autosync_command = e2e_runner.build_test_command( tmp_repo_str, "autosync", valid_args_dict ) - exit_code, _, response_stderr = e2e_runner.invoke_command(autosync_command) + exit_code, response_stdout, response_stderr = e2e_runner.invoke_command( + autosync_command + ) assert exit_code == ERROR_EXIT_CODE - assert "SSP test_ssp does not exists in the index" in response_stderr + err_msg = "SSP test_ssp does not exists in the index" + assert err_msg in response_stdout or err_msg in response_stderr diff --git a/tests/trestlebot/cli/test_autosync_cmd.py b/tests/trestlebot/cli/test_autosync_cmd.py index e0d370ec..e9916f68 100644 --- a/tests/trestlebot/cli/test_autosync_cmd.py +++ b/tests/trestlebot/cli/test_autosync_cmd.py @@ -87,8 +87,8 @@ def test_missing_markdown_dir_option(tmp_repo: Tuple[str, Repo]) -> None: assert result.exit_code == 2 assert "Error: Missing option '--markdown-dir'" in result.output - # With 'markdown_dir' setting in config.yml + # With non-existent 'markdown_dir' setting in config.yml config_obj = TrestleBotConfig(markdown_dir="markdown") write_to_file(config_obj, filepath) result = runner.invoke(autosync_cmd, cmd_options) - assert result.exit_code == 0 + assert result.exit_code == 1 diff --git a/trestlebot/cli/commands/autosync.py b/trestlebot/cli/commands/autosync.py index 19df0bb4..921752cc 100644 --- a/trestlebot/cli/commands/autosync.py +++ b/trestlebot/cli/commands/autosync.py @@ -5,11 +5,12 @@ import logging import sys +import traceback from typing import Any, List import click -from trestlebot.cli.options.common import common_options, git_options, handle_exceptions +from trestlebot.cli.options.common import common_options, git_options from trestlebot.cli.utils import comma_sep_to_list, run_bot from trestlebot.const import ERROR_EXIT_CODE from trestlebot.tasks.assemble_task import AssembleTask @@ -69,7 +70,6 @@ type=str, required=False, ) -@handle_exceptions def autosync_cmd(ctx: click.Context, **kwargs: Any) -> None: """Command to autosync catalog, profile, compdef and ssp.""" @@ -87,37 +87,43 @@ def autosync_cmd(ctx: click.Context, **kwargs: Any) -> None: if kwargs.get("file_pattern"): kwargs.update({"patterns": comma_sep_to_list(kwargs["file_patterns"])}) - model_filter: ModelFilter = ModelFilter( - skip_patterns=comma_sep_to_list(kwargs.get("skip_items", "")), - include_patterns=["*"], - ) - authored_object: AuthoredObjectBase = types.get_authored_object( - oscal_model, - working_dir, - kwargs.get("ssp_index_file", ""), - ) - - # Assuming an edit has occurred assemble would be run before regenerate. - if not kwargs.get("skip_assemble"): - assemble_task: AssembleTask = AssembleTask( - authored_object=authored_object, - markdown_dir=markdown_dir, - version=kwargs.get("version", ""), - model_filter=model_filter, + try: + model_filter: ModelFilter = ModelFilter( + skip_patterns=comma_sep_to_list(kwargs.get("skip_items", "")), + include_patterns=["*"], ) - pre_tasks.append(assemble_task) - else: - logger.info("Assemble task skipped.") - - if not kwargs.get("skip_regenerate"): - regenerate_task: RegenerateTask = RegenerateTask( - authored_object=authored_object, - markdown_dir=markdown_dir, - model_filter=model_filter, + authored_object: AuthoredObjectBase = types.get_authored_object( + oscal_model, + working_dir, + kwargs.get("ssp_index_file", ""), ) - pre_tasks.append(regenerate_task) - else: - logger.info("Regeneration task skipped.") - results = run_bot(pre_tasks, kwargs) - logger.debug(f"Trestlebot results: {results}") + # Assuming an edit has occurred assemble would be run before regenerate. + if not kwargs.get("skip_assemble"): + assemble_task: AssembleTask = AssembleTask( + authored_object=authored_object, + markdown_dir=markdown_dir, + version=kwargs.get("version", ""), + model_filter=model_filter, + ) + pre_tasks.append(assemble_task) + else: + logger.info("Assemble task skipped.") + + if not kwargs.get("skip_regenerate"): + regenerate_task: RegenerateTask = RegenerateTask( + authored_object=authored_object, + markdown_dir=markdown_dir, + model_filter=model_filter, + ) + pre_tasks.append(regenerate_task) + else: + logger.info("Regeneration task skipped.") + + results = run_bot(pre_tasks, kwargs) + logger.debug(f"Trestlebot results: {results}") + except Exception as e: + traceback_str = traceback.format_exc() + logger.error(f"Trestle-bot Error: {str(e)}") + logger.debug(traceback_str) + sys.exit(ERROR_EXIT_CODE)