3333
3434try :
3535 import synthtool
36- from synthtool .languages import python_mono_repo
36+ from synthtool .languages import python , python_mono_repo
3737
3838 SYNTHTOOL_INSTALLED = True
3939 SYNTHTOOL_IMPORT_ERROR = None
@@ -316,20 +316,28 @@ def _get_library_id(request_data: Dict) -> str:
316316 return library_id
317317
318318
319- def _run_post_processor (output : str , library_id : str ):
319+ def _run_post_processor (output : str , library_id : str , is_mono_repo : bool ):
320320 """Runs the synthtool post-processor on the output directory.
321321
322322 Args:
323323 output(str): Path to the directory in the container where code
324324 should be generated.
325325 library_id(str): The library id to be used for post processing.
326-
326+ is_mono_repo(bool): True if the current repository is a mono-repo.
327327 """
328328 os .chdir (output )
329- path_to_library = f"packages/{ library_id } "
329+ path_to_library = f"packages/{ library_id } " if is_mono_repo else "."
330330 logger .info ("Running Python post-processor..." )
331331 if SYNTHTOOL_INSTALLED :
332- python_mono_repo .owlbot_main (path_to_library )
332+ if is_mono_repo :
333+ python_mono_repo .owlbot_main (path_to_library )
334+ else :
335+ # Some repositories have customizations in `owlbot.py`. If this file exists,
336+ # run those customizations instead of `owlbot_main`
337+ if Path (f"{ output } /owlbot.py" ).exists ():
338+ subprocess .run (["python3.14" , f"{ output } /owlbot.py" ])
339+ else :
340+ python .owlbot_main ()
333341 else :
334342 raise SYNTHTOOL_IMPORT_ERROR # pragma: NO COVER
335343
@@ -342,7 +350,9 @@ def _run_post_processor(output: str, library_id: str):
342350 logger .info ("Python post-processor ran successfully." )
343351
344352
345- def _copy_files_needed_for_post_processing (output : str , input : str , library_id : str ):
353+ def _copy_files_needed_for_post_processing (
354+ output : str , input : str , library_id : str , is_mono_repo : bool
355+ ):
346356 """Copy files to the output directory whcih are needed during the post processing
347357 step, such as .repo-metadata.json and script/client-post-processing, using
348358 the input directory as the source.
@@ -353,25 +363,23 @@ def _copy_files_needed_for_post_processing(output: str, input: str, library_id:
353363 input(str): The path to the directory in the container
354364 which contains additional generator input.
355365 library_id(str): The library id to be used for post processing.
366+ is_mono_repo(bool): True if the current repository is a mono-repo.
356367 """
357368
358- path_to_library = f"packages/{ library_id } "
359- repo_metadata_path = f"{ input } /{ path_to_library } /.repo-metadata.json"
369+ path_to_library = f"packages/{ library_id } " if is_mono_repo else "."
370+ source_dir = f"{ input } /{ path_to_library } "
371+
372+ shutil .copytree (
373+ source_dir ,
374+ output ,
375+ dirs_exist_ok = True ,
376+ ignore = shutil .ignore_patterns ("client-post-processing" ),
377+ )
360378
361379 # We need to create these directories so that we can copy files necessary for post-processing.
362380 os .makedirs (
363381 f"{ output } /{ path_to_library } /scripts/client-post-processing" , exist_ok = True
364382 )
365- # TODO(https://github.com/googleapis/librarian/issues/2334):
366- # if `.repo-metadata.json` for a library exists in
367- # `.librarian/generator-input`, then we override the generated `.repo-metadata.json`
368- # with what we have in `generator-input`. Remove this logic once the
369- # generated `.repo-metadata.json` file is completely backfilled.
370- if os .path .exists (repo_metadata_path ):
371- shutil .copy (
372- repo_metadata_path ,
373- f"{ output } /{ path_to_library } /.repo-metadata.json" ,
374- )
375383
376384 # copy post-procesing files
377385 for post_processing_file in glob .glob (
@@ -385,7 +393,9 @@ def _copy_files_needed_for_post_processing(output: str, input: str, library_id:
385393 )
386394
387395
388- def _clean_up_files_after_post_processing (output : str , library_id : str ):
396+ def _clean_up_files_after_post_processing (
397+ output : str , library_id : str , is_mono_repo : bool
398+ ):
389399 """
390400 Clean up files which should not be included in the generated client.
391401 This function is idempotent and will not fail if files are already removed.
@@ -394,8 +404,9 @@ def _clean_up_files_after_post_processing(output: str, library_id: str):
394404 output(str): Path to the directory in the container where code
395405 should be generated.
396406 library_id(str): The library id to be used for post processing.
407+ is_mono_repo(bool): True if the current repository is a mono-repo.
397408 """
398- path_to_library = f"packages/{ library_id } "
409+ path_to_library = f"packages/{ library_id } " if is_mono_repo else "."
399410
400411 # Safely remove directories, ignoring errors if they don't exist.
401412 shutil .rmtree (f"{ output } /{ path_to_library } /.nox" , ignore_errors = True )
@@ -486,7 +497,7 @@ def _create_repo_metadata_from_service_config(
486497
487498
488499def _generate_repo_metadata_file (
489- output : str , library_id : str , source : str , apis : List [Dict ]
500+ output : str , library_id : str , source : str , apis : List [Dict ], is_mono_repo : bool
490501):
491502 """Generates the .repo-metadata.json file from the primary API service config.
492503
@@ -495,8 +506,9 @@ def _generate_repo_metadata_file(
495506 library_id (str): The ID of the library.
496507 source (str): The path to the source directory.
497508 apis (List[Dict]): A list of APIs to generate.
509+ is_mono_repo(bool): True if the current repository is a mono-repo.
498510 """
499- path_to_library = f"packages/{ library_id } "
511+ path_to_library = f"packages/{ library_id } " if is_mono_repo else "."
500512 output_repo_metadata = f"{ output } /{ path_to_library } /.repo-metadata.json"
501513
502514 # TODO(https://github.com/googleapis/librarian/issues/2334)): If `.repo-metadata.json`
@@ -523,7 +535,7 @@ def _generate_repo_metadata_file(
523535 _write_json_file (output_repo_metadata , metadata_content )
524536
525537
526- def _copy_readme_to_docs (output : str , library_id : str ):
538+ def _copy_readme_to_docs (output : str , library_id : str , is_mono_repo : bool ):
527539 """Copies the README.rst file for a generated library to docs/README.rst.
528540
529541 This function is robust against various symlink configurations that could
@@ -536,7 +548,7 @@ def _copy_readme_to_docs(output: str, library_id: str):
536548 should be generated.
537549 library_id(str): The library id.
538550 """
539- path_to_library = f"packages/{ library_id } "
551+ path_to_library = f"packages/{ library_id } " if is_mono_repo else "."
540552 source_path = f"{ output } /{ path_to_library } /README.rst"
541553 docs_path = f"{ output } /{ path_to_library } /docs"
542554 destination_path = f"{ docs_path } /README.rst"
@@ -593,6 +605,7 @@ def handle_generate(
593605 """
594606
595607 try :
608+ is_mono_repo = _is_mono_repo (input )
596609 # Read a generate-request.json file
597610 request_data = _read_json_file (f"{ librarian } /{ GENERATE_REQUEST_FILE } " )
598611 library_id = _get_library_id (request_data )
@@ -601,12 +614,16 @@ def handle_generate(
601614 for api in apis_to_generate :
602615 api_path = api .get ("path" )
603616 if api_path :
604- _generate_api (api_path , library_id , source , output , version )
605- _copy_files_needed_for_post_processing (output , input , library_id )
606- _generate_repo_metadata_file (output , library_id , source , apis_to_generate )
607- _run_post_processor (output , library_id )
608- _copy_readme_to_docs (output , library_id )
609- _clean_up_files_after_post_processing (output , library_id )
617+ _generate_api (
618+ api_path , library_id , source , output , version , is_mono_repo
619+ )
620+ _copy_files_needed_for_post_processing (output , input , library_id , is_mono_repo )
621+ _generate_repo_metadata_file (
622+ output , library_id , source , apis_to_generate , is_mono_repo
623+ )
624+ _run_post_processor (output , library_id , is_mono_repo )
625+ _copy_readme_to_docs (output , library_id , is_mono_repo )
626+ _clean_up_files_after_post_processing (output , library_id , is_mono_repo )
610627 except Exception as e :
611628 raise ValueError ("Generation failed." ) from e
612629 logger .info ("'generate' command executed." )
@@ -821,7 +838,12 @@ def _stage_gapic_library(tmp_dir: str, staging_dir: str) -> None:
821838
822839
823840def _generate_api (
824- api_path : str , library_id : str , source : str , output : str , gapic_version : str
841+ api_path : str ,
842+ library_id : str ,
843+ source : str ,
844+ output : str ,
845+ gapic_version : str ,
846+ is_mono_repo : bool ,
825847):
826848 """
827849 Handles the generation and staging process for a single API path.
@@ -833,6 +855,7 @@ def _generate_api(
833855 output (str): Path to the output directory where code should be staged.
834856 gapic_version(str): The desired version number for the GAPIC client library
835857 in a format which follows PEP-440.
858+ is_mono_repo(bool): True if the current repository is a mono-repo.
836859 """
837860 py_gapic_config = _read_bazel_build_py_rule (api_path , source )
838861 is_proto_only_library = len (py_gapic_config ) == 0
@@ -854,9 +877,10 @@ def _generate_api(
854877 staging_child_directory = _get_staging_child_directory (
855878 api_path , is_proto_only_library
856879 )
857- staging_dir = os .path .join (
858- output , "owl-bot-staging" , library_id , staging_child_directory
859- )
880+ staging_dir = os .path .join (output , "owl-bot-staging" )
881+ if is_mono_repo :
882+ staging_dir = os .path .join (staging_dir , library_id )
883+ staging_dir = os .path .join (staging_dir , staging_child_directory )
860884
861885 # 4. Stage the generated code
862886 if is_proto_only_library :
@@ -1464,10 +1488,7 @@ def handle_release_init(
14641488 f"{ library_id } version: { previous_version } \n "
14651489 )
14661490
1467- if is_mono_repo :
1468- path_to_library = f"packages/{ library_id } "
1469- else :
1470- path_to_library = "."
1491+ path_to_library = f"packages/{ library_id } " if is_mono_repo else "."
14711492
14721493 _update_version_for_library (repo , output , path_to_library , version )
14731494 _update_changelog_for_library (
0 commit comments