Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

Commit

Permalink
Add ts_proto_library rule
Browse files Browse the repository at this point in the history
Closes #193

PiperOrigin-RevId: 195706451
  • Loading branch information
alexeagle committed May 7, 2018
1 parent 8ff0552 commit eeb4eb9
Show file tree
Hide file tree
Showing 18 changed files with 874 additions and 20 deletions.
19 changes: 19 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# https://github.com/bazelbuild/rules_go/blob/master/go/tools/gazelle/README.rst#directives
# gazelle:exclude node_modules
load("@io_bazel_rules_go//go:def.bzl", "gazelle")
load("@build_bazel_rules_nodejs//internal/js_library:js_library.bzl", "js_library")

gazelle(
name = "gazelle",
Expand Down Expand Up @@ -48,6 +49,7 @@ skylark_doc(
"//internal:ts_config.bzl",
"//internal/devserver:ts_devserver.bzl",
"//internal/karma:ts_web_test.bzl",
"//internal/protobufjs:ts_proto_library.bzl",
],
format = "html",
# The site is served at http://tsetse.info so the URL doesn't include a
Expand All @@ -56,3 +58,20 @@ skylark_doc(
site_root = "/api",
strip_prefix = "internal/",
)

# Runtime libraries needed by the protobufjs library.
# Any JS code produced by the ts_proto_library rule has a runtime dependency on these scripts.
js_library(
name = "protobufjs_bootstrap_scripts",
srcs = [
"@build_bazel_rules_typescript_protobufs_compiletime_deps//:node_modules/long/dist/long.js",
"@build_bazel_rules_typescript_protobufs_compiletime_deps//:node_modules/protobufjs/dist/minimal/protobuf.min.js",
],
# Make devmode loading work when it does require("protobufjs/minimal")
# so this is shimmed to define it to equal global.protobuf
amd_names = {
"long": "Long",
"protobufjs/minimal": "protobuf",
},
visibility = ["//visibility:public"],
)
6 changes: 3 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ workspace(name = "build_bazel_rules_typescript")

http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.3.zip",
strip_prefix = "rules_nodejs-0.5.3",
sha256 = "17a5515f59777b00cb25dbc710017a14273f825029b2ec60e0969d28914870be",
url = "https://github.com/bazelbuild/rules_nodejs/archive/092404e3b47e1144ecfc2937d3729b717b1052bf.zip",
strip_prefix = "rules_nodejs-092404e3b47e1144ecfc2937d3729b717b1052bf",
sha256 = "5e3dd3f76a043687939a14ce6aee3049f8bd97d2cd885ef2105ac344d05213a3",
)

load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories", "yarn_install")
Expand Down
2 changes: 2 additions & 0 deletions defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ load("//internal:build_defs.bzl", _ts_library = "ts_library")
load("//internal:ts_config.bzl", _ts_config = "ts_config")
load("//internal/devserver:ts_devserver.bzl", _ts_devserver = "ts_devserver_macro")
load("//internal/karma:ts_web_test.bzl", _ts_web_test = "ts_web_test_macro")
load("//internal/protobufjs:ts_proto_library.bzl", _ts_proto_library = "ts_proto_library")

ts_setup_workspace = _ts_setup_workspace
ts_library = _ts_library
ts_config = _ts_config
ts_devserver = _ts_devserver
# TODO(alexeagle): make ts_web_test work in google3
ts_web_test = _ts_web_test
ts_proto_library = _ts_proto_library
# DO NOT ADD MORE rules here unless they appear in the generated docsite.
# Run yarn skydoc to re-generate the docsite.
60 changes: 60 additions & 0 deletions examples/protocol_buffers/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
load("@build_bazel_rules_typescript//:defs.bzl",
"ts_library",
"ts_proto_library",
"ts_web_test",
"ts_devserver",
)

proto_library(
name = "tire_proto",
srcs = ["tire.proto"],
)

proto_library(
name = "car_proto",
srcs = ["car.proto"],
deps = [":tire_proto"],
)

ts_proto_library(
# The result will be "car.d.ts" named after this target.
# We could use the output_name attribute if we want the output named
# differently than the target.
name = "car",
deps = [":car_proto"],
)

ts_library(
name = "test_lib",
testonly = True,
srcs = ["car.spec.ts"],
deps = [":car"],
)

