Skip to content

Commit 739ddbb

Browse files
authored
feat: generate selected libraries (#2598)
In this PR: - Generate a selected list of libraries based on `library_name` This PR is a preparation for improve nightly generation. Note that we need to change the [new library generation workflow](https://github.com/googleapis/google-cloud-java/blob/main/.github/workflows/generate_new_client_hermetic_build.yaml) in google-cloud-java to accommodate this change because `library_generation/generate_repo.py` has replaced `--target-library-api-shortname` with `--target-library-names`.
1 parent e3d35d1 commit 739ddbb

File tree

3 files changed

+117
-23
lines changed

3 files changed

+117
-23
lines changed

library_generation/generate_repo.py

+53-18
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
import click
1716
import library_generation.utilities as util
17+
import click
1818
import os
1919
from library_generation.generate_composed_library import generate_composed_library
20+
from library_generation.model.generation_config import GenerationConfig
2021
from library_generation.model.generation_config import from_yaml
22+
from library_generation.model.library_config import LibraryConfig
2123
from library_generation.utils.monorepo_postprocessor import monorepo_postprocessing
2224

2325

@@ -39,13 +41,22 @@ def main(ctx):
3941
""",
4042
)
4143
@click.option(
42-
"--target-library-api-shortname",
44+
"--target-library-names",
4345
required=False,
46+
default=None,
4447
type=str,
4548
help="""
46-
If specified, only the `library` whose api_shortname equals to
47-
target-library-api-shortname will be generated.
49+
A list of libraries will be generated.
50+
51+
If specified, only the `library` whose library_name is in
52+
target-library-names will be generated.
4853
If not specified, all libraries in the configuration yaml will be generated.
54+
55+
The input string will be parsed to a list of string with comma as the
56+
separator.
57+
58+
For example, apigeeconnect,alloydb-connectors will be parsed as a
59+
list of two strings, apigeeconnect and alloydb-connectors.
4960
""",
5061
)
5162
@click.option(
@@ -61,39 +72,46 @@ def main(ctx):
6172
)
6273
def generate(
6374
generation_config_yaml: str,
64-
target_library_api_shortname: str,
75+
target_library_names: str,
6576
repository_path: str,
6677
):
6778
generate_from_yaml(
6879
generation_config_yaml=generation_config_yaml,
6980
repository_path=repository_path,
70-
target_library_api_shortname=target_library_api_shortname,
81+
target_library_names=target_library_names.split(",")
82+
if target_library_names is not None
83+
else target_library_names,
7184
)
7285

7386

7487
def generate_from_yaml(
7588
generation_config_yaml: str,
7689
repository_path: str,
77-
target_library_api_shortname: str = None,
90+
target_library_names: list[str] = None,
7891
) -> None:
7992
"""
8093
Parses a config yaml and generates libraries via
8194
generate_composed_library.py
95+
:param generation_config_yaml: Path to generation_config.yaml that contains
96+
the metadata about library generation
97+
:param repository_path: If specified, the generated files will be sent to
98+
this location. If not specified, the repository will be generated to the
99+
current working directory.
100+
:param target_library_names: a list of libraries to be generated.
101+
If specified, only the library whose library_name is in
102+
target-library-names will be generated.
103+
If specified with an empty list, then no library will be generated.
104+
If not specified, all libraries in the configuration yaml will be generated.
82105
"""
83-
# convert paths to absolute paths so they can be correctly referenced in
106+
# convert paths to absolute paths, so they can be correctly referenced in
84107
# downstream scripts
85108
generation_config_yaml = os.path.abspath(generation_config_yaml)
86109
repository_path = os.path.abspath(repository_path)
87110

88111
config = from_yaml(generation_config_yaml)
89-
target_libraries = config.libraries
90-
if target_library_api_shortname is not None:
91-
target_libraries = [
92-
library
93-
for library in config.libraries
94-
if library.api_shortname == target_library_api_shortname
95-
]
96-
112+
target_libraries = get_target_libraries(
113+
config=config, target_library_names=target_library_names
114+
)
97115
repo_config = util.prepare_repo(
98116
gen_config=config, library_config=target_libraries, repo_path=repository_path
99117
)
@@ -118,5 +136,22 @@ def generate_from_yaml(
118136
)
119137

120138

121-
if __name__ == "__main__":
122-
main()
139+
def get_target_libraries(
140+
config: GenerationConfig, target_library_names: list[str] = None
141+
) -> list[LibraryConfig]:
142+
"""
143+
Returns LibraryConfig objects whose library_name is in target_library_names.
144+
145+
:param config: a GenerationConfig object.
146+
:param target_library_names: library_name of target libraries.
147+
If not specified, all libraries in the given config will be returned.
148+
:return: LibraryConfig objects.
149+
"""
150+
if target_library_names is None:
151+
return config.libraries
152+
target_libraries = set(target_library_names)
153+
return [
154+
library
155+
for library in config.libraries
156+
if library.get_library_name() in target_libraries
157+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env python3
2+
# Copyright 2024 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
import unittest
16+
17+
from library_generation.generate_repo import get_target_libraries
18+
from library_generation.model.generation_config import GenerationConfig
19+
from library_generation.model.library_config import LibraryConfig
20+
21+
22+
class GenerateRepoTest(unittest.TestCase):
23+
def test_get_target_library_returns_selected_libraries(self):
24+
one_library = GenerateRepoTest.__get_an_empty_library_config()
25+
one_library.api_shortname = "one_library"
26+
another_library = GenerateRepoTest.__get_an_empty_library_config()
27+
another_library.api_shortname = "another_library"
28+
config = GenerateRepoTest.__get_an_empty_generation_config()
29+
config.libraries.extend([one_library, another_library])
30+
target_libraries = get_target_libraries(config, ["another_library"])
31+
self.assertEqual([another_library], target_libraries)
32+
33+
def test_get_target_library_given_null_returns_all_libraries(self):
34+
one_library = GenerateRepoTest.__get_an_empty_library_config()
35+
one_library.api_shortname = "one_library"
36+
another_library = GenerateRepoTest.__get_an_empty_library_config()
37+
another_library.api_shortname = "another_library"
38+
config = GenerateRepoTest.__get_an_empty_generation_config()
39+
config.libraries.extend([one_library, another_library])
40+
target_libraries = get_target_libraries(config)
41+
self.assertEqual([one_library, another_library], target_libraries)
42+
43+
@staticmethod
44+
def __get_an_empty_generation_config() -> GenerationConfig:
45+
return GenerationConfig(
46+
gapic_generator_version="",
47+
googleapis_commitish="",
48+
synthtool_commitish="",
49+
owlbot_cli_image="",
50+
template_excludes=[],
51+
path_to_yaml="",
52+
libraries=[],
53+
)
54+
55+
@staticmethod
56+
def __get_an_empty_library_config() -> LibraryConfig:
57+
return LibraryConfig(
58+
api_shortname="",
59+
name_pretty="",
60+
api_description="",
61+
product_documentation="",
62+
gapic_configs=[],
63+
)

library_generation/utilities.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,7 @@ def prepare_repo(
131131
os.makedirs(output_folder, exist_ok=True)
132132
libraries = {}
133133
for library in library_config:
134-
library_name = (
135-
f"{language}-{library.library_name}"
136-
if library.library_name
137-
else f"{language}-{library.api_shortname}"
138-
)
134+
library_name = f"{language}-{library.get_library_name()}"
139135
library_path = (
140136
f"{repo_path}/{library_name}" if gen_config.is_monorepo else f"{repo_path}"
141137
)

0 commit comments

Comments
 (0)