Skip to content

Commit 43b66ad

Browse files
authored
fix: add repo argument to the build handler (#14238)
This PR fixes the issue to run the generate command with the build flag.
1 parent 1ef64cd commit 43b66ad

File tree

2 files changed

+68
-31
lines changed

2 files changed

+68
-31
lines changed

.generator/cli.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
SYNTHTOOL_INSTALLED = True
3131
SYNTHTOOL_IMPORT_ERROR = None
32-
except ImportError as e: # pragma: NO COVER
32+
except ImportError as e: # pragma: NO COVER
3333
SYNTHTOOL_IMPORT_ERROR = e
3434
SYNTHTOOL_INSTALLED = False
3535

@@ -91,7 +91,7 @@ def _determine_bazel_rule(api_path: str, source: str) -> str:
9191

9292
# This check is for a logical failure (no match), not a runtime exception.
9393
# It's good to keep it for clear error messaging.
94-
if not match: # pragma: NO COVER
94+
if not match: # pragma: NO COVER
9595
raise ValueError(
9696
f"No Bazel rule with a name ending in '-py' found in {build_file_path}"
9797
)
@@ -241,7 +241,7 @@ def _run_post_processor(output: str, library_id: str):
241241
if SYNTHTOOL_INSTALLED:
242242
python_mono_repo.owlbot_main(path_to_library)
243243
else:
244-
raise SYNTHTOOL_IMPORT_ERROR # pragma: NO COVER
244+
raise SYNTHTOOL_IMPORT_ERROR # pragma: NO COVER
245245
logger.info("Python post-processor ran successfully.")
246246

247247

@@ -269,7 +269,9 @@ def _copy_files_needed_for_post_processing(output: str, input: str, library_id:
269269
)
270270

271271
# copy post-procesing files
272-
for post_processing_file in glob.glob(f"{input}/client-post-processing/*.yaml"): # pragma: NO COVER
272+
for post_processing_file in glob.glob(
273+
f"{input}/client-post-processing/*.yaml"
274+
): # pragma: NO COVER
273275
with open(post_processing_file, "r") as post_processing:
274276
if f"{path_to_library}/" in post_processing.read():
275277
shutil.copy(
@@ -294,15 +296,15 @@ def _clean_up_files_after_post_processing(output: str, library_id: str):
294296
os.remove(f"{output}/{path_to_library}/docs/README.rst")
295297
for post_processing_file in glob.glob(
296298
f"{output}/{path_to_library}/scripts/client-post-processing/*.yaml"
297-
): # pragma: NO COVER
299+
): # pragma: NO COVER
298300
os.remove(post_processing_file)
299301
for gapic_version_file in glob.glob(
300302
f"{output}/{path_to_library}/**/gapic_version.py", recursive=True
301-
): # pragma: NO COVER
303+
): # pragma: NO COVER
302304
os.remove(gapic_version_file)
303305
for snippet_metadata_file in glob.glob(
304306
f"{output}/{path_to_library}/samples/generated_samples/snippet_metadata*.json"
305-
): # pragma: NO COVER
307+
): # pragma: NO COVER
306308
os.remove(snippet_metadata_file)
307309
shutil.rmtree(f"{output}/owl-bot-staging")
308310

@@ -364,7 +366,7 @@ def handle_generate(
364366
logger.info("'generate' command executed.")
365367

366368

367-
def _run_nox_sessions(sessions: List[str], librarian: str):
369+
def _run_nox_sessions(sessions: List[str], librarian: str, repo: str):
368370
"""Calls nox for all specified sessions.
369371
370372
Args:
@@ -377,12 +379,17 @@ def _run_nox_sessions(sessions: List[str], librarian: str):
377379
request_data = _read_json_file(f"{librarian}/{BUILD_REQUEST_FILE}")
378380
library_id = _get_library_id(request_data)
379381
for nox_session in sessions:
380-
_run_individual_session(nox_session, library_id)
382+
_run_individual_session(nox_session, library_id, repo)
383+
384+
# Write the `build-response.json` using `build-request.json` as the source
385+
with open(f"{librarian}/build-response.json", "w") as f:
386+
json.dump(request_data, f, indent=4)
387+
f.write("\n")
381388
except Exception as e:
382389
raise ValueError(f"Failed to run the nox session: {current_session}") from e
383390

384391

385-
def _run_individual_session(nox_session: str, library_id: str):
392+
def _run_individual_session(nox_session: str, library_id: str, repo: str):
386393
"""
387394
Calls nox with the specified sessions.
388395
@@ -396,13 +403,13 @@ def _run_individual_session(nox_session: str, library_id: str):
396403
"-s",
397404
nox_session,
398405
"-f",
399-
f"{REPO_DIR}/packages/{library_id}",
406+
f"{repo}/packages/{library_id}/noxfile.py",
400407
]
401408
result = subprocess.run(command, text=True, check=True)
402409
logger.info(result)
403410

