Make onos-gui bazel build hermetic
Change-Id: I24abb9c1a54314fb0dd00f40936e57f11280ebce
diff --git a/web/gui/BUILD b/web/gui/BUILD
index f4c2c93..3a2bfcc 100644
--- a/web/gui/BUILD
+++ b/web/gui/BUILD
@@ -1,4 +1,32 @@
-NODE_VERSION = "8.0.1"
+"""
+ Copyright 2018-present Open Networking Foundation
+
+ 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.
+"""
+
+"""
+ Rules to build the ONOS GUI
+
+ Bazel and npm are incompatibe in how they deal with files. npm likes to follow links
+ to get back to the original canonical path names, and bazel uses links extensively when
+ populating the sandbox. To get around these problems, the rules that follow use filegroups
+ to specify the files as dependencies and then use a genrule to convert the files into a tar
+ ball. Once the tar ball is unrolled into the sandbox, the links are broken, but the build is
+ still hermetic since those files are referred to as dependencies in the genrule.
+
+ Also note that the onos-gui.tar contains files from //tools/gui and //web/gui, so the files are placed into
+ the sandbox at the proper locations and then returned as a tar ball.
+"""
COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + [
"@javax_ws_rs_api//jar",
@@ -20,69 +48,9 @@
"//drivers/default:onos-drivers-default",
]
-genrule(
- name = "_onos-gui-npm-install",
- srcs = [
- "//tools/gui:package.json",
- "@nodejs//:bin/npm",
- ] + glob(
- [
- "src/main/webapp/*.js",
- "src/main/webapp/app/**/*.js",
- ],
- exclude = ["src/main/webapp/dist/*.js"],
- ),
- outs = ["onos-gui-npm-install.tar"],
- cmd = "(ROOT=`pwd` &&" +
- " NPM=$$ROOT/$(location @nodejs//:bin/npm) &&" +
- " cd tools/gui &&" +
- " $$NPM install --loglevel=error --no-cache --cache=$(@D)/.npm --no-update-notifier &&" +
- " tar cf $$ROOT/$@ package.json node_modules)",
- local = True,
- visibility = ["//visibility:public"],
-)
-
-genrule(
- name = "_onos-gui-npm-build",
- srcs = [
- "//tools/gui:gulpfile.babel.js",
- ":_onos-gui-npm-install",
- "@nodejs//:bin/npm",
- "//tools/gui:package.json",
- ] + glob(["src/main/webapp/*"]),
- outs = ["onos-gui-npm-build.tar"],
- cmd = "(ROOT=`pwd` &&" +
- " NPM=$$ROOT/$(location @nodejs//:bin/npm) &&" +
- " cd tools/gui &&" +
- " tar xf ../../$(location :_onos-gui-npm-install) &&" +
- " $$NPM run build --no-update-notifier &&" +
- " cd ../../web/gui/src/main/webapp &&" +
- " jar cf $$ROOT/$@ dist vendor data tests README.md _doc _dev app/fw app/*.css app/*.js app/*.txt)",
- local = True,
- visibility = ["//visibility:public"],
-)
-
-genrule(
- name = "_onos-gui-npm",
- srcs = [
- ":_onos-gui-npm-build",
- ],
- outs = ["onos-gui-npm.log"],
- cmd = "ROOT=`pwd` && cd web/gui/src/main/webapp && tar xf $$ROOT/$(location :_onos-gui-npm-build) >$$ROOT/$@",
- local = True,
- visibility = ["//visibility:public"],
-)
-
-osgi_jar_with_tests(
- name = "_onos-gui-base-jar",
- exclude_tests = [
- "org.onosproject.ui.impl.AbstractUiImplTest",
- "org.onosproject.ui.impl.topo.model.AbstractTopoModelTest",
- ],
- test_deps = TEST_DEPS,
- web_context = "/onos/ui",
- deps = COMPILE_DEPS,
-)
+"""
+ Files that get put at the top level of the tar ball
+"""
filegroup(
name = "_root_level_files",
@@ -95,6 +63,10 @@
],
)
+"""
+ Files that get put into the WEB-INF directory of the tar ball
+"""
+
filegroup(
name = "_web_inf_classes_files",
srcs =
@@ -108,21 +80,122 @@
],
)
+"""
+ webapp raw files
+"""
+
filegroup(
name = "_raw_classes_files",
srcs = glob(["src/main/webapp/raw/**"]),
)
-# app/view is packaged as a tar file because it has subdirectories that need to be preserved
+"""
+ dependency to expose all webapp files in the sandbox
+"""
+
+filegroup(
+ name = "_src_main_webapp_files",
+ srcs = glob([
+ "src/main/webapp/**",
+ ]),
+)
+
+"""
+ Install node.js and npm, and gather files needed from //tools/gui
+"""
+
+genrule(
+ name = "_onos-gui-npm-install",
+ srcs = [
+ "@nodejs//:bin/npm",
+ "//tools/gui:tools-gui-gulp",
+ ] + glob(
+ [
+ "src/main/webapp/*.js",
+ "src/main/webapp/app/**/*.js",
+ ],
+ exclude = ["src/main/webapp/dist/*.js"],
+ ),
+ outs = ["onos-gui-npm-install.tar"],
+ cmd = " ROOT=`pwd` &&" +
+ " export XDG_CONFIG_HOME=$(@D)/config &&" + # npm config cache to the sandbos
+ " export BABEL_DISABLE_CACHE=1" + # turn off babel cache
+ " NPM=$$ROOT/$(location @nodejs//:bin/npm) &&" +
+ " mkdir -p tools/gui &&" +
+ " cd tools/gui &&" +
+ " tar xf ../../$(location //tools/gui:tools-gui-gulp) &&" +
+ " $$NPM install --no-cache --loglevel=error >npm-install.out 2>&1 &&" +
+ " tar hcf $$ROOT/$@ package.json gulpfile.babel.js node_modules gulp-tasks",
+)
+
+"""
+ Run npm build to create node.js files
+"""
+
+genrule(
+ name = "_onos-gui-npm-build",
+ srcs = [
+ "@nodejs//:bin/npm",
+ "@nodejs//:bin/node",
+ ":_onos-gui-npm-install",
+ ":_web_app_all",
+ ],
+ outs = ["onos-gui-npm-build.tar"],
+ cmd = "(ROOT=`pwd` &&" +
+ " export XDG_CONFIG_HOME=$(@D)/config &&" +
+ " export BABEL_DISABLE_CACHE=1" +
+ " NPM=$(location @nodejs//:bin/npm) &&" +
+ " (mkdir -p web/gui && cd web/gui && tar xf ../../$(location :_web_app_all)) &&" +
+ " mkdir -p tools/gui && cd tools/gui &&" +
+ " tar xf $$ROOT/$(location :_onos-gui-npm-install) &&" +
+ " $$ROOT/$$NPM run build --no-cache --loglevel=error >npm-build.out &&" +
+ " cd ../../web/gui/src/main/webapp &&" +
+ " jar cf $$ROOT/$@ dist vendor data tests README.md _doc _dev app/fw app/*.css app/*.js app/*.txt)",
+)
+
+"""
+ Make a jar file of all the webapp files. Useful for breaking symblic links in the sandbox
+"""
+
+genrule(
+ name = "_web_app_all",
+ srcs = [":_src_main_webapp_files"],
+ outs = ["web_app_all.tar"],
+ cmd = "cd web/gui && tar hcf ../../$@ src/main/webapp",
+)
+
+"""
+ app/view is packaged as a tar file because it has subdirectories that need to be preserved
+"""
+
genrule(
name = "_app_view_tar",
srcs = glob(["src/main/webapp/app/view/**"]),
outs = ["app_view_tar.tar"],
cmd = " ROOT=`pwd` &&" +
" cd web/gui/src/main/webapp/app/view &&" +
- " tar cf $$ROOT/$@ .",
+ " tar hcf $$ROOT/$@ .",
)
+"""
+ Builds the java jar for the java code provided by the GUI
+"""
+
+osgi_jar_with_tests(
+ name = "_onos-gui-base-jar",
+ exclude_tests = [
+ "org.onosproject.ui.impl.AbstractUiImplTest",
+ "org.onosproject.ui.impl.topo.model.AbstractTopoModelTest",
+ ],
+ test_deps = TEST_DEPS,
+ web_context = "/onos/ui",
+ deps = COMPILE_DEPS,
+)
+
+"""
+ Builds the tar ball for the ONOS GUI
+"""
+
genrule(
name = "onos-gui",
srcs = [
@@ -141,10 +214,10 @@
" (cd WEB-INF/classes && mkdir -p app/view && cd app/view && tar xf $$ROOT/$(location :_app_view_tar)) &&" +
" for i in $(locations :_root_level_files); do cp $$ROOT/$$i .; done &&" +
" for i in $(locations :_web_inf_classes_files); do cp $$ROOT/$$i ./WEB-INF/classes/; done &&" +
- " mkdir ./WEB-INF/classes/raw && for i in $(locations :_raw_classes_files); do cp $$ROOT/$$i ./WEB-INF/classes/raw/; done &&" +
+ " mkdir ./WEB-INF/classes/raw && " +
+ " for i in $(locations :_raw_classes_files); do cp $$ROOT/$$i ./WEB-INF/classes/raw/; done &&" +
" jar xf $$ROOT/$(location :_onos-gui-base-jar) &&" +
" jar cmf META-INF/MANIFEST.MF $$ROOT/$@ .",
- local = True,
output_to_bindir = 1,
visibility = ["//visibility:public"],
)