Skip to content

api: add java proto options to avoid risk of future breakage#5764

Merged
htuch merged 13 commits intoenvoyproxy:masterfrom
dapengzhang0:outerclass
Feb 5, 2019
Merged

api: add java proto options to avoid risk of future breakage#5764
htuch merged 13 commits intoenvoyproxy:masterfrom
dapengzhang0:outerclass

Conversation

@dapengzhang0
Copy link
Contributor

Description: As discussed with @snowp in envoyproxy/java-control-plane#87 (comment) and envoyproxy/java-control-plane#87 (comment), adding these options will avoid the risk of having API breaking changes on the generated java code as the proto files evolve.

Risk Level: Medium
Note that e.g. envoyproxy/java-control-plane will have to do a refactoring when they sync the proto files next time.
Testing:
Docs Changes:
Release Notes:
[Optional Fixes #Issue] envoyproxy/java-control-plane#87
[Optional Deprecated:]

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
@snowp snowp self-requested a review January 29, 2019 22:32
@snowp snowp self-assigned this Jan 29, 2019
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

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

Thanks! Left a few comments to get you started


def checkJavaMultipleFilesProtoOption(file_path):
for line in fileinput.FileInput(file_path):
if "option java_multiple_files = " in line:
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe check that this is set to true? Or are there cases where you wouldn't want that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This only checks if the developer forgot to set it. If the developer sets it to false, that is unusual, might imply that they purposely want it to be false.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, makes sense


def checkJavaOuterClassnameProtoOption(file_path):
for line in fileinput.FileInput(file_path):
if "option java_outer_classname = " in line:
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be checking for the generated name? Does that matter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This allows purposely setting custom outer classname for some particular proto file. There's PRO and CON, but may not matter too much yet.


def fixJavaMultipleFilesProtoOption(file_path):
for line in fileinput.FileInput(file_path):
if "option java_multiple_files = " in line:
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, should this check for true?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same here, allow purposely setting it to false for some particular proto file.

if "option java_outer_classname = " in line:
return []

to_add = "option java_outer_classname = \"" + ''.join(
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybe split this line into two lines to make it easier to read?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.



def checkJavaProtoOptions(file_path):
# Add 'option java_outclass_name = FooBarProto' for foo_bar.proto
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: typo outclass -> outer_classname

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
snowp
snowp previously approved these changes Jan 30, 2019
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

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

Looks good, thanks!

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

Nice, solutions that automatically catch/fix breakages like this are the best.

syntax = "proto3";

package envoy.config.accesslog.v2;
option java_outer_classname = "FileProto";
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I think a blank line between package and the option block would make sense here and elsewhere.

Copy link
Contributor Author

@dapengzhang0 dapengzhang0 Jan 30, 2019

Choose a reason for hiding this comment

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

Done.

if "option java_outer_classname = " in line:
return []

to_add = "option java_outer_classname = \"" \
Copy link
Member

Choose a reason for hiding this comment

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

Nit: mixture of " and ` style for Python strings, please stick with the dominate convention in the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure which style dominates in the file, seems both are widely used, but I changed to use only one style in my diff.

if "-" in file_name or "." in file_name or not file_name.islower():
return ["Unable to decide java_outer_classname for proto file: %s" % file_path]

for line in fileinput.FileInput(file_path):
Copy link
Member

Choose a reason for hiding this comment

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

You don't need to iterate, just read in the file and do an in operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

+ ''.join(x.title() for x in file_name.split('_')) \
+ "Proto\";\n"

for line in fileinput.FileInput(file_path, inplace=True):
Copy link
Member

Choose a reason for hiding this comment

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

Don't need to iterate, can just do a re.sub here or similar on the entire file contents.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

return []


def fixJavaMultipleFilesProtoOption(file_path):
Copy link
Member

Choose a reason for hiding this comment

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

This is similar logic to the above function, can just refactor and parameterize on the string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
…erclass

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
This reverts commit 4b7bf26.

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

Thanks, looks better, a few comments.

f.seek(0)
f.write(new_text)
f.truncate()
sys.stdout.write(new_text)
Copy link
Member

Choose a reason for hiding this comment

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

Remove debug

new_text = re.sub(PROTO_PACKAGE_REGEX, repl, text)
f.seek(0)
f.write(new_text)
f.truncate()
Copy link
Member

Choose a reason for hiding this comment

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

Why is this needed?

if package_name is None:
return ["Unable to find package name for proto file: %s" % file_path]
new_text = re.sub(PROTO_PACKAGE_REGEX, repl, text)
f.seek(0)
Copy link
Member

Choose a reason for hiding this comment

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

I think you could do this as two separate with blocks, one with mode r and the other with w. This would be conceptually cleaner.

error_message = []
with open(file_path) as f:
result = PROTO_PACKAGE_REGEX.search(f.read())
if not result is None and len(result.groups()) == 1:
Copy link
Member

Choose a reason for hiding this comment

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

if result is not None and ...

if pattern in f.read():
return []
return [file_path + ": " + error_message]
# return [] if pattern in f.read() else [file_path + ": " + error_message]
Copy link
Member

Choose a reason for hiding this comment

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

Debug?

if "-" in file_name or "." in file_name or not file_name.islower():
return ["Unable to decide java_outer_classname for proto file: %s" % file_path]

to_add = "option java_outer_classname = \"" \
Copy link
Member

Choose a reason for hiding this comment

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

FWIW, I think if you make some of these strings like option java_outer_classname = \" file-level constants, it could make it easier to keep the fix/check synced.

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
…erclass

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
@dapengzhang0
Copy link
Contributor Author

@htuch Thanks for the additional comments. PTALA.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

LGTM, but if you could fix the nit and merge master when #5827 merges, we should be able to get this to pass CI.

if "option java_package = \"io.envoyproxy.envoy" in line:
return []
if not substring in text:

Copy link
Member

Choose a reason for hiding this comment

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

Nit: superfluous blank line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually this superfluous line was suggested by check_format

$ ENVOY_DOCKER_BUILD_DIR=~/build ./ci/run_envoy_docker.sh './ci/do_ci.sh check_format'
Running Python format check...
--- /source/tools/check_format.py	(original)
+++ /source/tools/check_format.py	(reformatted)
@@ -157,6 +157,7 @@
     text = f.read()
 
   if not substring in text:
+
     def repl(m):
       return m.group(0).rstrip() + "\n\n" + to_add + "\n"

@htuch
Copy link
Member

htuch commented Feb 4, 2019

Please merge master to pick up #5827.

…erclass

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
@htuch htuch merged commit 4a5f858 into envoyproxy:master Feb 5, 2019
@dapengzhang0 dapengzhang0 deleted the outerclass branch February 8, 2019 18:28
fredlas pushed a commit to fredlas/envoy that referenced this pull request Mar 5, 2019
…roxy#5764)

As discussed with @snowp in [envoyproxy/java-control-plane#87 (comment)](envoyproxy/java-control-plane#87 (comment)) and [envoyproxy/java-control-plane#87 (comment)](envoyproxy/java-control-plane#87 (comment)), adding these options will avoid the risk of having API breaking changes on the generated java code as the proto files evolve.

Risk Level_: Medium
Note that e.g. [envoyproxy/java-control-plane](https://github.com/envoyproxy/java-control-plane) will have to do a refactoring when they sync the proto files next time.

Signed-off-by: Penn (Dapeng) Zhang <zdapeng@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants