Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add concrete JsPlugin #4925

Merged
merged 14 commits into from
Dec 14, 2023
Merged

Add concrete JsPlugin #4925

merged 14 commits into from
Dec 14, 2023

Conversation

devinrsmith
Copy link
Member

@devinrsmith devinrsmith commented Dec 7, 2023

This PR gives a concrete structure to JsPlugin; name, version, main, path, and paths. All existing means of configuration for JS plugins delegates to JsPlugin. Java jars can now provide JS plugins with this change as well.

This is also a partial improvement for #4817 (JS Plugins development is slow), in that JsPlugin paths is a mean to reduce the scope of files that needs to be copied. This is not a full solution (which may involve routing paths in Jetty that lead directly to the resources as configured via the JS plugins).

For NPM packages, this PR takes a practical approach as opposed to a "perfect" approach; we are requiring that all "real" files be included under the top-level directory as specified by package.json/main. For example, if main is "build/index.js", we'll include everything under "build/". If main is "dist/bundle/index.js", we'll include everything under "dist/".

The inclusion of the matching python structures will follow shortly, either as additional commits to this PR, or as follow-up PR.

Adds testing, fixes #4893

This PR gives a concrete structure to JsPlugin; name, version, main, root, and paths. All existing means of configuration for JS plugins delegates to JsPlugin. Java jars can now provide JS plugins with this change as well.

This is also a _partial_ improvement for deephaven#4817 (JS Plugins development is slow), in that JsPlugin paths is a mean to reduce the scope of files that needs to be copied. This is _not_ a full solution (which may involve routing paths in Jetty that lead directly to the resources as configured via the JS plugins).

For NPM packages, this PR takes a practical approach as opposed to a "perfect" approach; we are requiring that all "real" files be included under the top-level directory as specified by package.json/main. For example, if main is "build/index.js", we'll include everything under "build/". If main is "dist/bundle/index.js", we'll include everything under "dist/".

The inclusion of the matching python structures will follow shortly, either as additional commits to this PR, or as follow-up PR.

Adds testing, fixes deephaven#4893
@devinrsmith devinrsmith added DocumentationNeeded plug-ins javascript Pull requests that update Javascript code ReleaseNotesNeeded Release notes are needed labels Dec 7, 2023
@devinrsmith devinrsmith added this to the November 2023 milestone Dec 7, 2023
@devinrsmith devinrsmith self-assigned this Dec 7, 2023
@devinrsmith
Copy link
Member Author

I've added the deephaven-core glue layer for the existing (but never used) python type deephaven.plugin.js.JsPlugin. I think we may want to update that type w/ some new naming and docs, but the existing structure will probably look very similar.


import java.nio.file.PathMatcher;