ts_web_test(
name = "test",
deps = ["test_lib"],
bootstrap = ["@build_bazel_rules_typescript//:protobufjs_bootstrap_scripts"],
)

ts_library(
name = "app",
srcs = ["app.ts"],
deps = [":car"],
)

ts_devserver(
name = "devserver",
deps = [":app"],
entry_module = "build_bazel_rules_typescript/examples/protocol_buffers/app",
bootstrap = ["@build_bazel_rules_typescript//:protobufjs_bootstrap_scripts"],
)

# Test for production mode
load("@build_bazel_rules_nodejs//:defs.bzl", "rollup_bundle")

rollup_bundle(
name = "bundle",
deps = [":app"],
entry_point = "examples/protocol_buffers/app",
)
7 changes: 7 additions & 0 deletions examples/protocol_buffers/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {Car} from './car';

const serverResponse = `{"make": "Porsche"}`;
const car = Car.create(JSON.parse(serverResponse));
const el: HTMLDivElement = document.createElement('div');
el.innerText = `Car from server: ${car.make}`;
document.body.appendChild(el);
12 changes: 12 additions & 0 deletions examples/protocol_buffers/car.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
syntax = "proto3";

import "examples/protocol_buffers/tire.proto";

message Car {
string make = 1;
string model = 2;
int32 year = 3;
Tire front_tires = 4;
Tire rear_tires = 5;
int64 mileage = 6;
}
35 changes: 35 additions & 0 deletions examples/protocol_buffers/car.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {Car} from './car';
import Long = require('long');

describe('protocol buffers', () => {

it('allows creation of an object described by proto', () => {
const pontiac = Car.create({
make: "pontiac",
frontTires: {
width: 225,
aspectRatio: 65,
construction: 'R',
diameter: 17,
},
});
expect(pontiac.make).toEqual('pontiac');
if (!pontiac.frontTires) {
fail('Should have frontTires set');
} else {
expect(pontiac.frontTires.width).toEqual(225);
}
});

// Asserts that longs are handled correctly.
// This value comes from https://github.com/dcodeIO/long.js#background
it('handles long values correctly', () => {
const pontiac = Car.create({
make: "pontiac",
// Long.MAX_VALUE
mileage: new Long(0xFFFFFFFF, 0x7FFFFFFF),
});
const object = Car.toObject(pontiac, {longs: String});
expect(object["mileage"]).toEqual("9223372036854775807");
});
});
11 changes: 11 additions & 0 deletions examples/protocol_buffers/tire.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";

message Tire {
string type = 1;
int32 width = 2;
int32 aspect_ratio = 3;
string construction = 4;
int32 diameter = 5;
int32 load_index = 6;
string speed_rating = 7;
}
6 changes: 5 additions & 1 deletion examples/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"compilerOptions": {
"strict": true,
"lib": ["es2015.promise", "dom", "es5"]
"lib": ["es2015.promise", "dom", "es5"],
// Include the output directory in rootDirs so that generated .d.ts files
// can be used for type-checking in the editor, for example the car.proto
// produces a car.d.ts.
"rootDirs": [".", "../bazel-bin/examples"]
}
}

23 changes: 18 additions & 5 deletions internal/devserver/ts_devserver.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
load("@build_bazel_rules_nodejs//internal:node.bzl",
"sources_aspect",
)
load("@build_bazel_rules_nodejs//internal/js_library:js_library.bzl",
"write_amd_names_shim",
)

def _ts_devserver(ctx):
files = depset()
Expand All @@ -43,12 +46,19 @@ def _ts_devserver(ctx):
workspace_name + "/" + f.short_path + "\n" for f in files
]))

amd_names_shim = ctx.actions.declare_file(
"_%s.amd_names_shim.js" % ctx.label.name,
sibling = ctx.outputs.executable)
write_amd_names_shim(ctx.actions, amd_names_shim, ctx.attr.bootstrap)

# Requirejs is always needed so its included as the first script
# in script_files before any user specified scripts for the devserver
# to concat in order.
script_files = depset()
script_files += ctx.files._requirejs_script
script_files += ctx.files.scripts
script_files = []
script_files.extend(ctx.files.bootstrap)
script_files.append(ctx.file._requirejs_script)
script_files.append(amd_names_shim)
script_files.extend(ctx.files.scripts)
ctx.actions.write(ctx.outputs.scripts_manifest, "".join([
workspace_name + "/" + f.short_path + "\n" for f in script_files
]))
Expand All @@ -57,9 +67,9 @@ def _ts_devserver(ctx):
ctx.executable._devserver,
ctx.outputs.manifest,
ctx.outputs.scripts_manifest,
ctx.file._requirejs_script]
]
devserver_runfiles += ctx.files.static_files
devserver_runfiles += ctx.files.scripts
devserver_runfiles += script_files

