Skip to content

Commit dfe1a50

Browse files
authored
feat: selectively generate libraries (#3290)
In this PR: - Allow selectively generate libraries by adding `--library-names` to CLI. We have a request of partially releasing google-cloud-java (b/331628538), which requires only generating a selective list of libraries. This change allows a user-defined list of libraries to be generated even if the corresponding library configs are the same.
1 parent 771bd0e commit dfe1a50

File tree

6 files changed

+351
-13
lines changed

6 files changed

+351
-13
lines changed

library_generation/cli/entry_point.py

+45-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414
import os
1515
import sys
16-
16+
from typing import Optional
1717
import click as click
1818
from library_generation.generate_pr_description import generate_pr_descriptions
1919
from library_generation.generate_repo import generate_from_yaml
@@ -51,6 +51,17 @@ def main(ctx):
5151
metadata about library generation.
5252
""",
5353
)
54+
@click.option(
55+
"--library-names",
56+
type=str,
57+
default=None,
58+
show_default=True,
59+
help="""
60+
A list of library names that will be generated, separated by comma.
61+
The library name of a library is the value of library_name or api_shortname,
62+
if library_name is not specified, in the generation configuration.
63+
""",
64+
)
5465
@click.option(
5566
"--repository-path",
5667
type=str,
@@ -77,6 +88,7 @@ def main(ctx):
7788
def generate(
7889
baseline_generation_config_path: str,
7990
current_generation_config_path: str,
91+
library_names: Optional[str],
8092
repository_path: str,
8193
api_definitions_path: str,
8294
):
@@ -86,24 +98,32 @@ def generate(
8698
history.
8799
88100
If baseline generation config is not specified but current generation
89-
config is specified, generate all libraries based on current generation
90-
config without commit history.
101+
config is specified, generate all libraries if `library_names` is not
102+
specified, based on current generation config without commit history.
91103
92104
If current generation config is not specified but baseline generation
93105
config is specified, raise FileNotFoundError because current generation
94106
config should be the source of truth of library generation.
95107
96108
If both baseline generation config and current generation config are not
97109
specified, generate all libraries based on the default generation config,
98-
which is generation_config.yaml in the current working directory. Raise
99-
FileNotFoundError if the default config does not exist.
110+
which is generation_config.yaml in the current working directory.
111+
112+
If `library_names` is specified, only libraries whose name can be found in
113+
the current generation config or default generation config, if current
114+
generation config is not specified, will be generated. Changed libraries
115+
will be ignored even if baseline and current generation config are
116+
specified.
117+
118+
Raise FileNotFoundError if the default config does not exist.
100119
101120
The commit history, if generated, will be available in
102121
repository_path/pr_description.txt.
103122
"""
104123
__generate_repo_and_pr_description_impl(
105124
baseline_generation_config_path=baseline_generation_config_path,
106125
current_generation_config_path=current_generation_config_path,
126+
library_names=library_names,
107127
repository_path=repository_path,
108128
api_definitions_path=api_definitions_path,
109129
)
@@ -112,6 +132,7 @@ def generate(
112132
def __generate_repo_and_pr_description_impl(
113133
baseline_generation_config_path: str,
114134
current_generation_config_path: str,
135+
library_names: Optional[str],
115136
repository_path: str,
116137
api_definitions_path: str,
117138
):
@@ -146,30 +167,39 @@ def __generate_repo_and_pr_description_impl(
146167
current_generation_config_path = os.path.abspath(current_generation_config_path)
147168
repository_path = os.path.abspath(repository_path)
148169
api_definitions_path = os.path.abspath(api_definitions_path)
170+
include_library_names = _parse_library_name_from(library_names)
171+
149172
if not baseline_generation_config_path:
150-
# Execute full generation based on current_generation_config if
173+
# Execute selective generation based on current_generation_config if
151174
# baseline_generation_config is not specified.
152175
# Do not generate pull request description.
153176
generate_from_yaml(
154177
config=from_yaml(current_generation_config_path),
155178
repository_path=repository_path,
156179
api_definitions_path=api_definitions_path,
180+
target_library_names=include_library_names,
157181
)
158182
return
159183

160-
# Compare two generation configs and only generate changed libraries.
184+
# Compare two generation configs to get changed libraries.
161185
# Generate pull request description.
162186
baseline_generation_config_path = os.path.abspath(baseline_generation_config_path)
163187
config_change = compare_config(
164188
baseline_config=from_yaml(baseline_generation_config_path),
165189
current_config=from_yaml(current_generation_config_path),
166190
)
167-
# pass None if we want to fully generate the repository.
168-
target_library_names = (
191+
# Pass None if we want to fully generate the repository.
192+
changed_library_names = (
169193
config_change.get_changed_libraries()
170194
if not _needs_full_repo_generation(config_change=config_change)
171195
else None
172196
)
197+
# Include library names takes preference if specified.
198+
target_library_names = (
199+
include_library_names
200+
if include_library_names is not None
201+
else changed_library_names
202+
)
173203
generate_from_yaml(
174204
config=config_change.current_config,
175205
repository_path=repository_path,
@@ -191,6 +221,12 @@ def _needs_full_repo_generation(config_change: ConfigChange) -> bool:
191221
return not current_config.is_monorepo() or current_config.contains_common_protos()
192222

193223

224+
def _parse_library_name_from(includes: str) -> Optional[list[str]]:
225+
if includes is None:
226+
return None
227+
return [library_name.strip() for library_name in includes.split(",")]
228+
229+
194230
@main.command()
195231
@click.option(
196232
"--generation-config-path",

library_generation/generate_repo.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
15-
import os
1615
import shutil
17-
16+
from typing import Optional
1817
import library_generation.utils.utilities as util
1918
from library_generation.generate_composed_library import generate_composed_library
2019
from library_generation.model.generation_config import GenerationConfig
@@ -26,7 +25,7 @@ def generate_from_yaml(
2625
config: GenerationConfig,
2726
repository_path: str,
2827
api_definitions_path: str,
29-
target_library_names: list[str] = None,
28+
target_library_names: Optional[list[str]],
3029
) -> None:
3130
"""
3231
Based on the generation config, generates libraries via

0 commit comments

Comments
 (0)