Skip to content

Commit 2984467

Browse files
authored
docs: howto find missing service protos (#14139)
1 parent 90aa011 commit 2984467

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# How-to Guide: Find missing service proto files
2+
3+
Some of the generated libraries include multiple gRPC services. Some directories
4+
in `googleapis/googleapis` include multiple services in a single `.proto` file.
5+
Some directories add new `.proto` files, and the expectation is that all these
6+
proto files are included in the same "package" or "library".
7+
8+
Most of the time we get a feature request to add new libraries. We rarely get
9+
such a bug for new `.proto` files, because for other languages the automation
10+
detects these and adds them as needed.
11+
12+
Fixing our processes and automation to detect these new `.proto` files would be
13+
ideal. Until that happens, we need to periodically detect if new protos must be
14+
included in a library.
15+
16+
We can find these with a few commands.
17+
18+
First use Bazel to compile `//:grpc_utils`. That will force Bazel to download
19+
the version of `googleapis/googleapis` defined in our repo:
20+
21+
```shell
22+
bazel build //:grpc_utils
23+
```
24+
25+
Next find out where bazel downloaded the code:
26+
27+
```shell
28+
googleapis="$(bazel info output_base)/external/com_google_googleapis/"
29+
```
30+
31+
At this point we can run a "one liner" to find the mismatched repos:
32+
33+
```shell
34+
time comm -23 \
35+
<(git ls-files -- 'external/googleapis/protolists/*.list' | \
36+
xargs sed -e 's;@com_google_googleapis//;;' -e 's;:;/;' | \
37+
xargs env -C ${googleapis} grep -l '^service ' | sort) \
38+
<(sed -n '/service_proto_path:/ {s/.*_path: "//; s/"//p}' generator/generator_config.textproto | sort)
39+
```
40+
41+
Once you have identified missing `*.proto` files, follow the
42+
[Adding generated libraries] guide to add these protos to an existing library.
43+
44+
## Explanation
45+
46+
We make the following assumptions, based on how we maintain the repository:
47+
48+
1. Recall that all the libraries we generate are based on `*_cc_grpc` targets in
49+
`googleapis/googleapis`.
50+
1. Recall that we do only generate libraries for a subset of the `*_cc_grpc`
51+
targets, e.g., we only include Cloud services.
52+
1. We are interested in any `*.proto` file that is needed by a `*_cc_grpc`
53+
target we *already have*, but that is not referenced from the
54+
`generator_config.textproto` file.
55+
1. Recall that the list of `*.proto` file dependencies are in our `*.list`
56+
files. These files are automatically generated (see [`update_libraries.sh`]).
57+
1. By convention / coding standards, all service definitions in the Google
58+
`*.proto` files start at column 0 with `service `.
59+
60+
With these assumptions, we can explain how the script works. First gather all
61+
the `*.list` files:
62+
63+
```shell
64+
git ls-files -- 'external/googleapis/protolists/*.list'
65+
```
66+
67+
Each file contains proto *targets*, we convert this list to just the relative
68+
path of each `*.proto` file:
69+
70+
```shell
71+
git ls-files -- 'external/googleapis/protolists/*.list' | \
72+
xargs sed -e 's;@com_google_googleapis//;;' -e 's;:;/;'
73+
```
74+
75+
Now we can search for any files that have a gRPC service definition:
76+
77+
```shell
78+
git ls-files -- 'external/googleapis/protolists/*.list' | \
79+
xargs sed -e 's;@com_google_googleapis//;;' -e 's;:;/;' | \
80+
xargs env -C ${googleapis} grep -l '^service '
81+
```
82+
83+
And we sort this list to make the comparison with a different list easy:
84+
85+
```shell
86+
git ls-files -- 'external/googleapis/protolists/*.list' | \
87+
xargs sed -e 's;@com_google_googleapis//;;' -e 's;:;/;' | \
88+
xargs env -C ${googleapis} grep -l '^service ' | sort
89+
```
90+
91+
Separately we build the list of protofiles that are listed in
92+
`generator_config.textproto`, and sort it for the same reasons:
93+
94+
```shell
95+
sed -n '/service_proto_path:/ {s/.*_path: "//; s/"//p}' generator/generator_config.textproto | sort
96+
```
97+
98+
Then just use `comm -23` to find the differences between these two lists.
99+
100+
```shell
101+
time comm -23 \
102+
<(git ls-files -- 'external/googleapis/protolists/*.list' | \
103+
xargs sed -e 's;@com_google_googleapis//;;' -e 's;:;/;' | \
104+
xargs env -C ${googleapis} grep -l '^service ' | sort) \
105+
<(sed -n '/service_proto_path:/ {s/.*_path: "//; s/"//p}' generator/generator_config.textproto | sort)
106+
```
107+
108+
[adding generated libraries]: /doc/contributor/howto-guide-adding-generated-libraries.md
109+
[`update_libraries.sh`]: /external/googleapis/update_libraries.sh

doc/contributor/howto-guide-update-googleapis-sha.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,22 @@ git push --set-upstream origin "$(git branch --show-current)"
4848

4949
Then use your favorite workflow to create the PR.
5050

51+
## Next Steps
52+
53+
Consider the output of the last command in this sequence. You may want to open
54+
bugs or PRs to add any new `*.proto` files to existing libraries.
55+
56+
```shell
57+
bazel build //:grpc_utils
58+
googleapis="$(bazel info output_base)/external/com_google_googleapis/"
59+
time comm -23 \
60+
<(git ls-files -- 'external/googleapis/protolists/*.list' | \
61+
xargs sed -e 's;@com_google_googleapis//;;' -e 's;:;/;' | \
62+
xargs env -C ${googleapis} grep -l '^service ' | sort) \
63+
<(sed -n '/service_proto_path:/ {s/.*_path: "//; s/"//p}' generator/generator_config.textproto | sort)
64+
```
65+
66+
See [Find missing service proto files] to find out how this command works.
67+
68+
[find missing service proto files]: /doc/contributor/howto-guide-find-missing-service-protos.md
5169
[googleapis-repo]: https://github.com/googleapis/googleapis.git

0 commit comments

Comments
 (0)