google / jsinterop-generator

Generates Java annotated with JsInterop from JavaScript extern sources
Apache License 2.0
74 stars 24 forks source link

Allowing a generated project to depend on another generated project (like elemental2) #43

Open niloc132 opened 4 years ago

niloc132 commented 4 years ago

Technically I did get this to work, but it seems awkward, and so I am probably using jsinterop-generator or bazel wrong, or both.

I have a new git repo of a bazel project using jsinterop-generator to turn some closure-compiler provided externs into jsinterop Java. As with any set of externs I can imagine, this depends on some elemental2 content - both core and dom - so I wrote the jsinterop_generator target like this:

jsinterop_generator(
    name = "googlemaps",
    srcs = [":google_maps_api_patched.js"],
    extension_type_prefix = "Maps",
    integer_entities_files = ["integer_entities.txt"],
    # override auto generated js_deps in order not to provide extern files
    # Common extern file are included by default.
    j2cl_js_deps = [],
    deps = [
        "//third_party:elemental2-core",
        "//third_party:elemental2-dom",
    ],
)

In keeping with bazel conventions, I created an alias for elemental2-core and dom in third_party/, which reference the targets that elemental2 provides:

alias(
    name = "elemental2-core",
    actual = "@com_google_elemental2//:elemental2-core",
)
alias(
    name = "elemental2-dom",
    actual = "@com_google_elemental2//:elemental2-dom",
)

This however was not sufficient. In addition to those two targets, these four are also required in that same BUILD file, and would generally be emitted automatically a jsinterop_generator invocation.

alias(
    name = "elemental2-core-j2cl",
    actual = "@com_google_elemental2//:elemental2-core-j2cl",
)
alias(
    name = "elemental2-dom-j2cl",
    actual = "@com_google_elemental2//:elemental2-dom-j2cl",
)
alias(
    name = "elemental2-core__internal_src_generated",
    actual = "@com_google_elemental2//:elemental2-core__internal_src_generated",
)
alias(
    name = "elemental2-dom__internal_src_generated",
    actual = "@com_google_elemental2//:elemental2-dom__internal_src_generated",
)

The only other thought I had to make these work cleanly was to avoid alias() and instead use jsinterop_generator() in third party:

jsinterop_generator(
    name = "elemental2-core",
    exports = ["@com_google_elemental2//:elemental2-core"],
)
jsinterop_generator(
    name = "elemental2-dom",
    exports = ["@com_google_elemental2//:elemental2-dom"],
)

But that seems a bit silly, and doesn't appear to work (jsinterop_generator perhaps is concating labels assuming that targets are local?):

ERROR: /home/colin/workspace/gwt-googlemaps-api/third_party/BUILD:19:1: //third_party:elemental2-core__internal_src_generated: invalid label '//third_party/@com_google_elemental2//:elemental2-core__internal_src_generated' in element 0 of attribute 'exports' in '_jsinterop_generator_export' rule: invalid package name 'third_party/@com_google_elemental2//': package names may not end with '/'
ERROR: /home/colin/workspace/gwt-googlemaps-api/third_party/BUILD:19:1: //third_party:elemental2-core-j2cl: invalid label '//third_party/@com_google_elemental2//:elemental2-core-j2cl' in element 0 of attribute 'exports' in 'j2cl_library' rule: invalid package name 'third_party/@com_google_elemental2//': package names may not end with '/'
ERROR: /home/colin/workspace/gwt-googlemaps-api/third_party/BUILD:19:1: //third_party:elemental2-core: invalid label '//third_party/@com_google_elemental2//:elemental2-core' in element 0 of attribute 'exports' in 'java_library' rule: invalid package name 'third_party/@com_google_elemental2//': package names may not end with '/'
ERROR: /home/colin/workspace/gwt-googlemaps-api/third_party/BUILD:23:1: //third_party:elemental2-dom__internal_src_generated: invalid label '//third_party/@com_google_elemental2//:elemental2-dom__internal_src_generated' in element 0 of attribute 'exports' in '_jsinterop_generator_export' rule: invalid package name 'third_party/@com_google_elemental2//': package names may not end with '/'
ERROR: /home/colin/workspace/gwt-googlemaps-api/third_party/BUILD:23:1: //third_party:elemental2-dom-j2cl: invalid label '//third_party/@com_google_elemental2//:elemental2-dom-j2cl' in element 0 of attribute 'exports' in 'j2cl_library' rule: invalid package name 'third_party/@com_google_elemental2//': package names may not end with '/'
ERROR: /home/colin/workspace/gwt-googlemaps-api/third_party/BUILD:23:1: //third_party:elemental2-dom: invalid label '//third_party/@com_google_elemental2//:elemental2-dom' in element 0 of attribute 'exports' in 'java_library' rule: invalid package name 'third_party/@com_google_elemental2//': package names may not end with '/'
ERROR: error loading package 'third_party': Package 'third_party' contains errors

What is the expected way to invoke jsinterop_generator() in a bazel project, without just forking elemental2 and including its own setup directly in our projects?

Full project is available at https://github.com/Vertispan/gwt-googlemaps-api, but please note that until https://github.com/google/elemental2/issues/137 is resolved, this repo will not build as-is, you need a local_repository of elemental2 with the latest commit reverted.

jDramaix commented 4 years ago

First I don't think you need to use a third_party package in your project. We mostly do that for introducing an indirection in the way we define our external (to our project) dependencies. We have two build files for the third_party package: one for our internal build (that is not sync on github) and another for the opensource build (that is not seen by our internal build system).

Second, jsinterop_generator is a macro not a rule and you can not alias it. The macro creates several rules and you will need to to alias all of these rules.

That being said, you should be able to use the exports field of the jsinterop_generator macro to achieve what you want. So there is a bug there. Could you close this issue and open a new one for the errors you got when you use exports ?