404411

405-
def handle_build(librarian: str = LIBRARIAN_DIR):
412+
def handle_build(librarian: str = LIBRARIAN_DIR, repo: str = REPO_DIR):
406413
"""The main coordinator for validating client library generation."""
407414
sessions = [
408415
"unit-3.9",
@@ -411,18 +418,17 @@ def handle_build(librarian: str = LIBRARIAN_DIR):
411418
"unit-3.12",
412419
"unit-3.13",
413420
"docs",
414-
"system",
421+
"system-3.13",
415422
"lint",
416423
"lint_setup_py",
417-
"mypy",
418-
"check_lower_bounds",
424+
"mypy-3.13",
419425
]
420-
_run_nox_sessions(sessions, librarian)
426+
_run_nox_sessions(sessions, librarian, repo)
421427

422428
logger.info("'build' command executed.")
423429

424430

425-
if __name__ == "__main__": # pragma: NO COVER
431+
if __name__ == "__main__": # pragma: NO COVER
426432
parser = argparse.ArgumentParser(description="A simple CLI tool.")
427433
subparsers = parser.add_subparsers(
428434
dest="command", required=True, help="Available commands"
@@ -466,6 +472,12 @@ def handle_build(librarian: str = LIBRARIAN_DIR):
466472
help="Path to the directory in the container which contains API protos",
467473
default=SOURCE_DIR,
468474
)
475+
parser_cmd.add_argument(
476+
"--repo",
477+
type=str,
478+
help="Path to the directory in the container which contains google-cloud-python repository",
479+
default=SOURCE_DIR,
480+
)
469481
if len(sys.argv) == 1:
470482
parser.print_help(sys.stderr)
471483
sys.exit(1)
@@ -481,6 +493,6 @@ def handle_build(librarian: str = LIBRARIAN_DIR):
481493
input=args.input,
482494
)
483495
elif args.command == "build":
484-
args.func(librarian=args.librarian)
496+
args.func(librarian=args.librarian, repo=args.repo)
485497
else:
486498
args.func()

.generator/test_cli.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
from cli import (
2424
GENERATE_REQUEST_FILE,
25+
BUILD_REQUEST_FILE,
2526
LIBRARIAN_DIR,
2627
REPO_DIR,
2728
_build_bazel_target,
@@ -60,6 +61,26 @@ def mock_generate_request_file(tmp_path, monkeypatch):
6061
return request_file
6162

6263

64+
@pytest.fixture
65+
def mock_build_request_file(tmp_path, monkeypatch):
66+
"""Creates the mock request file at the correct path inside a temp dir."""
67+
# Create the path as expected by the script: .librarian/build-request.json
68+
request_path = f"{LIBRARIAN_DIR}/{BUILD_REQUEST_FILE}"
69+
request_dir = tmp_path / os.path.dirname(request_path)
70+
request_dir.mkdir()
71+
request_file = request_dir / os.path.basename(request_path)
72+
73+
request_content = {
74+
"id": "google-cloud-language",
75+
"apis": [{"path": "google/cloud/language/v1"}],
76+
}
77+
request_file.write_text(json.dumps(request_content))
78+
79+
# Change the current working directory to the temp path for the test.
80+
monkeypatch.chdir(tmp_path)
81+
return request_file
82+
83+
6384
@pytest.fixture
6485
def mock_generate_request_data_for_nox():
6586
"""Returns mock data for generate-request.json for nox tests."""
@@ -298,14 +319,15 @@ def test_run_individual_session_success(mocker, caplog):
298319

299320
test_session = "unit-3.9"
300321
test_library_id = "test-library"
301-
_run_individual_session(test_session, test_library_id)
322+
repo = "repo"
323+
_run_individual_session(test_session, test_library_id, repo)
302324

303325
expected_command = [
304326
"nox",
305327
"-s",
306328
test_session,
307329
"-f",
308-
f"{REPO_DIR}/packages/{test_library_id}",
330+
f"{REPO_DIR}/packages/{test_library_id}/noxfile.py",
309331
]
310332
mock_subprocess_run.assert_called_once_with(expected_command, text=True, check=True)
311333

@@ -320,23 +342,25 @@ def test_run_individual_session_failure(mocker):
320342
)
321343

