1# Copyright 2018 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15from pathlib import Path 16 17from synthtool import _tracked_paths 18from synthtool.gcp import artman 19from synthtool.log import logger 20from synthtool.sources import git 21 22DISCOVERY_ARTIFACT_MANAGER_URL: str = git.make_repo_clone_url( 23 "googleapis/discovery-artifact-manager" 24) 25 26 27class DiscoGAPICGenerator: 28 def __init__(self): 29 self._clone_discovery_artifact_manager() 30 31 def py_library(self, service: str, version: str, **kwargs) -> Path: 32 """ 33 Generates the Python Library files using artman/GAPIC 34 returns a `Path` object 35 library: path to library. 'google/cloud/speech' 36 version: version of lib. 'v1' 37 """ 38 return self._generate_code(service, version, "python", **kwargs) 39 40 def node_library(self, service: str, version: str, **kwargs) -> Path: 41 return self._generate_code(service, version, "nodejs", **kwargs) 42 43 nodejs_library = node_library 44 45 def ruby_library(self, service: str, version: str, **kwargs) -> Path: 46 return self._generate_code(service, version, "ruby", **kwargs) 47 48 def php_library(self, service: str, version: str, **kwargs) -> Path: 49 return self._generate_code(service, version, "php", **kwargs) 50 51 def java_library(self, service: str, version: str, **kwargs) -> Path: 52 return self._generate_code(service, version, "java", **kwargs) 53 54 def _generate_code( 55 self, service, version, language, config_path=None, artman_output_name=None 56 ): 57 # map the language to the artman argument and subdir of genfiles 58 GENERATE_FLAG_LANGUAGE = { 59 "python": ("python_gapic", "python"), 60 "nodejs": ("nodejs_gapic", "js"), 61 "ruby": ("ruby_gapic", "ruby"), 62 "php": ("php_gapic", "php"), 63 "java": ("java_discogapic", "java"), 64 } 65 66 if language not in GENERATE_FLAG_LANGUAGE: 67 raise ValueError("provided language unsupported") 68 69 gapic_language_arg, gen_language = GENERATE_FLAG_LANGUAGE[language] 70 71 if self.discovery_artifact_manager is None: 72 raise RuntimeError( 73 f"Unable to generate {config_path}, the googleapis repository" 74 "is unavailable." 75 ) 76 77 # Run the code generator. 78 # $ artman --config path/to/artman_api.yaml generate python_gapic 79 if config_path is None: 80 config_path = ( 81 Path("gapic/google") / service / f"artman_{service}_{version}.yaml" 82 ) 83 elif Path(config_path).is_absolute(): 84 config_path = Path(config_path).relative_to("/") 85 else: 86 config_path = Path("gapic/google") / service / Path(config_path) 87 88 if not (self.discovery_artifact_manager / config_path).exists(): 89 raise FileNotFoundError( 90 f"Unable to find configuration yaml file: {config_path}." 91 ) 92 93 logger.debug(f"Running generator for {config_path}.") 94 output_root = artman.Artman().run( 95 f"googleapis/artman:{artman.ARTMAN_VERSION}", 96 self.discovery_artifact_manager, 97 config_path, 98 gapic_language_arg, 99 ) 100 101 # Expect the output to be in the artman-genfiles directory. 102 # example: /artman-genfiles/python/speech-v1 103 if artman_output_name is None: 104 artman_output_name = f"{service}-{version}" 105 genfiles = output_root / gen_language / artman_output_name 106 107 if not genfiles.exists(): 108 raise FileNotFoundError( 109 f"Unable to find generated output of artman: {genfiles}." 110 ) 111 112 logger.success(f"Generated code into {genfiles}.") 113 114 _tracked_paths.add(genfiles) 115 return genfiles 116 117 def _clone_discovery_artifact_manager(self): 118 logger.debug("Cloning discovery-artifact-manager.") 119 self.discovery_artifact_manager = git.clone(DISCOVERY_ARTIFACT_MANAGER_URL) 120