Skip to content

Commit

Permalink
Python Support (#238)
Browse files Browse the repository at this point in the history
* Pull MessageRules out of oneof FieldRules (#213)

* add idea to gitignore

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* add required as a field rule to ensure nullability

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* unimplemented flag for c++

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* add import to build bazel

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* ignore java

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* fix syntax

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* fix error

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* fix java exception

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* fix fail statement

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Pull message rules out

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* fix tests

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* undo style change

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* removing messagerules

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* use messagerules inside rulecontext

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* remove generated files

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* prevent use of non-scalar wkts with message rules

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Unnecessary change

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* add float rules

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* C++ support

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* java support

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Update docs

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Changes updated

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* fixing javabuild

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Fix file permission

Signed-off-by: Aditya Kothari <akothari@lyft.com>
Signed-off-by: Aditya Kothari <akothari@lyft.com>

* String, Bool, Num, Global (disabled)

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Message rules

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* finished string rules

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Duration Rules completed

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Timestamp rules

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Wrapper rules

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Comments addressed, fixed tests

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Print generated code

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Add test case

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Enum Rules added

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* Tests python 3 as well

Signed-off-by: Aditya Kothari <akothari@lyft.com>

* any rules

Signed-off-by: Aditya Kothari <akothari@lyft.com>
  • Loading branch information
kothariaditya authored and Chris Roche committed Aug 2, 2019
1 parent ee0f8c7 commit e736f5d
Show file tree
Hide file tree
Showing 19 changed files with 1,016 additions and 93 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ build: validate/validate.pb.go
.PHONY: bazel
bazel:
# generate the PGV plugin with Bazel
bazel build //tests/...
bazel build //tests/... --incompatible_new_actions_api=false

.PHONY: build_generation_tests
build_generation_tests:
Expand Down Expand Up @@ -72,7 +72,7 @@ harness: testcases tests/harness/go/harness.pb.go tests/harness/gogo/harness.pb.
.PHONY: bazel-harness
bazel-harness:
# runs the test harness via bazel
bazel run //tests/harness/executor:executor -- -go -gogo -cc -java
bazel run //tests/harness/executor:executor --incompatible_new_actions_api=false -- -go -gogo -cc -java -python

.PHONY: testcases
testcases: gogofast
Expand Down
28 changes: 28 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,31 @@ maven_jar(
name = "org_apache_commons_validator",
artifact = "commons-validator:commons-validator:1.6"
)

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

git_repository(
name = "io_bazel_rules_python",
remote = "https://github.com/bazelbuild/rules_python.git",
commit = "fdbb17a4118a1728d19e638a5291b4c4266ea5b8",
shallow_since = "1557865590 -0400",
)

# Only needed for PIP support:
load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories")

pip_repositories()

load("@io_bazel_rules_python//python:pip.bzl", "pip_import")

# This rule translates the specified requirements.txt into
# @my_deps//:requirements.bzl, which itself exposes a pip_install method.
pip_import(
name = "my_deps",
requirements = "//:requirements.txt",
)

# Load the pip_install symbol for my_deps, and create the dependencies'
# repositories.
load("@my_deps//:requirements.bzl", "pip_install")
pip_install()
29 changes: 28 additions & 1 deletion bazel/pgv_proto_library.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@io_bazel_rules_go//proto:compiler.bzl", "go_proto_compiler")
load(":protobuf.bzl", "cc_proto_gen_validate", "java_proto_gen_validate")
load(":protobuf.bzl", "cc_proto_gen_validate", "java_proto_gen_validate", "python_proto_gen_validate")

def pgv_go_proto_library(name, proto = None, deps = [], **kwargs):
go_proto_compiler(
Expand Down Expand Up @@ -74,4 +74,31 @@ def pgv_cc_proto_library(
**kargs
)

def pgv_python_proto_library(
name,
deps = [],
python_deps = [],
**kwargs):
"""Bazel rule to create a Python protobuf validation library from proto sources files.
Args:
name: the name of the pgv_python_proto_library
deps: proto_library rules that contain the necessary .proto files
python_deps: Python dependencies of the protos being compiled. Likely py_proto_library or pgv_python_proto_library.
"""

python_proto_gen_validate(
name = name + "_validate",
deps = deps,
)

native.py_library(
name = name,
srcs = [name + "_validate"],
deps = python_deps + [
"@com_envoyproxy_protoc_gen_validate//validate:validate_py",
],
**kwargs
)


pgv_java_proto_library = java_proto_gen_validate
55 changes: 55 additions & 0 deletions bazel/protobuf.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,38 @@ def _protoc_gen_validate_cc_impl(ctx):
package_command = "true",
)

def _protoc_python_output_files(proto_file_sources):
python_srcs = []

for p in proto_file_sources:
basename = p.basename[:-len(".proto")]

python_srcs.append(basename + "_pb2.py")
return python_srcs

def _protoc_gen_validate_python_impl(ctx):
"""Generate Python protos using protoc-gen-validate plugin"""
protos = _proto_sources(ctx)

python_files = _protoc_python_output_files(protos)
out_files = [ctx.actions.declare_file(out) for out in python_files]

dir_out = _output_dir(ctx)

args = [
"--python_out=" + dir_out,
]

return _protoc_gen_validate_impl(
ctx = ctx,
lang = "python",
protos = protos,
out_files = out_files,
protoc_args = args,
package_command = "true",
)


def _protoc_gen_validate_impl(ctx, lang, protos, out_files, protoc_args, package_command):
protoc_args.append("--plugin=protoc-gen-validate=" + ctx.executable._plugin.path)

Expand Down Expand Up @@ -241,3 +273,26 @@ java_proto_gen_validate = rule(
},
implementation = _java_proto_gen_validate_impl,
)

python_proto_gen_validate = rule(
attrs = {
"deps": attr.label_list(
mandatory = True,
providers = ["proto"],
),
"_protoc": attr.label(
cfg = "host",
default = Label("@com_google_protobuf//:protoc"),
executable = True,
allow_single_file = True,
),
"_plugin": attr.label(
cfg = "host",
default = Label("@com_envoyproxy_protoc_gen_validate//:protoc-gen-validate"),
allow_files = True,
executable = True,
),
},
output_to_genfiles = True,
implementation = _protoc_gen_validate_python_impl,
)
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public static void main(String[] args) {
Bool.getDescriptor().toProto(),
Bytes.getDescriptor().toProto(),
Enums.getDescriptor().toProto(),
KitchenSink.getDescriptor().toProto(),
Maps.getDescriptor().toProto(),
Messages.getDescriptor().toProto(),
Numbers.getDescriptor().toProto(),
Expand Down
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ipaddress==1.0.22
validate-email==1.3
Jinja2==2.10.1
MarkupSafe==1.1.1
162 changes: 81 additions & 81 deletions rule_comparison.md
Original file line number Diff line number Diff line change
@@ -1,109 +1,109 @@
# Constraint Rule Comparison
## Global
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| disabled |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| disabled ||||||

## Numerics
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| const |||||
| lt/lte/gt/gte |||||
| in/not_in |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| const ||||||
| lt/lte/gt/gte ||||||
| in/not_in ||||||

## Bools
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| const |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| const ||||||

## Strings
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| const |||||
| len/min\_len/max_len |||||
| min\_bytes/max\_bytes |||||
| pattern |||||
| prefix/suffix/contains |||||
| in/not_in |||||
| email |||||
| hostname |||||
| address |||||
| ip |||||
| ipv4 |||||
| ipv6 |||||
| uri |||||
| uri_ref |||||
| uuid |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| const ||||||
| len/min\_len/max_len ||||||
| min\_bytes/max\_bytes ||||||
| pattern ||||||
| prefix/suffix/contains ||||||
| in/not_in ||||||
| email ||||||
| hostname ||||||
| address ||||||
| ip ||||||
| ipv4 ||||||
| ipv6 ||||||
| uri ||||||
| uri_ref ||||||
| uuid ||||||

## Bytes
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| const |||||
| len/min\_len/max_len |||||
| pattern |||||
| prefix/suffix/contains |||||
| in/not_in |||||
| ip |||||
| ipv4 |||||
| ipv6 |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| const ||||||
| len/min\_len/max_len ||||||
| pattern ||||||
| prefix/suffix/contains ||||||
| in/not_in ||||||
| ip ||||||
| ipv4 ||||||
| ipv6 ||||||

## Enums
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| const |||||
| defined_only |||||
| in/not_in |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| const ||||||
| defined_only ||||||
| in/not_in ||||||

## Messages
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| skip |||||
| required |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| skip ||||||
| required ||||||

## Repeated
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| min\_items/max_items |||||
| unique |||||
| items |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| min\_items/max_items ||||||
| unique ||||||
| items ||||||

## Maps
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| min\_pairs/max_pairs |||||
| no_sparse |||||
| keys |||||
| values |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| min\_pairs/max_pairs ||||||
| no_sparse ||||||
| keys ||||||
| values ||||||

## OneOf
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| required |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| required ||||||

## WKT Scalar Value Wrappers
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| wrapper validation |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| wrapper validation ||||||

## WKT Any
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| required |||||
| in/not_in |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| required ||||||
| in/not_in ||||||

## WKT Duration
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| required |||||
| const |||||
| lt/lte/gt/gte |||||
| in/not_in |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| required ||||||
| const ||||||
| lt/lte/gt/gte ||||||
| in/not_in ||||||

## WKT Timestamp
| Constraint Rule | Go | GoGo | C++ | Java |
| ---| :---: | :---: | :---: | :---: |
| required |||||
| const |||||
| lt/lte/gt/gte |||||
| lt_now/gt_now |||||
| within |||||
| Constraint Rule | Go | GoGo | C++ | Java | Python |
| ---| :---: | :---: | :---: | :---: | :---: |
| required ||||||
| const ||||||
| lt/lte/gt/gte ||||||
| lt_now/gt_now ||||||
| within ||||||
11 changes: 11 additions & 0 deletions tests/harness/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
# gazelle:exclude harness.pb.go

load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@com_google_protobuf//:protobuf.bzl", "py_proto_library")


proto_library(
name = "harness_proto",
Expand Down Expand Up @@ -54,3 +56,12 @@ go_library(
importpath = "github.com/envoyproxy/protoc-gen-validate/tests/harness",
visibility = ["//visibility:public"],
)

py_proto_library(
name = "python-harness-proto",
srcs = ["harness.proto"],
protoc = "@com_google_protobuf//:protoc",
default_runtime = "@com_google_protobuf//:protobuf_python",
deps = ["@com_google_protobuf//:protobuf_python"],
visibility = ["//visibility:public"],
)
Loading

0 comments on commit e736f5d

Please sign in to comment.