Add polymer template checker
For details how to use it see the polygerrit-ui/README file.
Twinkie patch note: the template checker uses twinkie library for
checking. The library has a bug, that stops checker from working. As a
temporary workaround, the patch is added directly to this change. The
patch will be removed after fixing bug in twinkie library.
Change-Id: I3375d6654478e12eeb1df9a2b912125f6929838c
diff --git a/WORKSPACE b/WORKSPACE
index 428a6a4..a6a4937 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -70,6 +70,19 @@
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.5.0/rules_nodejs-3.5.0.tar.gz"],
)
+http_archive(
+ name = "rules_pkg",
+ sha256 = "038f1caa773a7e35b3663865ffb003169c6a71dc995e39bf4815792f385d837d",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.4.0/rules_pkg-0.4.0.tar.gz",
+ "https://github.com/bazelbuild/rules_pkg/releases/download/0.4.0/rules_pkg-0.4.0.tar.gz",
+ ],
+)
+
+load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
+
+rules_pkg_dependencies()
+
# Golang support for PolyGerrit local dev server.
http_archive(
name = "io_bazel_rules_go",
@@ -941,6 +954,7 @@
yarn_install(
name = "npm",
+ data = ["//:twinkie.patch"],
frozen_lockfile = False,
package_json = "//:package.json",
yarn_lock = "//:yarn.lock",
diff --git a/package.json b/package.json
index a3329a1..151b784 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,8 @@
"dependencies": {
"@bazel/rollup": "^3.5.0",
"@bazel/terser": "^3.5.0",
- "@bazel/typescript": "^3.5.0"
+ "@bazel/typescript": "^3.5.0",
+ "twinkie": "^1.1.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.22.0",
@@ -34,7 +35,10 @@
"eslintfix": "npm run safe_bazelisk run polygerrit-ui/app:lint_bin -- -- --fix $(pwd)/polygerrit-ui/app",
"polylint": "npm run safe_bazelisk test polygerrit-ui/app:polylint_test",
"test:debug": "npm run compile:local && npm run safe_bazelisk run //polygerrit-ui:karma_bin -- -- start $(pwd)/polygerrit-ui/karma.conf.js --browsers ChromeDev --no-single-run --testFiles",
- "test:single": "npm run compile:local && npm run safe_bazelisk run //polygerrit-ui:karma_bin -- -- start $(pwd)/polygerrit-ui/karma.conf.js --testFiles"
+ "test:single": "npm run compile:local && npm run safe_bazelisk run //polygerrit-ui:karma_bin -- -- start $(pwd)/polygerrit-ui/karma.conf.js --testFiles",
+ "postinstall": "(git apply --reverse --ignore-whitespace twinkie.patch || true) && git apply --ignore-whitespace twinkie.patch",
+ "polytest": "npm run safe_bazelisk test //polygerrit-ui/app:validate_polymer_templates",
+ "polytest:dev": "rm -rf ./polygerrit-ui/app/tmpl_out && npm run safe_bazelisk build //polygerrit-ui/app:template_test_tar && mkdir ./polygerrit-ui/app/tmpl_out && tar -xf bazel-bin/polygerrit-ui/app/template_test_tar.tar -C ./polygerrit-ui/app/tmpl_out"
},
"repository": {
"type": "git",
diff --git a/polygerrit-ui/README.md b/polygerrit-ui/README.md
index c6e6cd9..0297324 100644
--- a/polygerrit-ui/README.md
+++ b/polygerrit-ui/README.md
@@ -228,6 +228,56 @@
the "Before launch" section for IntelliJ. This is a temporary problem until
typescript migration is complete.
+## Running Templates Test
+The templates test validates polymer templates. The test convert polymer
+templates into a plain typescript code and then run TS compiler. The test fails
+if TS compiler reports errors; in this case you will see TS errors in
+the log/output. Gerrit-CI automatically runs templates test.
+
+**Note**: Files defined in `ignore_templates_list` (`polygerrit-ui/app/BUILD`)
+are excluded from code generation and checking. If you don't know how to fix
+a problem, you can add a problematic template in the list.
+
+* To run test locally, use npm command:
+``` sh
+npm run polytest
+```
+
+* Often, the output from the previous command is not clear (cryptic TS errors).
+In this case, run the command
+```sh
+npm run polytest:dev
+```
+This command (re)creates the `polygerrit-ui/app/tmpl_out` directory and put
+generated files into it. For each polygerrit .ts file there is a generated file
+in the `tmpl_out` directory. If an original file doesn't contain a polymer
+template, the generated file is empty.
+
+You can open a problematic file in IDE and fix the problem. Ensure, that IDE
+uses `polygerrit-ui/app/tsconfig.json` as a project (usually, this is default).
+
+### Generated file overview
+
+A generated file starts with imports followed by a static content with
+different type definitions. You can skip this part - it doesn't contains
+anything usefule.
+
+After the static content there is a class definition. Example:
+```typescript
+export class GrCreateGroupDialogCheck extends GrCreateGroupDialog {
+ templateCheck() {
+ // Converted template
+ // Each HTML element from the template is wrapped into own block.
+ }
+}
+```
+
+The converted template usually quite straightforward, but in some cases
+additional functions are added. For example, `<element x=[[y.a]]>` converts into
+`el.x = y!.a` if y is a simple type. However, if y has a union type, like - `y:A|B`,
+then the generated code looks like `el.x=__f(y)!.a` (`y!.a` may result in a TS error
+if `a` is defined only in one type of a union).
+
## Style guide
We follow the [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
diff --git a/polygerrit-ui/app/.eslintignore b/polygerrit-ui/app/.eslintignore
index 087a049..bb30f23 100644
--- a/polygerrit-ui/app/.eslintignore
+++ b/polygerrit-ui/app/.eslintignore
@@ -2,3 +2,4 @@
**/rollup.config.js
node_modules_licenses
!.eslintrc-bazel.js
+tmpl_out
diff --git a/polygerrit-ui/app/.gitignore b/polygerrit-ui/app/.gitignore
index c235144..6b96e60 100644
--- a/polygerrit-ui/app/.gitignore
+++ b/polygerrit-ui/app/.gitignore
@@ -1,2 +1,3 @@
/plugins/
/node_modules/
+/tmpl_out/
diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD
index 2f83182..c794b01 100644
--- a/polygerrit-ui/app/BUILD
+++ b/polygerrit-ui/app/BUILD
@@ -1,5 +1,7 @@
load(":rules.bzl", "compile_ts", "polygerrit_bundle")
load("//tools/js:eslint.bzl", "eslint")
+load("//tools/js:template_checker.bzl", "transform_polymer_templates")
+load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test", "npm_package_bin")
package(default_visibility = ["//visibility:public"])
@@ -48,15 +50,176 @@
exclude = [
"node_modules/**",
"node_modules_licenses/**",
- "template_test_srcs/**",
+ "tmpl_out/**", # This directory is created by template checker in dev-mode
"rollup.config.js",
],
),
- include_tests = True,
+ additional_deps = [
+ "@ui_dev_npm//:node_modules",
+ "tsconfig_bazel.json",
+ ],
# The same outdir also appears in the following files:
# wct_test.sh
# karma.conf.js
ts_outdir = "_pg_with_tests_out",
+ ts_project = "tsconfig_bazel_test.json",
+)
+
+# Template checker reports problems in the following files. Ignore the files,
+# so template tests pass.
+# TODO: fix problems reported by template checker in these files.
+ignore_templates_list = [
+ "elements/admin/gr-access-section/gr-access-section_html.ts",
+ "elements/admin/gr-admin-group-list/gr-admin-group-list_html.ts",
+ "elements/admin/gr-admin-view/gr-admin-view_html.ts",
+ "elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_html.ts",
+ "elements/admin/gr-create-change-dialog/gr-create-change-dialog_html.ts",
+ "elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_html.ts",
+ "elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_html.ts",
+ "elements/admin/gr-group-audit-log/gr-group-audit-log_html.ts",
+ "elements/admin/gr-group-members/gr-group-members_html.ts",
+ "elements/admin/gr-group/gr-group_html.ts",
+ "elements/admin/gr-permission/gr-permission_html.ts",
+ "elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_html.ts",
+ "elements/admin/gr-plugin-list/gr-plugin-list_html.ts",
+ "elements/admin/gr-repo-access/gr-repo-access_html.ts",
+ "elements/admin/gr-repo-commands/gr-repo-commands_html.ts",
+ "elements/admin/gr-repo-dashboards/gr-repo-dashboards_html.ts",
+ "elements/admin/gr-repo-detail-list/gr-repo-detail-list_html.ts",
+ "elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_html.ts",
+ "elements/admin/gr-repo/gr-repo_html.ts",
+ "elements/admin/gr-rule-editor/gr-rule-editor_html.ts",
+ "elements/change-list/gr-change-list-item/gr-change-list-item_html.ts",
+ "elements/change-list/gr-change-list-view/gr-change-list-view_html.ts",
+ "elements/change-list/gr-change-list/gr-change-list_html.ts",
+ "elements/change-list/gr-dashboard-view/gr-dashboard-view_html.ts",
+ "elements/change-list/gr-user-header/gr-user-header_html.ts",
+ "elements/change/gr-change-actions/gr-change-actions_html.ts",
+ "elements/change/gr-change-metadata/gr-change-metadata_html.ts",
+ "elements/change/gr-change-requirements/gr-change-requirements_html.ts",
+ "elements/change/gr-change-view/gr-change-view_html.ts",
+ "elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_html.ts",
+ "elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_html.ts",
+ "elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_html.ts",
+ "elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_html.ts",
+ "elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_html.ts",
+ "elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_html.ts",
+ "elements/change/gr-download-dialog/gr-download-dialog_html.ts",
+ "elements/change/gr-file-list-header/gr-file-list-header_html.ts",
+ "elements/change/gr-file-list/gr-file-list_html.ts",
+ "elements/change/gr-label-score-row/gr-label-score-row_html.ts",
+ "elements/change/gr-message/gr-message_html.ts",
+ "elements/change/gr-messages-list/gr-messages-list_html.ts",
+ "elements/change/gr-reply-dialog/gr-reply-dialog_html.ts",
+ "elements/change/gr-reviewer-list/gr-reviewer-list_html.ts",
+ "elements/change/gr-thread-list/gr-thread-list_html.ts",
+ "elements/checks/gr-hovercard-run_html.ts",
+ "elements/core/gr-main-header/gr-main-header_html.ts",
+ "elements/core/gr-search-bar/gr-search-bar_html.ts",
+ "elements/core/gr-smart-search/gr-smart-search_html.ts",
+ "elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog_html.ts",
+ "elements/diff/gr-diff-builder/gr-diff-builder-element_html.ts",
+ "elements/diff/gr-diff-host/gr-diff-host_html.ts",
+ "elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_html.ts",
+ "elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog_html.ts",
+ "elements/diff/gr-diff-view/gr-diff-view_html.ts",
+ "elements/diff/gr-diff/gr-diff_html.ts",
+ "elements/diff/gr-patch-range-select/gr-patch-range-select_html.ts",
+ "elements/documentation/gr-documentation-search/gr-documentation-search_html.ts",
+ "elements/edit/gr-default-editor/gr-default-editor_html.ts",
+ "elements/edit/gr-edit-controls/gr-edit-controls_html.ts",
+ "elements/edit/gr-edit-file-controls/gr-edit-file-controls_html.ts",
+ "elements/edit/gr-editor-view/gr-editor-view_html.ts",
+ "elements/gr-app-element_html.ts",
+ "elements/settings/gr-cla-view/gr-cla-view_html.ts",
+ "elements/settings/gr-edit-preferences/gr-edit-preferences_html.ts",
+ "elements/settings/gr-email-editor/gr-email-editor_html.ts",
+ "elements/settings/gr-identities/gr-identities_html.ts",
+ "elements/settings/gr-registration-dialog/gr-registration-dialog_html.ts",
+ "elements/settings/gr-settings-view/gr-settings-view_html.ts",
+ "elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_html.ts",
+ "elements/shared/gr-account-entry/gr-account-entry_html.ts",
+ "elements/shared/gr-account-label/gr-account-label_html.ts",
+ "elements/shared/gr-account-list/gr-account-list_html.ts",
+ "elements/shared/gr-autocomplete/gr-autocomplete_html.ts",
+ "elements/shared/gr-change-star/gr-change-star_html.ts",
+ "elements/shared/gr-change-status/gr-change-status_html.ts",
+ "elements/shared/gr-comment-thread/gr-comment-thread_html.ts",
+ "elements/shared/gr-comment/gr-comment_html.ts",
+ "elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog_html.ts",
+ "elements/shared/gr-copy-clipboard/gr-copy-clipboard_html.ts",
+ "elements/shared/gr-dialog/gr-dialog_html.ts",
+ "elements/shared/gr-diff-preferences/gr-diff-preferences_html.ts",
+ "elements/shared/gr-download-commands/gr-download-commands_html.ts",
+ "elements/shared/gr-dropdown-list/gr-dropdown-list_html.ts",
+ "elements/shared/gr-dropdown/gr-dropdown_html.ts",
+ "elements/shared/gr-editable-content/gr-editable-content_html.ts",
+ "elements/shared/gr-editable-label/gr-editable-label_html.ts",
+ "elements/shared/gr-hovercard-account/gr-hovercard-account_html.ts",
+ "elements/shared/gr-label-info/gr-label-info_html.ts",
+ "elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_html.ts",
+ "elements/shared/gr-limited-text/gr-limited-text_html.ts",
+ "elements/shared/gr-linked-chip/gr-linked-chip_html.ts",
+ "elements/shared/gr-list-view/gr-list-view_html.ts",
+ "elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_html.ts",
+ "elements/shared/gr-textarea/gr-textarea_html.ts",
+]
+
+# Transform templates into a .ts files.
+templates_srcs = transform_polymer_templates(
+ name = "template_test",
+ srcs = glob(
+ [src_dir + "/**/*" + ext for src_dir in src_dirs for ext in [
+ ".ts",
+ ]],
+ exclude = [
+ "**/*_test.ts",
+ ] + ignore_templates_list,
+ ),
+ out_tsconfig = "tsconfig_template_test.json",
+ tsconfig = "tsconfig_bazel.json",
+ deps = [
+ "tsconfig.json",
+ "tsconfig_bazel.json",
+ "@ui_npm//:node_modules",
+ ],
+)
+
+# Compile transformed templates together with the polygerrit source. If
+# templates don't have problem, then the compilation ends without error.
+# Otherwise, the typescript compiler reports the error.
+# Note, that the compile_ts macro creates build rules. If the build succeed,
+# the macro creates the file compile_template_test.success. The
+# 'validate_polymer_templates' rule tests existence of the file.
+compile_ts(
+ name = "compile_template_test",
+ srcs = templates_srcs + glob(
+ [src_dir + "/**/*" + ext for src_dir in src_dirs for ext in [
+ ".ts",
+ ]],
+ exclude = [
+ "**/*_test.ts",
+ ] + ignore_templates_list,
+ ),
+ additional_deps = [
+ "tsconfig_bazel.json",
+ ],
+ emitJS = False,
+ # Should not run sandboxed.
+ tags = [
+ "local",
+ "manual",
+ ],
+ ts_outdir = "_pg_template_test_out",
+ ts_project = "tsconfig_template_test.json",
+)
+
+# This rule allows to run polymer template checker with bazel test command.
+# For details - see compile_template_test rule.
+sh_test(
+ name = "validate_polymer_templates",
+ srcs = [":empty_test.sh"],
+ data = ["compile_template_test.success"],
)
polygerrit_bundle(
diff --git a/polygerrit-ui/app/empty_test.sh b/polygerrit-ui/app/empty_test.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/polygerrit-ui/app/empty_test.sh
diff --git a/polygerrit-ui/app/rules.bzl b/polygerrit-ui/app/rules.bzl
index feb1a82..5397655 100644
--- a/polygerrit-ui/app/rules.bzl
+++ b/polygerrit-ui/app/rules.bzl
@@ -34,49 +34,55 @@
result.append(_get_ts_compiled_path(outdir, f))
return result
-def compile_ts(name, srcs, ts_outdir, include_tests = False):
- """Compiles srcs files with the typescript compiler
+def compile_ts(name, srcs, ts_outdir, additional_deps = [], ts_project = "tsconfig_bazel.json", emitJS = True, tags = []):
+ """Compiles srcs files with the typescript compiler. The following
+ dependencies are always passed:
+ the file specified by the ts_project argument
+ :tsconfig.json"
+ @ui_npm//:node_modules,
+ If compilation succeed, the file name+".success" is created. This is useful
+ for wrapping compilation in bazel test rules.
Args:
name: rule name
srcs: list of input files (.js, .d.ts and .ts)
- ts_outdir: typescript output directory
+ ts_outdir: typescript output directory; ignored if emitJS is True
+ additional_deps: list of additional dependencies for compilation
+ ts_project: the file with typescript project. If it extends another
+ typescript file, ensure that this other file is either in the default or
+ in the additional_deps dependencies.
+ emitJS: True - the rule generates JS output; otherwise(False) the rule
+ just run a compiler (for error checking)
Returns:
- The list of compiled files
+ The list of compiled JS files if emitJS is True; otherwise returns an
+ empty list
"""
ts_rule_name = name + "_ts_compiled"
# List of files produced by the typescript compiler
- generated_js = _get_ts_output_files(ts_outdir, srcs)
+ generated_js = _get_ts_output_files(ts_outdir, srcs) if emitJS else []
all_srcs = srcs + [
":tsconfig.json",
- ":tsconfig_bazel.json",
"@ui_npm//:node_modules",
- ]
- ts_project = "tsconfig_bazel.json"
+ ] + [ts_project] + additional_deps
- if include_tests:
- all_srcs = all_srcs + [
- ":tsconfig_bazel_test.json",
- "@ui_dev_npm//:node_modules",
- ]
- ts_project = "tsconfig_bazel_test.json"
+ success_out = name + ".success"
# Run the compiler
native.genrule(
name = ts_rule_name,
srcs = all_srcs,
- outs = generated_js,
+ outs = generated_js + [success_out],
cmd = " && ".join([
- "$(location //tools/node_tools:tsc-bin) --project $(location :" +
- ts_project +
- ") --outdir $(RULEDIR)/" +
- ts_outdir +
+ "$(location //tools/node_tools:tsc-bin) --project $(location :{})".format(ts_project) +
+ (" --outdir $(RULEDIR)/{}".format(ts_outdir) if emitJS else "") +
" --baseUrl ./external/ui_npm/node_modules/",
+ "touch $(location {})".format(success_out),
]),
tools = ["//tools/node_tools:tsc-bin"],
+ tags = tags,
)
return generated_js
diff --git a/polygerrit-ui/app/tsconfig.json b/polygerrit-ui/app/tsconfig.json
index 46d0173d..a533a0f 100644
--- a/polygerrit-ui/app/tsconfig.json
+++ b/polygerrit-ui/app/tsconfig.json
@@ -61,6 +61,7 @@
"styles/**/*",
"types/**/*",
"utils/**/*",
- "test/**/*"
+ "test/**/*",
+ "tmpl_out/**/*" //Created by template checker in dev-mode
]
}
diff --git a/tools/js/template_checker.bzl b/tools/js/template_checker.bzl
new file mode 100644
index 0000000..da77234
--- /dev/null
+++ b/tools/js/template_checker.bzl
@@ -0,0 +1,136 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# 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.
+
+"""This file contains macro to run polymer templates check."""
+
+load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test", "npm_package_bin", "params_file")
+load("@rules_pkg//:pkg.bzl", "pkg_tar")
+
+def _get_generated_files(outdir, srcs):
+ result = []
+ for f in srcs:
+ result.append(outdir + "/" + f)
+ return result
+
+def _generate_transformed_templates(name, srcs, tsconfig, deps, out_tsconfig, outdir, dev_run):
+ """Generates typescript code from polymer templates. It uses twinkie package
+ for generation.
+
+ Args:
+ name: rule name
+ srcs: all files in a project project
+ tsconfig: the original typescript project file
+ deps: dependencies
+ out_tsconfig: where to store the generated TS project.
+ outdir: where to store generated .ts files
+ dev_run: if True, the generator uses different file paths in generated
+ import statements. Later, generated files can be copied into workspace
+ for future debugging\\investigation templates issues.
+
+ Returns:
+ The list of generated files
+ """
+ generated_files = _get_generated_files(outdir, srcs)
+
+ # There is a limitation on the command-line length. Put all source files
+ # into a .params file (this is a text file, where each argument is placed
+ # on a new line)
+ params_file(
+ name = name + "_params",
+ out = name + ".params",
+ args = ["$(execpath {})".format(src) for src in srcs],
+ data = srcs,
+ )
+
+ # Arguments for twinkie
+ args = [
+ "$(location //tools/node_tools:twinkie-bin)",
+ "--tsconfig $(location {})".format(tsconfig),
+ "--out-dir $(RULEDIR)/{} ".format(outdir),
+ "--files $(location {})".format(name + ".params"),
+ ]
+ if dev_run:
+ args.append("--dev-run")
+ if out_tsconfig:
+ args.append("--out-ts-config $(location {})".format(out_tsconfig))
+
+ # Execute twinkie.
+ native.genrule(
+ name = name + "_npm_bin",
+ srcs = srcs + deps + [name + ".params"],
+ outs = generated_files + ([out_tsconfig] if out_tsconfig else []),
+ cmd = " ".join(args),
+ tools = ["//tools/node_tools:twinkie-bin"],
+ # Should not run sandboxed.
+ tags = [
+ "local",
+ "manual",
+ ],
+ )
+ return generated_files
+
+def transform_polymer_templates(name, srcs, tsconfig, deps, out_tsconfig):
+ """Transforms polymer templates into typescript code.
+ Additionally, the macro defines name+"_tar" package that contains
+ generated code with slightly different import paths.
+ Note, that polygerrit template tests don't depend on the tar package, so
+ bazel doesn't generate the tar package with the bazel test command.
+ The tar package must be build explicitly with the bazel build command.
+
+ Args:
+ name: rule name
+ srcs: all files in a project project
+ tsconfig: the original typescript project file
+ deps: dependencies
+ out_tsconfig: where to store the generated TS project.
+
+ Returns:
+ list of generated files
+ """
+
+ # Transformed templates for tests
+ generated_files = _generate_transformed_templates(
+ name = name,
+ srcs = srcs,
+ tsconfig = tsconfig,
+ deps = deps,
+ out_tsconfig = out_tsconfig,
+ dev_run = False,
+ outdir = name + "_out",
+ )
+
+ # Transformed templates for developers. Only the tar package depends
+ # on it and it never runs during tests.
+ generated_dev_files = _generate_transformed_templates(
+ name = name + "_dev",
+ srcs = srcs,
+ tsconfig = tsconfig,
+ deps = deps,
+ dev_run = True,
+ outdir = name + "_dev_out",
+ out_tsconfig = None,
+ )
+
+ # Pack all transformed files. Later files can be materialized in the
+ # WORKSPACE/polygerrit-ui/app/tmpl_out dir. The following command do it
+ # automatically
+ # npm run polytest:dev
+ pkg_tar(
+ name = name + "_tar",
+ srcs = generated_dev_files,
+ # Set strip_prefix to keep directory hierarchy in the .tar
+ # https://github.com/bazelbuild/rules_pkg/issues/82
+ strip_prefix = name + "_dev_out",
+ )
+ return generated_files
diff --git a/tools/node_tools/BUILD b/tools/node_tools/BUILD
index 03e3a13..0f836a0 100644
--- a/tools/node_tools/BUILD
+++ b/tools/node_tools/BUILD
@@ -45,3 +45,16 @@
data = ["@tools_npm//:node_modules"],
entry_point = "@tools_npm//:node_modules/typescript/lib/tsc.js",
)
+
+# Wrap twinkie into a twinkie-bin binary.
+nodejs_binary(
+ name = "twinkie-bin",
+ # Point bazel to your node_modules to find the entry point
+ data = ["@npm//:node_modules"],
+ entry_point = "@npm//:node_modules/twinkie/src/app/index.js",
+ # Should not run sandboxed.
+ tags = [
+ "local",
+ "manual",
+ ],
+)
diff --git a/twinkie.patch b/twinkie.patch
new file mode 100644
index 0000000..0a61243
--- /dev/null
+++ b/twinkie.patch
@@ -0,0 +1,11 @@
+--- a/node_modules/twinkie/src/app/index.js
++++ b/node_modules/twinkie/src/app/index.js
+@@ -250,7 +250,7 @@ twinkie --tsconfig tsconfig.json --outdir output_dir [--files file_list] [--outt
+ incremental: false,
+ noEmit: true,
+ },
+- files: [...allProgramFilesNames, generatedFiles],
++ files: [...allProgramFilesNames, ...generatedFiles],
+ };
+ fs.writeFileSync(cmdLineOptions.outputTsConfig, JSON.stringify(tsconfigContent, null, 2));
+ }
diff --git a/yarn.lock b/yarn.lock
index 45b4f2c..faa1e99 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1082,6 +1082,11 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21"
integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==
+"@types/minimatch@3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
+ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
+
"@types/minimist@^1.2.0":
version "1.2.1"
resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz"
@@ -2356,6 +2361,11 @@
raw-body "2.4.0"
type-is "~1.6.17"
+boolbase@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+ integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
+
bower-config@^1.4.0, bower-config@^1.4.1:
version "1.4.3"
resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.3.tgz#3454fecdc5f08e7aa9cc6d556e492be0669689ae"
@@ -2432,7 +2442,7 @@
widest-line "^3.1.0"
wrap-ansi "^7.0.0"
-brace-expansion@^1.1.7:
+brace-expansion@^1.0.0, brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
@@ -2742,6 +2752,18 @@
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
+cheerio@1.0.0-rc.2:
+ version "1.0.0-rc.2"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db"
+ integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=
+ dependencies:
+ css-select "~1.2.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "^3.9.1"
+ lodash "^4.15.0"
+ parse5 "^3.0.1"
+
chokidar@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@@ -3253,6 +3275,16 @@
resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz"
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
+css-select@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
+ integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
+ dependencies:
+ boolbase "~1.0.0"
+ css-what "2.1"
+ domutils "1.5.1"
+ nth-check "~1.0.1"
+
css-slam@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/css-slam/-/css-slam-2.1.2.tgz#3d35b1922cb3e0002a45c89ab189492508c493e5"
@@ -3264,7 +3296,7 @@
parse5 "^4.0.0"
shady-css-parser "^0.1.0"
-css-what@^2.1.0:
+css-what@2.1, css-what@^2.1.0:
version "2.1.3"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
@@ -3547,6 +3579,14 @@
dependencies:
esutils "^2.0.2"
+dom-serializer@0:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
+ integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==
+ dependencies:
+ domelementtype "^2.0.1"
+ entities "^2.0.0"
+
dom-serializer@^1.0.1:
version "1.3.1"
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.1.tgz"
@@ -3556,6 +3596,14 @@
domhandler "^4.0.0"
entities "^2.0.0"
+dom-serializer@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
+ integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
+ dependencies:
+ domelementtype "^1.3.0"
+ entities "^1.1.1"
+
dom-urls@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/dom-urls/-/dom-urls-1.1.0.tgz#001ddf81628cd1e706125c7176f53ccec55d918e"
@@ -3572,11 +3620,23 @@
clone "^2.1.0"
parse5 "^4.0.0"
+domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
+ integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
+
domelementtype@^2.0.1, domelementtype@^2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
+domhandler@^2.3.0:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
+ integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
+ dependencies:
+ domelementtype "1"
+
domhandler@^4.0.0, domhandler@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.1.0.tgz"
@@ -3584,6 +3644,22 @@
dependencies:
domelementtype "^2.2.0"
+domutils@1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
+ integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
+domutils@^1.5.1:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
+ integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
domutils@^2.5.2:
version "2.5.2"
resolved "https://registry.npmjs.org/domutils/-/domutils-2.5.2.tgz"
@@ -3767,6 +3843,11 @@
dependencies:
ansi-colors "^4.1.1"
+entities@^1.1.1, entities@~1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
+ integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
+
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz"
@@ -5355,6 +5436,18 @@
relateurl "0.2.x"
uglify-js "3.4.x"
+htmlparser2@^3.9.1:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
+ integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
+ dependencies:
+ domelementtype "^1.3.1"
+ domhandler "^2.3.0"
+ domutils "^1.5.1"
+ entities "^1.1.1"
+ inherits "^2.0.1"
+ readable-stream "^3.1.1"
+
htmlparser2@^6.0.1:
version "6.1.0"
resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz"
@@ -6498,7 +6591,7 @@
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
-lodash@^4.0.0, lodash@^4.11.1, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.3.0:
+lodash@^4.0.0, lodash@^4.11.1, lodash@^4.15.0, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.3.0:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -6901,6 +6994,13 @@
dependencies:
brace-expansion "^1.1.7"
+minimatch@3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
+ integrity sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=
+ dependencies:
+ brace-expansion "^1.0.0"
+
minimist-options@4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz"
@@ -7172,6 +7272,13 @@
dependencies:
path-key "^3.0.0"
+nth-check@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
+ integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
+ dependencies:
+ boolbase "~1.0.0"
+
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
@@ -7527,6 +7634,13 @@
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
+parse5@^3.0.1:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
+ integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==
+ dependencies:
+ "@types/node" "*"
+
parse5@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
@@ -9882,6 +9996,16 @@
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
+twinkie@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/twinkie/-/twinkie-1.1.2.tgz#c301e4fc26d00d61d3d7e5be030dc6a2264271da"
+ integrity sha512-4KwhyrcrRb0WWJKMX/aT+npmMZC0h+sA//+bLhNupmuKvesrH2vEZDe6yIr48FMWKEsdA2xNdQqw/3MapZ5qXQ==
+ dependencies:
+ "@types/minimatch" "3.0.3"
+ cheerio "1.0.0-rc.2"
+ minimatch "3.0.3"
+ typescript "4.0.5"
+
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
@@ -9939,6 +10063,11 @@
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
+typescript@4.0.5:
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389"
+ integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==
+
typescript@4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.4.tgz#f058636e2f4f83f94ddaae07b20fd5e14598432f"