1f7c13f3a5
* stable-2.15: PolyGerrit: Update documentation Support for GWT to PolyGerrit integration plugin migration Update the plugin development documentation. Update PolyGerrit plugin documentation Change-Id: I6b80221d85d3c045f935e8d2accfc23519293c70
153 lines
4.9 KiB
Plaintext
153 lines
4.9 KiB
Plaintext
= Gerrit Code Review - PolyGerrit Plugin Development
|
|
|
|
CAUTION: Work in progress. Hard hat area. Please
|
|
link:https://bugs.chromium.org/p/gerrit/issues/entry?template=PolyGerrit%20plugins[send
|
|
feedback] if something's not right.
|
|
|
|
[[migration]]
|
|
== Incremental migration of existing GWT UI plugins
|
|
|
|
link:pg-plugin-dev.html[PolyGerrit plugin API] is based on different concepts and
|
|
provides a different type of API compared to the one available to GWT
|
|
plugins. Depending on the plugin, it might require significant modifications to
|
|
existing UI scripts to fully take advantage of the benefits provided by the PolyGerrit API.
|
|
|
|
To make migration easier, PolyGerrit recommends an incremental migration
|
|
strategy. Starting with a .js file that works for GWT UI, plugin author can
|
|
incrementally migrate deprecated APIs to the new plugin API.
|
|
|
|
The goal for this guide is to provide a migration path from .js-based UI script to
|
|
a html based implementation
|
|
|
|
NOTE: Web UI plugins distributed as a single .js file are not covered in this
|
|
guide.
|
|
|
|
Let's start with a basic plugin that has an UI module. Commonly, file tree
|
|
should look like this:
|
|
|
|
├── BUILD
|
|
├── LICENSE
|
|
└── src
|
|
└── main
|
|
├── java
|
|
│ └── com
|
|
│ └── foo
|
|
│ └── SamplePluginModule.java
|
|
└── resources
|
|
└── static
|
|
└── sampleplugin.js
|
|
|
|
For simplicity's sake, let's assume SamplePluginModule.java has following
|
|
content:
|
|
|
|
``` java
|
|
public class SamplePluginModule extends AbstractModule {
|
|
|
|
@Override
|
|
protected void configure() {
|
|
DynamicSet.bind(binder(), WebUiPlugin.class)
|
|
.toInstance(new JavaScriptPlugin("sampleplugin.js"));
|
|
}
|
|
}
|
|
```
|
|
|
|
=== Step 1: Create `sampleplugin.html`
|
|
|
|
As a first step, create `sampleplugin.html` and include the UI script in the
|
|
module file.
|
|
|
|
NOTE: GWT UI ignores html files which it doesn't support.
|
|
|
|
``` java
|
|
@Override
|
|
protected void configure() {
|
|
DynamicSet.bind(binder(), WebUiPlugin.class)
|
|
.toInstance(new JavaScriptPlugin("sampleplugin.js"));
|
|
DynamicSet.bind(binder(), WebUiPlugin.class)
|
|
.toInstance(new JavaScriptPlugin("sampleplugin.html"));
|
|
}
|
|
```
|
|
|
|
Here's recommended starter code for `sampleplugin.html`:
|
|
|
|
NOTE: By specification, the `id` attribute of `dom-module` *must* contain a dash
|
|
(-).
|
|
|
|
``` html
|
|
<dom-module id="sample-plugin">
|
|
<script>
|
|
Gerrit.install(plugin => {
|
|
// Setup block, is executed before sampleplugin.js
|
|
|
|
// Install deprecated JS APIs (onAction, popup, etc)
|
|
plugin.deprecated.install();
|
|
});
|
|
</script>
|
|
|
|
<script src="./sampleplugin.js"></script>
|
|
|
|
<script>
|
|
Gerrit.install(plugin => {
|
|
// Cleanup block, is executed after sampleplugin.js
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
```
|
|
|
|
Here's how this works:
|
|
|
|
- PolyGerrit detects migration scenario because UI scripts have same filename
|
|
and different extensions
|
|
* PolyGerrit will load `sampleplugin.html` and skip `sampleplugin.js`
|
|
* PolyGerrit will reuse `plugin` (aka `self`) instance for `Gerrit.install()`
|
|
callbacks
|
|
- `sampleplugin.js` is loaded since it's referenced in `sampleplugin.html`
|
|
- setup script tag code is executed before `sampleplugin.js`
|
|
- cleanup script tag code is executed after `sampleplugin.js`
|
|
- `plugin.deprecated.install()` enables deprecated APIs (onAction(), popup(),
|
|
etc) before `sampleplugin.js` is loaded
|
|
|
|
This means the plugin instance is shared between .html-based and .js-based
|
|
code. This allows to gradually and incrementally transfer code to the new API.
|
|
|
|
=== Step 2: Create cut-off marker in `sampleplugin.js`
|
|
|
|
Commonly, window.Polymer is being used to detect in GWT UI script if it's being
|
|
executed inside PolyGerrit. This could be used to separate code that was already
|
|
migrated to new APIs from old not yet migrated code.
|
|
|
|
During incremental migration, some of the UI code will be reimplemented using
|
|
the PolyGerrit plugin API. However, old code still could be required for the plugin
|
|
to work in GWT UI.
|
|
|
|
To handle this case, add the following code at the end of the installation
|
|
callback in `sampleplugin.js`
|
|
|
|
``` js
|
|
Gerrit.install(function(self) {
|
|
|
|
// Existing code here, not modified.
|
|
|
|
if (window.Polymer) { return; } // Cut-off marker
|
|
|
|
// Everything below was migrated to PolyGerrit plugin API.
|
|
// Code below is still needed for the plugin to work in GWT UI.
|
|
});
|
|
```
|
|
|
|
=== Step 3: Migrate!
|
|
|
|
The code that uses deprecated APIs should be eventually rewritten using
|
|
non-deprecated counterparts. Duplicated pieces could be kept under cut-off
|
|
marker to work in GWT UI.
|
|
|
|
If some data or functions needs to be shared between code in .html and .js, it
|
|
could be stored in the `plugin` (aka `self`) object that's shared between both
|
|
|
|
=== Step 4: Cleanup
|
|
|
|
Once deprecated APIs are migrated, `sampleplugin.js` will only contain
|
|
duplicated code that's required for GWT UI to work. As soon as GWT support is removed from Gerrit
|
|
that file can be simply deleted, along with the script tag loading it.
|
|
|