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

api: add go proto generation script #8155

Merged
merged 22 commits into from
Sep 19, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ cc_proto_library(

go_proto_library(
name = "gogo_proto_go",
importpath = "gogoproto",
importpath = "github.com/gogo/protobuf/gogoproto",
proto = ":gogo_proto",
visibility = ["//visibility:public"],
deps = [
Expand Down Expand Up @@ -113,7 +113,7 @@ api_proto_library(

go_proto_library(
name = "client_model_go_proto",
importpath = "client_model",
importpath = "github.com/prometheus/client_model/go",
proto = ":client_model",
visibility = ["//visibility:public"],
)
Expand Down
51 changes: 51 additions & 0 deletions tools/api/generate_go_protobuf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python
kyessenov marked this conversation as resolved.
Show resolved Hide resolved
from subprocess import check_output
kyessenov marked this conversation as resolved.
Show resolved Hide resolved
from subprocess import call

import glob
import os
import shutil
import sys

# Find the locations of the workspace root and the generated files directory.
workspace = check_output(['bazel', 'info', 'workspace']).strip()
bazel_bin = check_output(['bazel', 'info', 'bazel-bin']).strip()
targets = '@envoy_api//...'
import_base = 'github.com/envoyproxy/data-plane-api/api'
output_base = 'go_out'
kyessenov marked this conversation as resolved.
Show resolved Hide resolved

go_protos = check_output([
'bazel',
'query',
'kind("go_proto_library", %s)' % targets,
]).split()

# Each rule has the form @envoy_api//foo/bar:baz_go_proto.
# First build all the rules to ensure we have the output files.
if call(['bazel', 'build'] + go_protos) != 0:
print('Build failed')
sys.exit(1)

shutil.rmtree(os.path.join(workspace, output_base, 'envoy'), ignore_errors=True)
for rule in go_protos:
# Example rule:
# @envoy_api//envoy/config/bootstrap/v2:pkg_go_proto
#
# Example generated directory:
# bazel-bin/external/envoy_api/envoy/config/bootstrap/v2/linux_amd64_stripped/pkg_go_proto%/github.com/envoyproxy/data-plane-api/api/envoy/config/bootstrap/v2/
#
# Example output directory:
# go_out/envoy/config/bootstrap/v2
rule_dir, proto = rule[len("@envoy_api//"):].rsplit(':', 1)

input_dir = os.path.join(bazel_bin, 'external', 'envoy_api', rule_dir, 'linux_amd64_stripped',
Copy link
Member

Choose a reason for hiding this comment

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

This code is quite similar to https://github.com/envoyproxy/envoy/blob/master/docs/build.sh#L66. Is there a way to refactor to share, or maybe you can avoid reaching into amd64 named dirs somehow like we do for docs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

linux_amd64_stripped is specific to rules_go I think. It's not coming from bazel itself. I've tried to figure out how to get generated files with bazel query but eventually gave up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's due to compilation modes in go. It statically links everything, so it has to keep outputs in sub-directories https://github.com/bazelbuild/rules_go/blob/0303b3a69695e35940b09ddbf7a444bcc7fbefd4/go/private/mode.bzl.

Copy link
Member

Choose a reason for hiding this comment

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

Can you specify --strip=always or -c fastbuild when bazel build is invoked in line 25? Otherwise the directory name is interfered by .bazelrc (e.g. I have -c dbg in my bazelrc)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe it's better to recommend running this script with empty --bazelrc=/dev/null on linux amd64?
If you poke around the logic for the choice of the directory, it's pretty convoluted and interferes with msan/race/etc: https://github.com/bazelbuild/rules_go/blob/0303b3a69695e35940b09ddbf7a444bcc7fbefd4/go/private/mode.bzl#L135

Copy link
Member

Choose a reason for hiding this comment

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

yeah an empty bazelrc works too but I think that ignores workspace .bazelrc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, -c fastbuild is better than ignoring workspace bazel rc.

proto + '%', import_base, rule_dir)
input_files = glob.glob(os.path.join(input_dir, '*.go'))
output_dir = os.path.join(workspace, output_base, rule_dir)

# Ensure the output directory exists
if not os.path.exists(output_dir):
kyessenov marked this conversation as resolved.
Show resolved Hide resolved
os.makedirs(output_dir, 0o755)
for generated_file in input_files:
shutil.copy(generated_file, output_dir)
os.chmod(os.path.join(output_dir, generated_file), 0o644)
Copy link
Member

Choose a reason for hiding this comment

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

You could optionally just call rsync here.