Skip to content

Commit b19fa33

Browse files
authored
feat: add entry point (#2616)
In this PR: - Create `entry_point.py` to combine `generate_repo.py` and `generate_pr_description.py`. - Change Integration test. Follow up of #2604. For the goal of series of PRs, please refer to [improvement proposal](https://docs.google.com/document/d/1JiCcG3X7lnxaJErKe0ES_JkyU7ECb40nf2Xez3gWvuo/edit?tab=t.g3vua2kd06gx#bookmark=id.72s3ukwwzevo).
1 parent 56775a6 commit b19fa33

14 files changed

+536
-244
lines changed

library_generation/README.md

+30-23
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Generate a repository containing GAPIC Client Libraries
22

3-
The script, `generate_repo.py`, allows you to generate a repository containing
4-
GAPIC client libraries (a monorepo, for example, google-cloud-java) from a
5-
configuration file.
3+
The script, `entry_point.py`, allows you to generate a repository containing
4+
GAPIC client libraries with googleapis commit history (a monorepo, for example,
5+
google-cloud-java) from a configuration file.
66

77
## Environment
88

@@ -17,30 +17,27 @@ In order to generate a version for each library, a versions.txt has to exist
1717
in `repository_path`.
1818
Please refer to [Repository path](#repository-path--repositorypath---optional) for more information.
1919

20-
## Parameters to generate a repository using `generate_repo.py`
20+
## Parameters to generate a repository using `entry_point.py`
2121

22-
### Generation configuration yaml (`generation_config_yaml`)
22+
### Baseline generation configuration yaml (`baseline_generation_config`)
2323

24-
A path to a configuration file containing parameters to generate the repository.
25-
Please refer [Configuration to generate a repository](#configuration-to-generate-a-repository)
26-
for more information.
27-
28-
### Target library API shortname (`target_library_api_shortname`), optional
24+
An absolute or relative path to a generation_config.yaml.
25+
This config file is used for commit history generation, not library
26+
generation.
2927

30-
If specified, the libray whose `api_shortname` equals to `target_library_api_shortname`
31-
will be generated; otherwise all libraries in the configuration file will be
32-
generated.
33-
This can be useful when you just want to generate one library for debugging
34-
purposes.
28+
### Current generation configuration yaml (`current_generation_config`)
3529

36-
The default value is an empty string, which means all libraries will be generated.
30+
An absolute or relative path to a configuration file containing parameters to
31+
generate the repository.
32+
Please refer [Configuration to generate a repository](#configuration-to-generate-a-repository)
33+
for more information.
3734

3835
### Repository path (`repository_path`), optional
3936

4037
The path to where the generated repository goes.
4138

4239
The default value is the current working directory when running the script.
43-
For example, `cd google-cloud-java && python generate_repo.py ...` without
40+
For example, `cd google-cloud-java && python entry_point.py ...` without
4441
specifying the `--repository_path` option will modify the `google-cloud-java`
4542
repository the user `cd`'d into.
4643

@@ -49,7 +46,9 @@ right version for each library.
4946
Please refer [here](go/java-client-releasing#versionstxt-manifest) for more info
5047
of versions.txt.
5148

52-
## Output of `generate_repo.py`
49+
## Output of `entry_point.py`
50+
51+
### GAPIC libraries
5352

5453
For each module (e.g. `google-cloud-java/java-asset`), the following files/folders
5554
will be created/modified:
@@ -73,6 +72,11 @@ will be created/modified:
7372
| pom.xml (repo root dir) | Always generated from inputs |
7473
| versions.txt | New entries will be added if they don’t exist |
7574

75+
### googleapis commit history
76+
77+
If both `baseline_generation_config` and `current_generation_config` are
78+
specified, and they contain different googleapis commit, the commit history will
79+
be generated into `pr_description.txt` in the `repository_path`.
7680

7781
## Configuration to generate a repository
7882

@@ -184,20 +188,23 @@ libraries:
184188
- proto_path: google/cloud/asset/v1p7beta1
185189
```
186190
187-
## An example to generate a repository using `generate_repo.py`
191+
## An example to generate a repository using `entry_point.py`
188192

189193
```bash
190194
# install python module (allows the `library_generation` module to be imported from anywhere)
191195
python -m pip install -r library_generation/requirements.in
196+
# install library_generation module
197+
python -m pip install library_generation
192198
# generate the repository
193-
python -m library_generation/generate_repo.py generate \
194-
--generation-config-yaml=/path/to/config-file \
199+
python -m library_generation/entry_point.py generate \
200+
--baseline-generation-config=/path/to/baseline_config_file \
201+
--current-generation-config=/path/to/current_config_file \
195202
--repository-path=/path/to/repository
196203
```
197204

198-
## An example of generated repository using `generate_repo.py`
205+
## An example of generated repository using `entry_point.py`
199206

200-
If you run `generate_repo.py` with the example [configuration](#an-example-of-generation-configuration)
207+
If you run `entry_point.py` with the example [configuration](#an-example-of-generation-configuration)
201208
shown above, the repository structure is:
202209
```
203210
$repository_path

library_generation/cli/entry_point.py

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Copyright 2024 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+
import os
15+
16+
import click as click
17+
from library_generation.generate_pr_description import generate_pr_descriptions
18+
from library_generation.generate_repo import generate_from_yaml
19+
from library_generation.model.generation_config import from_yaml
20+
from library_generation.utils.generation_config_comparator import compare_config
21+
22+
23+
@click.group(invoke_without_command=False)
24+
@click.pass_context
25+
@click.version_option(message="%(version)s")
26+
def main(ctx):
27+
pass
28+
29+
30+
@main.command()
31+
@click.option(
32+
"--baseline-generation-config",
33+
required=False,
34+
default=None,
35+
type=str,
36+
help="""
37+
Absolute or relative path to a generation_config.yaml.
38+
This config file is used for commit history generation, not library
39+
generation.
40+
""",
41+
)
42+
@click.option(
43+
"--current-generation-config",
44+
required=False,
45+
default=None,
46+
type=str,
47+
help="""
48+
Absolute or relative path to a generation_config.yaml that contains the
49+
metadata about library generation.
50+
""",
51+
)
52+
@click.option(
53+
"--repository-path",
54+
type=str,
55+
default=".",
56+
show_default=True,
57+
help="""
58+
The repository path to which the generated files
59+
will be sent.
60+
If not specified, the repository will be generated to the current working
61+
directory.
62+
""",
63+
)
64+
def generate(
65+
baseline_generation_config: str,
66+
current_generation_config: str,
67+
repository_path: str,
68+
):
69+
"""
70+
Compare baseline generation config and current generation config and
71+
generate changed libraries based on current generation config with commit
72+
history.
73+
74+
If baseline generation config is not specified but current generation
75+
config is specified, generate all libraries based on current generation
76+
config without commit history.
77+
78+
If current generation config is not specified but baseline generation
79+
config is specified, raise FileNotFoundError because current generation
80+
config should be the source of truth of library generation.
81+
82+
If both baseline generation config and current generation config are not
83+
specified, generate all libraries based on the default generation config,
84+
which is generation_config.yaml in the current working directory. Raise
85+
FileNotFoundError if the default config does not exist.
86+
87+
The commit history, if generated, will be available in
88+
repository_path/pr_description.txt.
89+
"""
90+
default_generation_config = f"{os.getcwd()}/generation_config.yaml"
91+
92+
if baseline_generation_config is None and current_generation_config is None:
93+
if not os.path.isfile(default_generation_config):
94+
raise FileNotFoundError(
95+
f"{default_generation_config} does not exist. "
96+
"A valid generation config has to be passed in as "
97+
"current_generation_config or exist in the current working "
98+
"directory."
99+
)
100+
current_generation_config = default_generation_config
101+
elif current_generation_config is None:
102+
raise FileNotFoundError(
103+
"current_generation_config is not specified when "
104+
"baseline_generation_config is specified. "
105+
"current_generation_config should be the source of truth of "
106+
"library generation."
107+
)
108+
109+
current_generation_config = os.path.abspath(current_generation_config)
110+
repository_path = os.path.abspath(repository_path)
111+
if not baseline_generation_config:
112+
# Execute full generation based on current_generation_config if
113+
# baseline_generation_config is not specified.
114+
# Do not generate pull request description.
115+
generate_from_yaml(
116+
config=from_yaml(current_generation_config),
117+
repository_path=repository_path,
118+
)
119+
return
120+
121+
# Compare two generation configs and only generate changed libraries.
122+
# Generate pull request description.
123+
baseline_generation_config = os.path.abspath(baseline_generation_config)
124+
config_change = compare_config(
125+
baseline_config=from_yaml(baseline_generation_config),
126+
current_config=from_yaml(current_generation_config),
127+
)
128+
generate_from_yaml(
129+
config=config_change.current_config,
130+
repository_path=repository_path,
131+
target_library_names=config_change.get_changed_libraries(),
132+
)
133+
generate_pr_descriptions(
134+
config=config_change.current_config,
135+
baseline_commit=config_change.baseline_config.googleapis_commitish,
136+
description_path=repository_path,
137+
)
138+
139+
140+
if __name__ == "__main__":
141+
main()

0 commit comments

Comments
 (0)