serving_arg = ""
if ctx.attr.serving_path:
Expand Down Expand Up @@ -120,6 +130,9 @@ ts_devserver = rule(
ts_devserver concats the following snippet after the bundle to load the application:
`require(["entry_module"]);`
"""),
"bootstrap": attr.label_list(
doc = "Scripts to include in the JS bundle before the module loader (require.js)",
allow_files = [".js"]),
"_requirejs_script": attr.label(allow_files = True, single_file = True, default = Label("@build_bazel_rules_typescript_devserver_deps//:node_modules/requirejs/require.js")),
"_devserver": attr.label(
default = Label("//internal/devserver/main"),
Expand Down
10 changes: 9 additions & 1 deletion internal/karma/ts_web_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ load("@build_bazel_rules_nodejs//internal:node.bzl",
"sources_aspect",
"expand_path_into_runfiles",
)
load("@build_bazel_rules_nodejs//internal/js_library:js_library.bzl", "write_amd_names_shim")

_CONF_TMPL = "//internal/karma:karma.conf.js"
# TODO(alexeagle): users will need some control over browser; needs design
Expand Down Expand Up @@ -45,6 +46,12 @@ def _ts_web_test_impl(ctx):
expand_path_into_runfiles(ctx, f.short_path)
for f in ctx.files.bootstrap
]

amd_names_shim = ctx.actions.declare_file(
"_%s.amd_names_shim.js" % ctx.label.name,
sibling = ctx.outputs.executable)
write_amd_names_shim(ctx.actions, amd_names_shim, ctx.attr.bootstrap)

# Explicitly list the requirejs library files here, rather than use
# `frameworks: ['requirejs']`
# so that we control the script order, and the bootstrap files come before
Expand All @@ -55,6 +62,7 @@ def _ts_web_test_impl(ctx):
bootstrap_entries += [
"build_bazel_rules_typescript_karma_deps/node_modules/requirejs/require.js",
"build_bazel_rules_typescript_karma_deps/node_modules/karma-requirejs/lib/adapter.js",
"/".join([ctx.workspace_name, amd_names_shim.short_path]),
]
# Finally we load the user's srcs and deps
user_entries = [
Expand Down Expand Up @@ -115,7 +123,7 @@ $KARMA ${{ARGV[@]}}
return [DefaultInfo(
runfiles = ctx.runfiles(
files = ctx.files.srcs + ctx.files.deps + ctx.files.bootstrap + [
conf,
conf, amd_names_shim
],
transitive_files = files,
# Propagate karma_bin and its runfiles
Expand Down
19 changes: 19 additions & 0 deletions internal/protobufjs/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package(default_visibility=["//visibility:public"])
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")

exports_files([
"node_modules/protobufjs/dist/minimal/protobuf.min.js",
# Exported to be consumed for generating skydoc.
"ts_proto_library.bzl",
])

nodejs_binary(
name = "pbjs",
node_modules = "@build_bazel_rules_typescript_protobufs_compiletime_deps//:node_modules",
entry_point = "protobufjs/bin/pbjs",
)
nodejs_binary(
name = "pbts",
node_modules = "@build_bazel_rules_typescript_protobufs_compiletime_deps//:node_modules",
entry_point = "protobufjs/bin/pbts",
)
20 changes: 20 additions & 0 deletions internal/protobufjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "protobufjs",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"chalk": "^1.1.3",
"escodegen": "^1.9.0",
"espree": "^3.5.3",
"estraverse": "^4.2.0",
"glob": "^7.1.2",
"jsdoc": "^3.5.5",
"minimist": "^1.2.0",
"protobufjs": "Use HEAD to pick up fix for https://github.com/dcodeIO/protobuf.js/pull/1018",
"protobufjs": "github:dcodeIO/protobuf.js#65d113b0079fa2570837f3cf95268ce24714a248",
"semver": "^5.5.0",
"tmp": "0.0.33",
"uglify-js": "^2.8.29"
}
}
Loading

0 comments on commit eeb4eb9

Please sign in to comment.