322344
with pytest.raises(subprocess.CalledProcessError):
323-
_run_individual_session("lint", "another-library")
345+
_run_individual_session("lint", "another-library", "repo")
324346

325347

326-
def test_run_nox_sessions_success(mocker, mock_generate_request_data_for_nox):
348+
def test_run_nox_sessions_success(
349+
mocker, mock_generate_request_data_for_nox, mock_build_request_file
350+
):
327351
"""Tests that _run_nox_sessions successfully runs all specified sessions."""
328352
mocker.patch("cli._read_json_file", return_value=mock_generate_request_data_for_nox)
329353
mocker.patch("cli._get_library_id", return_value="mock-library")
330354
mock_run_individual_session = mocker.patch("cli._run_individual_session")
331355

332356
sessions_to_run = ["unit-3.9", "lint"]
333-
_run_nox_sessions(sessions_to_run, "librarian")
357+
_run_nox_sessions(sessions_to_run, "librarian", "repo")
334358

335359
assert mock_run_individual_session.call_count == len(sessions_to_run)
336360
mock_run_individual_session.assert_has_calls(
337361
[
338-
mocker.call("unit-3.9", "mock-library"),
339-
mocker.call("lint", "mock-library"),
362+
mocker.call("unit-3.9", "mock-library", "repo"),
363+
mocker.call("lint", "mock-library", "repo"),
340364
]
341365
)
342366

@@ -346,7 +370,7 @@ def test_run_nox_sessions_read_file_failure(mocker):
346370
mocker.patch("cli._read_json_file", side_effect=FileNotFoundError("file not found"))
347371

348372
with pytest.raises(ValueError, match="Failed to run the nox session"):
349-
_run_nox_sessions(["unit-3.9"], "librarian")
373+
_run_nox_sessions(["unit-3.9"], "librarian", "repo")
350374

351375

352376
def test_run_nox_sessions_get_library_id_failure(mocker):
@@ -358,7 +382,7 @@ def test_run_nox_sessions_get_library_id_failure(mocker):
358382
)
359383

360384
with pytest.raises(ValueError, match="Failed to run the nox session"):
361-
_run_nox_sessions(["unit-3.9"], "librarian")
385+
_run_nox_sessions(["unit-3.9"], "librarian", "repo")
362386

363387

364388
def test_run_nox_sessions_individual_session_failure(
@@ -374,7 +398,7 @@ def test_run_nox_sessions_individual_session_failure(
374398

375399
sessions_to_run = ["unit-3.9", "lint"]
376400
with pytest.raises(ValueError, match="Failed to run the nox session"):
377-
_run_nox_sessions(sessions_to_run, "librarian")
401+
_run_nox_sessions(sessions_to_run, "librarian", "repo")
378402

379403
# Check that _run_individual_session was called at least once
380404
assert mock_run_individual_session.call_count > 0
@@ -416,16 +440,17 @@ def test_invalid_json(mocker):
416440
with pytest.raises(json.JSONDecodeError):
417441
_read_json_file("fake/path.json")
418442

443+
419444
def test_copy_files_needed_for_post_processing_success(mocker):
420445
mock_makedirs = mocker.patch("os.makedirs")
421446
mock_shutil_copy = mocker.patch("shutil.copy")
422-
_copy_files_needed_for_post_processing('output', 'input', 'library_id')
423-
447+
_copy_files_needed_for_post_processing("output", "input", "library_id")
448+
424449
mock_makedirs.assert_called()
425450
mock_shutil_copy.assert_called_once()
426451

427452

428453
def test_clean_up_files_after_post_processing_success(mocker):
429454
mock_shutil_rmtree = mocker.patch("shutil.rmtree")
430455
mock_os_remove = mocker.patch("os.remove")
431-
_clean_up_files_after_post_processing('output', 'library_id')
456+
_clean_up_files_after_post_processing("output", "library_id")

0 commit comments

Comments
 (0)