interface PathsInternal extends Paths, PathMatcher {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsolicited advice, and unimportant for this iteration, but might be handy if considering using PathMatcher more generally: FileSystems.getDefault().getPathMatcher(...) supports glob: patterns, but if you do, take care to note that **/* does not match files in the current dir (that is, something which * would match).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - I considered making PathMatcher the public API, but I don't know what sort of interface limitations we might wish we had imposed if we want an "easy" route-based integration w/ jetty.



def to_j_js_plugin(js_plugin: JsPlugin) -> jpy.JType:
# TODO: update deephaven-plugin JsPlugin, probably rename distribution_path to root (to match JsPlugin?)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(if my comment isnt already outdated...) i'm guessing this is pending in the deephaven-plugin repo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any code yet; but it's simple once we decide the naming we are OK w/. deephaven/deephaven-plugin#15

# Note: this only works for "normally" distributed / installed packages.
# In cases where the package is distributed as zip, we'll need additional logic to create a zip resource path,
# or copy the data into a temporary directory.
# See note about zip from https://docs.python.org/3.11/library/importlib.resources.html#importlib.resources.path
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we detect and throw/warn about this case? @jmao-denver is this case at all common?

also I know that https://peps.python.org/pep-0441/ exists, is supported, but probably not by us

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's pretty uncommon; that said, I suspect there is a way to use create proper zip URI/Path if it comes down to it. I'm guessing we can look at the return type to figure out. Somewhat relevant discussion around this topic, python/cpython#99818

// If listing and traversing the contents of development directories (and skipping the copy) becomes
// too expensive, we can add logic here wrt PathsInternal/PathsPrefix to specify a dirMatcher. Or,
// properly route directly from the filesystem via Jetty.
CopyHelper.copyRecursive(plugin.root(), dstPath, d -> true, pathMatcher);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only usage of dirMatcher, and d -> true here as a constant, inline into CopyHelper.copyRecursive (esp since that is package protected and will never be called by user code)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do - I think there's a chance we'll end up using dirMatcher in the future (if, for some reason we are unable to use a jetty route-based approach), so I'll keep the underlying impl.

@JsonProperty(MAIN)
public abstract String main();

// Note: do we want "files" here, and actually try to parse it? Or, "deephaven" object that more closely matches
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tag with a follow-up ticket?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update the comment and link to #4817, which I think is sufficient.

devinrsmith added a commit to devinrsmith/deephaven-plugin that referenced this pull request Dec 11, 2023
In addition, updates JsPlugin documentation to be consistent with deephaven/deephaven-core#4925

Fixes deephaven#15
devinrsmith added a commit to deephaven/deephaven-plugin that referenced this pull request Dec 13, 2023
In addition, updates JsPlugin documentation to be more consistent with deephaven/deephaven-core#4925

Fixes #15
devinrsmith added a commit that referenced this pull request Dec 13, 2023
This bump is to minimize the bump needed wrt #4925
plugin/src/main/java/io/deephaven/plugin/js/JsPlugin.java Outdated Show resolved Hide resolved

import java.nio.file.Path;

public interface Paths {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might consider a different class name here - when dealing with java.nio.file.Path instances, it is common to use java.nio.file.Paths to create them.

Also, javadoc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to best rename it if necessary - I'm personally less offended by names that overlap in these regards, although I know others disagree. At least java.nio.file.Paths is somewhat discouraged in their javadoc:

 * @apiNote
 * It is recommended to obtain a {@code Path} via the {@code Path.of} methods
 * instead of via the {@code get} methods defined in this class as this class
 * may be deprecated in a future release.

niloc132
niloc132 previously approved these changes Dec 14, 2023
Copy link
Contributor

@jmao-denver jmao-denver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python changes LGTM

@devinrsmith devinrsmith enabled auto-merge (squash) December 14, 2023 21:11
@devinrsmith devinrsmith merged commit aadf4c8 into deephaven:main Dec 14, 2023
19 checks passed
@devinrsmith devinrsmith deleted the js-plugins-v2 branch December 14, 2023 21:16
@github-actions github-actions bot locked and limited conversation to collaborators Dec 14, 2023
@deephaven-internal
Copy link
Contributor

Labels indicate documentation is required. Issues for documentation have been opened:

How-to: https://github.com/deephaven/deephaven.io/issues/3550
Reference: https://github.com/deephaven/deephaven.io/issues/3549

Comment on lines +46 to +47
* and the file "/path-to/my-plugin/dist/index.js" would be served at "js-plugins/foo/dist/index.js". All other files of
* the form "/path-to/my-plugin/{somePath}" will be served at "js-plugins/foo/{somePath}".
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems kind of redundant - why not just say "All files of from "/path-to/my-plugin/{somePath}" will be served at "js-plugins/foo/{somePath}"? The main by definition is going to be relative to that path, ergo must always be served.

}

/**
* The JS plugin name. The JS plugin contents will be served via the URL path "js-plugins/{name}/", as well as
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should note that name can have a / in it for subfolders. Likely important to note that we do not want to URL encode that /, we want it to actually be at js-plugins/@scope/name, not js-plugins/@scope%2Fname

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
DocumentationNeeded javascript Pull requests that update Javascript code plug-ins ReleaseNotesNeeded Release notes are needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add testing for JsPlugins
6 participants