Skip to content

Commit

Permalink
Integrate JS soy proto support (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
hochhaus authored and jart committed Sep 1, 2016
1 parent ee88f22 commit 1cae287
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 2 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,9 @@ Defines a set of Protocol Buffer files.

- *name*.js: A generated protocol buffer JavaScript library.

- *name*.descriptor: A protoc FileDescriptorsSet representation of the .proto
files.

#### Rule Polymorphism

This rule can be referenced as though it were the following:
Expand Down
7 changes: 7 additions & 0 deletions closure/compiler/closure_js_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ def _impl(ctx):
"--label=%s" % ctx.label,
"--convention=%s" % ctx.attr.convention,
"--language=%s" % _determine_check_language(ctx.attr.language)]
proto_descriptor_sets = []
if ctx.attr.proto_descriptor_set:
proto_descriptor_sets += [ctx.attr.proto_descriptor_set]
if ctx.attr.testonly:
args += ["--testonly"]
roots = set(order="compile")
Expand All @@ -65,6 +68,8 @@ def _impl(ctx):
for edep in direct_dep.js_exports:
args += ["--dep=%s" % edep.js_provided.path]
inputs.append(edep.js_provided)
if hasattr(direct_dep, "proto_descriptor_sets"):
proto_descriptor_sets += direct_dep.proto_descriptor_sets
args += ["--suppress=%s" % s for s in ctx.attr.suppress]
if ctx.attr.internal_expect_failure:
args += ["--expect_failure"]
Expand All @@ -86,6 +91,7 @@ def _impl(ctx):
progress_message="Checking %d JS files in %s" % (
len(ctx.files.srcs) + len(ctx.files.externs), ctx.label))
return struct(files=set(),
proto_descriptor_sets=proto_descriptor_sets,
js_language=determine_js_language(ctx),
js_exports=ctx.attr.exports,
js_provided=ctx.outputs.provided,
Expand All @@ -111,6 +117,7 @@ closure_js_library = rule(
"language": attr.string(default=JS_LANGUAGE_DEFAULT),
"no_closure_library": attr.bool(default=False),
"srcs": attr.label_list(allow_files=JS_FILE_TYPE),
"proto_descriptor_set": attr.label(allow_files=True),
"suppress": attr.string_list(),
"data": attr.label_list(cfg=DATA_CFG, allow_files=True),

Expand Down
2 changes: 2 additions & 0 deletions closure/private/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ CSS_DEPS_ATTR = attr.label_list(
"transitive_css_srcs",
"transitive_css_labels"])

SOY_DEPS_ATTR = attr.label_list(allow_files=False, providers=["proto_descriptor_sets"])

CLOSURE_LIBRARY_BASE_ATTR = attr.label(
default=Label("@closure_library//:closure/goog/base.js"),
allow_files=True,
Expand Down
4 changes: 3 additions & 1 deletion closure/protobuf/closure_js_proto_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def closure_js_proto_library(
if import_style:
js_out_options += ["import_style=%s" % import_style]
cmd += ["--js_out=%s:$(@D)" % ",".join(js_out_options)]
cmd += ["--descriptor_set_out=$(@D)/%s.descriptor" % name]
cmd += ["$(locations " + src + ")" for src in srcs]

native.genrule(
Expand All @@ -48,14 +49,15 @@ def closure_js_proto_library(
testonly = testonly,
visibility = ["//visibility:private"],
message = "Generating JavaScript Protocol Buffer file",
outs = [name + ".js"],
outs = [name + ".js", name + ".descriptor"],
tools = [protocbin],
cmd = " ".join(cmd),
)

closure_js_library(
name = name,
srcs = [name + ".js"],
proto_descriptor_set = name + ".descriptor",
data = data,
deps = [
str(Label("//closure/library")),
Expand Down
9 changes: 8 additions & 1 deletion closure/templates/closure_js_template_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"""

load("//closure/compiler:closure_js_library.bzl", "closure_js_library")
load("//closure/private:defs.bzl", "SOY_FILE_TYPE")
load("//closure/private:defs.bzl", "SOY_DEPS_ATTR", "SOY_FILE_TYPE")


def _impl(ctx):
Expand Down Expand Up @@ -53,6 +53,11 @@ def _impl(ctx):
if ctx.attr.globals:
args += ["--compileTimeGlobalsFile='%s'" % ctx.attr.globals.path]
srcs += ctx.attr.globals
for dep in ctx.attr.deps:
for desc in dep.proto_descriptor_sets:
srcs += list(desc.files)
for f in desc.files:
args += ["--protoFileDescriptors=%s" % f.path]

ctx.action(
inputs=srcs,
Expand All @@ -70,6 +75,7 @@ _closure_js_template_library = rule(
output_to_genfiles = True,
attrs={
"srcs": attr.label_list(allow_files=SOY_FILE_TYPE),
"deps": SOY_DEPS_ATTR,
"outputs": attr.output_list(),
"globals": attr.label_list(),
"plugin_modules": attr.label_list(),
Expand Down Expand Up @@ -107,6 +113,7 @@ def closure_js_template_library(
_closure_js_template_library(
name = name + "_soy_js",
srcs = srcs,
deps = deps,
outputs = js_srcs,
testonly = testonly,
visibility = ["//visibility:private"],
Expand Down
62 changes: 62 additions & 0 deletions closure/templates/test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@
package(default_testonly = True)

load("//closure:defs.bzl", "closure_js_library")
load("//closure:defs.bzl", "closure_js_proto_library")
load("//closure:defs.bzl", "closure_js_template_library")
load("//closure:defs.bzl", "closure_js_test")
load("//closure:defs.bzl", "closure_java_template_library")
load("//closure/private:file_test.bzl", "file_test")

closure_js_proto_library(
name = "person_proto",
srcs = ["person.proto"],
)

closure_js_template_library(
name = "greeter_soy",
srcs = ["greeter.soy"],
Expand All @@ -31,6 +37,19 @@ closure_js_template_library(
incremental_dom = 1,
)

closure_js_template_library(
name = "greeter_proto_soy",
srcs = ["greeter_proto.soy"],
deps = [":person_proto"],
)

closure_js_template_library(
name = "greeter_idom_proto_soy",
srcs = ["greeter_idom_proto.soy"],
deps = [":person_proto"],
incremental_dom = 1,
)

closure_js_library(
name = "greeter_lib",
srcs = ["greeter.js"],
Expand All @@ -51,6 +70,28 @@ closure_js_library(
],
)

closure_js_library(
name = "greeter_proto_lib",
srcs = ["greeter_proto.js"],
deps = [
":greeter_proto_soy",
":person_proto",
"//closure/library",
],
)

closure_js_library(
name = "greeter_idom_proto_lib",
srcs = ["greeter_idom_proto.js"],
language = "ECMASCRIPT6_STRICT",
deps = [
":greeter_idom_proto_soy",
":person_proto",
"//closure/library",
"//closure/templates:incremental_dom",
],
)

closure_js_test(
name = "greeter_test",
srcs = ["greeter_test.js"],
Expand All @@ -73,6 +114,27 @@ closure_js_test(
],
)

closure_js_test(
name = "greeter_proto_test",
srcs = ["greeter_proto_test.js"],
deps = [
":greeter_proto_lib",
"//closure/library",
"//closure/library:testing",
],
)

closure_js_test(
name = "greeter_idom_proto_test",
srcs = ["greeter_idom_proto_test.js"],
language = "ECMASCRIPT6_STRICT",
deps = [
":greeter_idom_proto_lib",
"//closure/library",
"//closure/library:testing",
],
)

closure_java_template_library(
name = "greeter_soy_java",
srcs = ["greeter.soy"],
Expand Down
45 changes: 45 additions & 0 deletions closure/templates/test/greeter_idom_proto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2016 The Closure Rules Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.module('io.bazel.rules.closure.GreeterIdomProto');

const idom = goog.require('incrementaldom');
const greeter = goog.require('io.bazel.rules.closure.soy.greeter.incrementaldom');
const Person = goog.require('proto.io.bazel.rules.closure.soy.Person');



exports = class GreeterIdomProto {
/**
* Greeter page.
* @param {string} name Name of person to greet.
*/
constructor(name) {
/**
* Name of person to greet.
* @private {string}
* @const
*/
this.name_ = name;
}

/**
* Renders HTML greeting as document body.
*/
greet() {
var person = new Person();
person.setName(this.name_);
idom.patchInner(goog.global.document.body, greeter.greet, {person: person});
}
};
26 changes: 26 additions & 0 deletions closure/templates/test/greeter_idom_proto.soy
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2016 The Closure Rules Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

{namespace io.bazel.rules.closure.soy.greeter autoescape="strict"}


/**
* Greets a person.
*/
{template .greet}
{@param person: io.bazel.rules.closure.soy.Person}
<p>
Hello <b>{$person.name}</b>!
</p>
{/template}
26 changes: 26 additions & 0 deletions closure/templates/test/greeter_idom_proto_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2016 The Closure Rules Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.require('goog.module');
goog.require('goog.testing.asserts');
goog.require('goog.testing.jsunit');
goog.require('io.bazel.rules.closure.GreeterIdomProto');


function testGreet() {
var GreeterIdom = goog.module.get('io.bazel.rules.closure.GreeterIdomProto');
var greeter = new GreeterIdom('Andy');
greeter.greet();
assertHTMLEquals('<p>Hello <b>Andy</b>!</p>', document.body.innerHTML);
}
50 changes: 50 additions & 0 deletions closure/templates/test/greeter_proto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2016 The Closure Rules Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.provide('io.bazel.rules.closure.GreeterProto');

goog.require('goog.soy');
goog.require('io.bazel.rules.closure.soy.greeter');
goog.require('proto.io.bazel.rules.closure.soy.Person');



/**
* Greeter page.
* @param {string} name Name of person to greet.
* @constructor
* @final
*/
io.bazel.rules.closure.GreeterProto = function(name) {

/**
* Name of person to greet.
* @private {string}
* @const
*/
this.name_ = name;
};


/**
* Renders HTML greeting as document body.
*/
io.bazel.rules.closure.GreeterProto.prototype.greet = function() {
var person = new proto.io.bazel.rules.closure.soy.Person();
person.setName(this.name_);

goog.soy.renderElement(goog.global.document.body,
io.bazel.rules.closure.soy.greeter.greet,
{person: person});
};
25 changes: 25 additions & 0 deletions closure/templates/test/greeter_proto.soy
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2016 The Closure Rules Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

{namespace io.bazel.rules.closure.soy.greeter autoescape="strict"}


/**
* Greets a person.
*/
{template .greet}
{@param person: io.bazel.rules.closure.soy.Person}
<p>
Hello <b>{$person.name}</b>!
{/template}
Loading

0 comments on commit 1cae287

Please sign in to comment.