Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a CLI tool to validate generation configuration #2691

Merged
merged 11 commits into from
Apr 26, 2024

Conversation

JoeWang1127
Copy link
Collaborator

@JoeWang1127 JoeWang1127 commented Apr 25, 2024

In this PR:

  • Add a CLI tool to validate generation config.

Downstream libraries, e.g., google-cloud-java, can write a workflow job like:

docker run ...
 python /src/cli/entry_point.py \
 validate-generation-config \
 --generation-config-path=path/to/generation_config.yaml

@product-auto-label product-auto-label bot added the size: m Pull request size is medium. label Apr 25, 2024
@@ -130,10 +130,6 @@ def prepare_repo(
# use absolute path because docker requires absolute path
# in volume name.
absolute_library_path = str(Path(library_path).resolve())
if absolute_library_path in libraries:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this check because the Generation object is validated when reaches this point.

@JoeWang1127 JoeWang1127 marked this pull request as ready for review April 25, 2024 20:20
@JoeWang1127 JoeWang1127 requested a review from a team as a code owner April 25, 2024 20:20
@JoeWang1127 JoeWang1127 changed the title feat: add config check feat: add a generation config validation CLI tool Apr 25, 2024
@JoeWang1127 JoeWang1127 changed the title feat: add a generation config validation CLI tool feat: add a CLI tool to validate generation configuration Apr 25, 2024
library_name = library.get_library_name()
if library_name in seen_library_names:
raise ValueError(
f"{library.name_pretty} has the same library name with "
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make the error message more verbose and actionable? Something like

f"Both {library.name_pretty} and {seen_library_names.get(library_name)} have the same library_name: 
{library_name}, please update one of the library to have a different library_name."

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another edge case is that two libraries may have the same name_pretty, but I think the error message is already good enough, so we may not have to consider it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -130,7 +142,9 @@ def from_yaml(path_to_yaml: str) -> GenerationConfig:

def __required(config: Dict, key: str):
if key not in config:
raise ValueError(f"required key {key} not found in yaml")
raise ValueError(
f"required key {key} not found in {config} " f"when parsing yaml"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is {config} going to print out the whole config? If yes, I don't think we want to do that. Something like

f"Required repo level config {key} not found"

should be good enough.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separately, there are a few library level required field, and I don't see any validation for them yet. They can be addressed in a separate PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remove config in the err message.

Separately, there are a few library level required field, and I don't see any validation for them yet. They can be addressed in a separate PR.

Library level required fields are tests in utilities_unit_tests.py. I moved it to generation_config_unit_test.py.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that library level config is validated in the same way as repo level config now. However, it makes the error message not clear for library level config. e.g. If api-shortname is missing for a specific library, we don't know which library is missing api-shortname from required key {key} not found.

@blakeli0
Copy link
Collaborator

How do we plan to use it? I think we can add it to the CI as a required check for every PR, as this should be a very lightweight check.

@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: m Pull request size is medium. labels Apr 25, 2024
@JoeWang1127
Copy link
Collaborator Author

JoeWang1127 commented Apr 25, 2024

How do we plan to use it? I think we can add it to the CI as a required check for every PR, as this should be a very lightweight check.

Yes, the check should be finished quickly. I tested with generation_config.yaml in google-cloud-java and it finished in 0.3s:

(.venv) joewa-macbookpro:sdk-platform-java joewa$ time python library_generation/cli/entry_point.py validate-generation-config --generation-config-path=../google-cloud-java/generation_config.yaml

real    0m0.299s
user    0m0.161s
sys     0m0.052s

I added how to use the check in the description.

@JoeWang1127 JoeWang1127 added the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 26, 2024
@gcf-owl-bot gcf-owl-bot bot removed the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 26, 2024
@JoeWang1127 JoeWang1127 added the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 26, 2024
@gcf-owl-bot gcf-owl-bot bot removed the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 26, 2024
@JoeWang1127 JoeWang1127 added the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 26, 2024
@gcf-owl-bot gcf-owl-bot bot removed the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 26, 2024
Copy link
Collaborator

@blakeli0 blakeli0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the command just be

docker run ...
 python /src/cli/entry_point.py validate-generation-config

without specifying the yaml location? I think it should be fine since we have a default location?

# be raised.
@parameterized.expand(
[
("libraries", f"{test_config_dir}/config_without_libraries.yaml"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not a fan of parameterized tests, but I know this test was pre-existing, and in this case, the name of test yamls are kind of self-explanatory, so it's fine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced this parameterized test to several individual tests.

@@ -130,7 +142,9 @@ def from_yaml(path_to_yaml: str) -> GenerationConfig:

def __required(config: Dict, key: str):
if key not in config:
raise ValueError(f"required key {key} not found in yaml")
raise ValueError(
f"required key {key} not found in {config} " f"when parsing yaml"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that library level config is validated in the same way as repo level config now. However, it makes the error message not clear for library level config. e.g. If api-shortname is missing for a specific library, we don't know which library is missing api-shortname from required key {key} not found.

@JoeWang1127
Copy link
Collaborator Author

Can the command just be

docker run ...
 python /src/cli/entry_point.py validate-generation-config

without specifying the yaml location? I think it should be fine since we have a default location?

Yes, if the yaml location is not specified, the default value is generation_config.yaml in the current working directory.

@JoeWang1127
Copy link
Collaborator Author

I see that library level config is validated in the same way as repo level config now. However, it makes the error message not clear for library level config. e.g. If api-shortname is missing for a specific library, we don't know which library is missing api-shortname from required key {key} not found.

I added a parameter, level, so that library config is shown in the raised exception. Missing a repo level parameter will not print the whole config (existing behavior).

@blakeli0
Copy link
Collaborator

I see that library level config is validated in the same way as repo level config now. However, it makes the error message not clear for library level config. e.g. If api-shortname is missing for a specific library, we don't know which library is missing api-shortname from required key {key} not found.

I added a parameter, level, so that library config is shown in the raised exception. Missing a repo level parameter will not print the whole config (existing behavior).

The main concern is not that we don't know if the config is at library or repo level, the concern is that we don't know which library is missing a config if it's a library level config.

@JoeWang1127
Copy link
Collaborator Author

The main concern is not that we don't know if the config is at library or repo level, the concern is that we don't know which library is missing a config if it's a library level config.

When parsing from yaml, we don't know which parameter maybe missing so I think the best we can do is printing the library dict and hopefully some of the values can let us find which library is missing parameter.

Copy link
Collaborator

@blakeli0 blakeli0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than one minor issue for unit test. Separately I think we should error out on unknown parameters, which I don't think we are doing currently.

@JoeWang1127
Copy link
Collaborator Author

Separately I think we should error out on unknown parameters, which I don't think we are doing currently.

I'll address this issue in a follow-up PR.

Copy link

sonarcloud bot commented Apr 26, 2024

Quality Gate Passed Quality Gate passed for 'gapic-generator-java-root'

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarCloud

Copy link

sonarcloud bot commented Apr 26, 2024

Please retry analysis of this Pull-Request directly on SonarCloud

Copy link

sonarcloud bot commented Apr 26, 2024

Quality Gate Passed Quality Gate passed for 'java_showcase_integration_tests'

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarCloud

@JoeWang1127 JoeWang1127 enabled auto-merge (squash) April 26, 2024 22:14
@JoeWang1127 JoeWang1127 merged commit f2ce524 into main Apr 26, 2024
29 checks passed
@JoeWang1127 JoeWang1127 deleted the feat/add-config-check branch April 26, 2024 22:46
alicejli pushed a commit that referenced this pull request May 2, 2024
🤖 I have created a release *beep* *boop*
---


<details><summary>2.40.0</summary>

##
[2.40.0](v2.39.0...v2.40.0)
(2024-05-02)


### Features

* [common-protos] add `Weight` to common types for Shopping APIs to be
used for accounts bundle
([#2699](#2699))
([5bb9770](5bb9770))
* add a CLI tool to validate generation configuration
([#2691](#2691))
([f2ce524](f2ce524))
* Parser to consume the api-versioning value from proto
([#2630](#2630))
([40711fd](40711fd))
* Update Gapic generator and Gax to emit api-versioning via header
([#2671](#2671))
([e63d1b4](e63d1b4))


### Bug Fixes

* change folder prefix for adding headers
([#2688](#2688))
([4e92be8](4e92be8))
* Log HttpJson's async thread pool core size
([#2697](#2697))
([34b4bc3](34b4bc3))
* replace `cfg = "host"` with `cfg = "exec"`
([#2637](#2637))
([6d673f3](6d673f3))
* Return resolved endpoint from StubSettings' Builder
([#2715](#2715))
([32c9995](32c9995))


### Dependencies

* Make opentelemetry-api an optional dependency.
([#2681](#2681))
([3967a19](3967a19))
* update dependency absl-py to v2.1.0
([#2659](#2659))
([cae6d79](cae6d79))
* update dependency gitpython to v3.1.43
([#2656](#2656))
([208bef4](208bef4))
* update dependency lxml to v5.2.1
([#2661](#2661))
([b95ad49](b95ad49))
* update dependency net.bytebuddy:byte-buddy to v1.14.14
([#2703](#2703))
([87069bc](87069bc))
* update dependency typing to v3.10.0.0
([#2663](#2663))
([7fb5653](7fb5653))
* update gapic-showcase to v0.33.0
([#2653](#2653))
([0a71cbf](0a71cbf))


### Documentation

* Add contributing guidelines to PR and issue templates
([#2682](#2682))
([42526dc](42526dc))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
lqiu96 pushed a commit that referenced this pull request May 22, 2024
In this PR:
- Add a CLI tool to validate generation config.

Downstream libraries, e.g., google-cloud-java, can write a workflow job
like:
```
docker run ...
 python /src/cli/entry_point.py \
 validate-generation-config \
 --generation-config-path=path/to/generation_config.yaml
```
lqiu96 pushed a commit that referenced this pull request May 22, 2024
🤖 I have created a release *beep* *boop*
---


<details><summary>2.40.0</summary>

##
[2.40.0](v2.39.0...v2.40.0)
(2024-05-02)


### Features

* [common-protos] add `Weight` to common types for Shopping APIs to be
used for accounts bundle
([#2699](#2699))
([5bb9770](5bb9770))
* add a CLI tool to validate generation configuration
([#2691](#2691))
([f2ce524](f2ce524))
* Parser to consume the api-versioning value from proto
([#2630](#2630))
([40711fd](40711fd))
* Update Gapic generator and Gax to emit api-versioning via header
([#2671](#2671))
([e63d1b4](e63d1b4))


### Bug Fixes

* change folder prefix for adding headers
([#2688](#2688))
([4e92be8](4e92be8))
* Log HttpJson's async thread pool core size
([#2697](#2697))
([34b4bc3](34b4bc3))
* replace `cfg = "host"` with `cfg = "exec"`
([#2637](#2637))
([6d673f3](6d673f3))
* Return resolved endpoint from StubSettings' Builder
([#2715](#2715))
([32c9995](32c9995))


### Dependencies

* Make opentelemetry-api an optional dependency.
([#2681](#2681))
([3967a19](3967a19))
* update dependency absl-py to v2.1.0
([#2659](#2659))
([cae6d79](cae6d79))
* update dependency gitpython to v3.1.43
([#2656](#2656))
([208bef4](208bef4))
* update dependency lxml to v5.2.1
([#2661](#2661))
([b95ad49](b95ad49))
* update dependency net.bytebuddy:byte-buddy to v1.14.14
([#2703](#2703))
([87069bc](87069bc))
* update dependency typing to v3.10.0.0
([#2663](#2663))
([7fb5653](7fb5653))
* update gapic-showcase to v0.33.0
([#2653](#2653))
([0a71cbf](0a71cbf))


### Documentation

* Add contributing guidelines to PR and issue templates
([#2682](#2682))
([42526dc](42526dc))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: l Pull request size is large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants