diff --git a/WORKSPACE b/WORKSPACE index 66609249b3..17fbfea079 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -962,6 +962,14 @@ npm_binary( name = "bower", ) +npm_binary( + name = "vulcanize", +) + +npm_binary( + name = "crisper", +) + # bower_archive() seed components. bower_archive( name = 'iron-autogrow-textarea', @@ -1040,6 +1048,29 @@ bower_archive( sha1 = 'a3b598c06cbd7f441402e666ff748326030905d6', ) +# bower test stuff + +bower_archive( + name = 'iron-test-helpers', + package = 'polymerelements/iron-test-helpers', + version = '1.2.5', + sha1 = '433b03b106f5ff32049b84150cd70938e18b67ac', +) + +bower_archive( + name = 'test-fixture', + package = 'polymerelements/test-fixture', + version = '1.1.1', + sha1 = 'e373bd21c069163c3a754e234d52c07c77b20d3c', +) + +bower_archive( + name = 'web-component-tester', + package = 'web-component-tester', + version = '4.2.2', + sha1 = '54556000c33d9ed7949aa546c1b4a1531491a5f0', +) + # Bower component transitive dependencies. load("//lib/js:bower_archives.bzl", "load_bower_archives") load_bower_archives() diff --git a/lib/js/BUILD b/lib/js/BUILD index 30300139ed..249f5d0d04 100644 --- a/lib/js/BUILD +++ b/lib/js/BUILD @@ -27,3 +27,18 @@ js_component( srcs = [ "//lib/highlightjs:highlight.min.js" ], license = '//lib:LICENSE-highlightjs', ) + +bower_component( + name = 'iron-test-helpers', + seed = True, +) + +bower_component( + name = 'test-fixture', + seed = True, +) + +bower_component( + name = 'web-component-tester', + seed = True, +) diff --git a/polygerrit-ui/BUILD b/polygerrit-ui/BUILD index 6378bfc029..9191ab72fe 100644 --- a/polygerrit-ui/BUILD +++ b/polygerrit-ui/BUILD @@ -1,9 +1,12 @@ +package( + default_visibility=["//visibility:public"] +) load("//tools/bzl:js.bzl", "bower_component_bundle") load('//tools/bzl:genrule2.bzl', 'genrule2') bower_component_bundle( - name = "components", + name = "polygerrit_components", deps = [ '//lib/js:es6-promise', '//lib/js:fetch', diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD new file mode 100644 index 0000000000..29bbfffe09 --- /dev/null +++ b/polygerrit-ui/app/BUILD @@ -0,0 +1,37 @@ +package( + default_visibility = ["//visibility:public"]) +load("//tools/bzl:js.bzl", "bower_component_bundle", "vulcanize") + +WCT_TEST_PATTERNS = [ + 'test/*.js', + 'test/*.html', + '**/*_test.html', +] +PY_TEST_PATTERNS = ['polygerrit_wct_tests.py'] +APP_SRCS = glob( + ['**'], + exclude = [ + 'BUCK', + '*~', + '**/BUILD', + 'index.html', + 'test/**', + ] + WCT_TEST_PATTERNS + PY_TEST_PATTERNS) + + +bower_component_bundle( + name = 'test_components', + deps = [ + '//polygerrit-ui:polygerrit_components', + '//lib/js:iron-test-helpers', + '//lib/js:test-fixture', + '//lib/js:web-component-tester', + ], +) + +vulcanize( + name = "gr-app", + app = 'elements/gr-app.html', + srcs = APP_SRCS, + deps = [ "//polygerrit-ui:polygerrit_components"], +) diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl index 978059a12f..38d6c9179f 100644 --- a/tools/bzl/js.bzl +++ b/tools/bzl/js.bzl @@ -39,11 +39,12 @@ def _npm_binary_impl(ctx): python = ctx.which("python") script = ctx.path(ctx.attr._download_script) - args = [python, script, "-o", dest, "-u", url] + sha1 = NPM_SHA1S[name] + args = [python, script, "-o", dest, "-u", url, "-v", sha1] out = ctx.execute(args) if out.return_code: fail("failed %s: %s" % (args, out.stderr)) - ctx.file("BUILD", "filegroup(name='tarball', srcs=['%s'])" % base, False) + ctx.file("BUILD", "package(default_visibility=['//visibility:public'])\nfilegroup(name='tarball', srcs=['%s'])" % base, False) npm_binary = repository_rule( implementation=_npm_binary_impl, @@ -55,12 +56,13 @@ npm_binary = repository_rule( }) -def _run_npm_binary_str(ctx, tarball, name): +# for use in repo rules. +def _run_npm_binary_str(ctx, tarball, args): python_bin = ctx.which("python") return " ".join([ python_bin, ctx.path(ctx.attr._run_npm), - ctx.path(tarball)]) + ctx.path(tarball)] + args) def _bower_archive(ctx): @@ -72,7 +74,7 @@ def _bower_archive(ctx): cmd = [ ctx.which("python"), ctx.path(ctx.attr._download_bower), - '-b', '%s' % _run_npm_binary_str(ctx, ctx.attr._bower_archive, "bower"), + '-b', '%s' % _run_npm_binary_str(ctx, ctx.attr._bower_archive, []), '-n', ctx.name, '-p', ctx.attr.package, '-v', ctx.attr.version, @@ -235,6 +237,10 @@ def _bower_component_bundle_impl(ctx): for d in ctx.attr.deps: versions += d.transitive_versions + licenses = set([]) + for d in ctx.attr.deps: + licenses += d.transitive_versions + out_zip = ctx.outputs.zip out_versions = ctx.outputs.version_json @@ -259,6 +265,11 @@ def _bower_component_bundle_impl(ctx): mnemonic="BowerVersions", command="(echo '{' ; for j in %s ; do cat $j; echo ',' ; done ; echo \\\"\\\":\\\"\\\"; echo '}') > %s" % (" ".join([v.path for v in versions]), out_versions.path)) + return struct( + transitive_zipfiles=zips, + transitive_versions=versions, + transitive_licenses=licenses) + bower_component_bundle = rule( _bower_component_bundle_impl, @@ -268,3 +279,88 @@ bower_component_bundle = rule( "version_json": "%{name}-versions.json", } ) + +def _vulcanize_impl(ctx): + destdir = ctx.outputs.vulcanized.path + ".dir" + zips = [z for d in ctx.attr.deps for z in d.transitive_zipfiles ] + + hermetic_npm_binary = " ".join([ + 'python', + "$p/" + ctx.file._run_npm.path, + "$p/" + ctx.file._vulcanize_archive.path, + '--inline-scripts', + '--inline-css', + '--strip-comments', + '--out-html', "$p/" + ctx.outputs.vulcanized.path, + ctx.file.app.path + ]) + + pkg_dir = ctx.attr.pkg.lstrip("/") + cmd = " && ".join([ + # unpack dependencies. + "export PATH", + "p=$PWD", + "rm -rf %s" % destdir, + "mkdir -p %s/%s/bower_components" % (destdir, pkg_dir), + "for z in %s; do unzip -qd %s/%s/bower_components/ $z; done" % ( + ' '.join([z.path for z in zips]), destdir, pkg_dir), + "tar -cf - %s | tar -C %s -xf -" % (" ".join([s.path for s in ctx.files.srcs]), destdir), + "cd %s" % destdir, + hermetic_npm_binary, + ]) + ctx.action( + mnemonic = "Vulcanize", + inputs = [ctx.file._run_npm, ctx.file.app, + ctx.file._vulcanize_archive + ] + list(zips) + ctx.files.srcs, + outputs = [ctx.outputs.vulcanized], + command = cmd) + + hermetic_npm_command = "export PATH && " + " ".join([ + 'python', + ctx.file._run_npm.path, + ctx.file._crisper_archive.path, + "--always-write-script", + "--source", ctx.outputs.vulcanized.path, + "--html", ctx.outputs.html.path, + "--js", ctx.outputs.js.path]) + + ctx.action( + mnemonic = "Crisper", + inputs = [ctx.file._run_npm, ctx.file.app, + ctx.file._crisper_archive, ctx.outputs.vulcanized], + outputs = [ctx.outputs.js, ctx.outputs.html], + command = hermetic_npm_command) + + +_vulcanize_rule = rule( + _vulcanize_impl, + attrs = { + "deps": attr.label_list(providers=["transitive_zipfiles"]), + "app": attr.label(mandatory=True, allow_single_file=True), + "srcs": attr.label_list(allow_files=[".js", ".html", ".txt", ".css", ".ico"]), + + "pkg": attr.string(mandatory=True), + "_run_npm": attr.label( + default=Label("//tools/js:run_npm_binary.py"), + allow_single_file=True + ), + "_vulcanize_archive": attr.label( + default=Label("@vulcanize//:%s" % _npm_tarball("vulcanize")), + allow_single_file=True + ), + "_crisper_archive": attr.label( + default=Label("@crisper//:%s" % _npm_tarball("crisper")), + allow_single_file=True + ), + }, + outputs = { + "vulcanized": "%{name}.vulcanized.html", + "html": "%{name}.crisped.html", + "js": "%{name}.crisped.js", + } +) + +def vulcanize(*args, **kwargs): + """Vulcanize runs vulcanize and crisper on a set of sources.""" + _vulcanize_rule(*args, pkg=PACKAGE_NAME, **kwargs) diff --git a/tools/js/BUILD b/tools/js/BUILD index e69de29bb2..fedaf7ffc4 100644 --- a/tools/js/BUILD +++ b/tools/js/BUILD @@ -0,0 +1 @@ +exports_files(["run_npm_binary.py"])