From 3e73a1150febaad7a04e097ecac225c3aaf4f8db Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 24 Jul 2025 15:12:07 +0000 Subject: [PATCH 1/3] feat: run post processor in cli --- .generator/cli.py | 33 +++++++++++++++++++++++++++++++-- .generator/test_cli.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/.generator/cli.py b/.generator/cli.py index 2d216d0aac3a..067ded658f5e 100644 --- a/.generator/cli.py +++ b/.generator/cli.py @@ -21,6 +21,15 @@ import subprocess from typing import Dict, List +try: + import synthtool + from synthtool import gcp + + SYNTHTOOL_INSTALLED = True +except ImportError as e: + SYNTHTOOL_IMPORT_ERROR = e + SYNTHTOOL_INSTALLED = False + logger = logging.getLogger() LIBRARIAN_DIR = "librarian" @@ -174,6 +183,26 @@ def _locate_and_extract_artifact(bazel_rule: str, library_id: str): ) from e +def _run_post_processor(): + """Runs the synthtool post-processor on the output directory. + + Raises: + ValueError: If the subprocess call fails. + """ + try: + logger.info("Running Python post-processor...") + if SYNTHTOOL_INSTALLED: + command = ["python3", "-m", "synthtool.languages.python_mono_repo"] + os.chdir(OUTPUT_DIR) + subprocess.run(command, cwd=OUTPUT_DIR, text=True, check=True) + else: + raise SYNTHTOOL_IMPORT_ERROR + logger.info("Python post-processor ran successfully.") + + except Exception as e: + raise ValueError("Python post-processor failed...") from e + + def handle_generate(): """The main coordinator for the code generation process. @@ -185,8 +214,8 @@ def handle_generate(): ValueError: If the `generate-request.json` file is not found or read. """ - # Read a generate-request.json file try: + # Read a generate-request.json file request_data = _read_json_file(f"{LIBRARIAN_DIR}/{GENERATE_REQUEST_FILE}") library_id = _get_library_id(request_data) @@ -196,8 +225,8 @@ def handle_generate(): bazel_rule = _determine_bazel_rule(api_path) _build_bazel_target(bazel_rule) _locate_and_extract_artifact(bazel_rule, library_id) + _run_post_processor() - logger.info(json.dumps(request_data, indent=2)) except Exception as e: raise ValueError("Generation failed.") from e diff --git a/.generator/test_cli.py b/.generator/test_cli.py index d14619443a72..68983c5021c1 100644 --- a/.generator/test_cli.py +++ b/.generator/test_cli.py @@ -31,6 +31,7 @@ _read_json_file, _run_individual_session, _run_nox_sessions, + _run_post_processor, handle_build, handle_configure, handle_generate, @@ -205,6 +206,37 @@ def test_locate_and_extract_artifact_fails(mocker, caplog): ) +def test_run_post_processor_success(mocker, caplog): + """ + Tests that the post-processor helper calls the correct command. + """ + caplog.set_level(logging.INFO) + mocker.patch("cli.SYNTHTOOL_INSTALLED", return_value=True) + mock_chdir = mocker.patch("cli.os.chdir") + mock_subprocess = mocker.patch("cli.subprocess.run") + + _run_post_processor() + + mock_subprocess.assert_called_once() + + assert mock_subprocess.call_args.kwargs["cwd"] == "output" + assert "Python post-processor ran successfully." in caplog.text + + +def test_locate_and_extract_artifact_fails(mocker, caplog): + """ + Tests that an exception is raised if the subprocess command fails. + """ + caplog.set_level(logging.INFO) + mocker.patch( + "cli.subprocess.run", + side_effect=subprocess.CalledProcessError(1, "cmd", stderr="Python error"), + ) + + with pytest.raises(ValueError): + _run_post_processor() + + def test_handle_generate_success(caplog, mock_generate_request_file, mocker): """ Tests the successful execution path of handle_generate. @@ -215,8 +247,8 @@ def test_handle_generate_success(caplog, mock_generate_request_file, mocker): "cli._determine_bazel_rule", return_value="mock-rule" ) mock_build_target = mocker.patch("cli._build_bazel_target") - mock_locate_and_extract_artifact = mocker.patch("cli._locate_and_extract_artifact") + mock_run_post_processor = mocker.patch("cli._run_post_processor") handle_generate() From 0d6410171ebf9eb0dd3d569a355e9968731a4bf2 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 24 Jul 2025 18:47:31 +0000 Subject: [PATCH 2/3] address PR feedback --- .generator/cli.py | 20 ++++++++------------ .generator/test_cli.py | 8 ++------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/.generator/cli.py b/.generator/cli.py index 067ded658f5e..312fa43ba713 100644 --- a/.generator/cli.py +++ b/.generator/cli.py @@ -26,6 +26,7 @@ from synthtool import gcp SYNTHTOOL_INSTALLED = True + SYNTHTOOL_IMPORT_ERROR = None except ImportError as e: SYNTHTOOL_IMPORT_ERROR = e SYNTHTOOL_INSTALLED = False @@ -189,18 +190,13 @@ def _run_post_processor(): Raises: ValueError: If the subprocess call fails. """ - try: - logger.info("Running Python post-processor...") - if SYNTHTOOL_INSTALLED: - command = ["python3", "-m", "synthtool.languages.python_mono_repo"] - os.chdir(OUTPUT_DIR) - subprocess.run(command, cwd=OUTPUT_DIR, text=True, check=True) - else: - raise SYNTHTOOL_IMPORT_ERROR - logger.info("Python post-processor ran successfully.") - - except Exception as e: - raise ValueError("Python post-processor failed...") from e + logger.info("Running Python post-processor...") + if SYNTHTOOL_INSTALLED: + command = ["python3", "-m", "synthtool.languages.python_mono_repo"] + subprocess.run(command, cwd=OUTPUT_DIR, text=True, check=True) + else: + raise SYNTHTOOL_IMPORT_ERROR + logger.info("Python post-processor ran successfully.") def handle_generate(): diff --git a/.generator/test_cli.py b/.generator/test_cli.py index 68983c5021c1..552ebaee024e 100644 --- a/.generator/test_cli.py +++ b/.generator/test_cli.py @@ -212,7 +212,6 @@ def test_run_post_processor_success(mocker, caplog): """ caplog.set_level(logging.INFO) mocker.patch("cli.SYNTHTOOL_INSTALLED", return_value=True) - mock_chdir = mocker.patch("cli.os.chdir") mock_subprocess = mocker.patch("cli.subprocess.run") _run_post_processor() @@ -228,12 +227,9 @@ def test_locate_and_extract_artifact_fails(mocker, caplog): Tests that an exception is raised if the subprocess command fails. """ caplog.set_level(logging.INFO) - mocker.patch( - "cli.subprocess.run", - side_effect=subprocess.CalledProcessError(1, "cmd", stderr="Python error"), - ) + mocker.patch("cli.SYNTHTOOL_INSTALLED", return_value=True) - with pytest.raises(ValueError): + with pytest.raises(FileNotFoundError): _run_post_processor() From ba6360d1bc954cbf93ba5fce6198e85d50258ccc Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 24 Jul 2025 15:19:23 -0400 Subject: [PATCH 3/3] Update .generator/cli.py Co-authored-by: Anthonios Partheniou --- .generator/cli.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/.generator/cli.py b/.generator/cli.py index 312fa43ba713..417ef2d0a922 100644 --- a/.generator/cli.py +++ b/.generator/cli.py @@ -186,9 +186,6 @@ def _locate_and_extract_artifact(bazel_rule: str, library_id: str): def _run_post_processor(): """Runs the synthtool post-processor on the output directory. - - Raises: - ValueError: If the subprocess call fails. """ logger.info("Running Python post-processor...") if SYNTHTOOL_INSTALLED: