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

Improve accessibility of Mojo configuration parameters and (partially) use it in M2E #996

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

HannesWell
Copy link
Contributor

This PR aims to improve the accessibility of Mojo configuration parameters by introducing the method IMaven.getMojoConfiguration(MavenProject , MojoExecution , IProgressMonitor ), which returns a ConfigurationElement that allows to traverse the tree that can be formed by a configuration in general.

The advantage are:

  • Enables access to nested elements, not only top-level elements
  • Enables accessing multiple elements of same name
  • In general enables to selectively walk the configuration element tree

The new method is intended as a replacement for the method IMaven.getMojoParameterValue(MavenProject, MojoExecution, String, Class, IProgressMonitor), which returns only the value of a top-level configuration element.
The method IMaven.getMojoParameterValue(MavenProject, String, Class, Plugin, ConfigurationContainer, String, IProgressMonitor) can probably replaced in the same manner.

The new method can for example be used in #981 or if we introduce for example a connector for the Maven clean-plugin to handle additional files to delete.

This PR is a draft that is not yet completed, method names have to/can be adjusted, java-doc has to be added as well as tests.
@mickaelistria, @laeubi what do you think?

@github-actions
Copy link

github-actions bot commented Oct 18, 2022

Unit Test Results

598 tests   592 ✔️  8m 5s ⏱️
  94 suites      6 💤
  94 files        0

Results for commit 3c5a887.

♻️ This comment has been updated with latest results.

Copy link
Member

@kwin kwin left a comment

Choose a reason for hiding this comment

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

Looks good overall, added some minor implementation remarks.

* @since 2.1
*/
public interface ConfigurationElement {
boolean exists();
Copy link
Member

Choose a reason for hiding this comment

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

This seems weird, I would rather throw some exception when invalid names are passed. The top level element should always be valid (even if no explicit configuration is given in the underlying effective pom).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that the top-level element should always be valid and if actually absent should be treated as empty.
But since (some) elements can be present or absent, it is also a valid workflow to check if a certain element exists and only handle it if it exists. Therefore I think throwing an exception in that case is not so convenient and wanted ConfigurationElement to be similar to Optional.

ConfigurationParameter get(String name) throws NoSuchElementException;

// TODO: or getAll() or similar.
Stream<ConfigurationParameter> children(String name) throws NoSuchElementException;
Copy link
Member

Choose a reason for hiding this comment

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

name is always unique except for collections (https://maven.apache.org/guides/mini/guide-configuring-plugins.html#mapping-collections-and-arrays). I don't think that we need to support that here, I one is interested in getting the collection she/he can call get("rootElementForCollection).as(Collection.class).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is a good point. But if one calls get("rootElementForCollection).as(Collection.class) the elements of the returned collection are (probably) of the type used in the Mojo, which are usually not available in a connector. I think it is better to have a collection/stream of ConfiguraitonElements here so that a caller can further query on this abstract/proxy level.

However, I have to admit I never actually had such case yet and therefore should create a test-case for that. Nevertheless I think it is relevant for the example given initially.

}

private String formatAsDirectory(String directory) {
return directory.replace(GROUP_SEPARATOR, PATH_SEPARATOR);
private class ConfigurationElementImpl implements ConfigurationElement {
Copy link
Member

Choose a reason for hiding this comment

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

I would put this and related classes to a dedicated file.

Copy link
Contributor Author

@HannesWell HannesWell Oct 18, 2022

Choose a reason for hiding this comment

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

Actually I have no strong opinion about that.
But the MavenImpl class is already quite large and moving the configuration related classes into a dedicated class makes it simpler to overview that story.
-> Moved it.

public <T> T as(Class<T> clazz) throws NoSuchElementException {
if(!exists()) {
throw new NoSuchElementException(
"Plugin execution " + valueComputer.mojo.getId() + "does not have a configuration parameter " + name);
Copy link
Member

Choose a reason for hiding this comment

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

this should emit the full path to the parameter

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The name/path is already the full path. When a new ConfigurationParameterImpl is created the parents path concatenated with the elements name is passed as path.

Advantages:
- Enables access to nested elements
- Enables accessing multiple elements of same name
- In general enables to selectively walk the configuration element tree
@mickaelistria
Copy link
Contributor

I'm skeptical in general about the idea of m2e building a different model and new classes for concepts that are mostly already expressed by Maven API. This makes m2e much harder to understand IMO, while sticking to Maven API is actually keeping things simple. For this case, I believe that instead of a IConfigurationElement model, some "MojoConfigurationHelper" that has static method to manipulate Maven's MojoExecution and other plain Maven types would in the end be simpler.

@HannesWell
Copy link
Contributor Author

I'm skeptical in general about the idea of m2e building a different model and new classes for concepts that are mostly already expressed by Maven API. This makes m2e much harder to understand IMO, while sticking to Maven API is actually keeping things simple. For this case, I believe that instead of a IConfigurationElement model, some "MojoConfigurationHelper" that has static method to manipulate Maven's MojoExecution and other plain Maven types would in the end be simpler.

The configuration elements should only be read, but should not be changed (in case you mean that by manipulating).
I think what should be provided by the new method and what (probably) actually wants is simply the full PlexusConfiguration of the mojo execution. Actually the only reason why we can use the raw configuration from the dom is that it can contain unresolved property/variable references.
So instead of inventing a new API we could just reuse PlexusConfiguration and use a ready-only implementation (subclass) that resolves values on demand using the means already used at the moment.
This way a user gets a PlexusConfiguration that looks like it contains only resolved values and does not permit writes (e.g. throws a UnsupportedOperationException).
Since the PlexusConfiguration API is much older it is a bit old fashion (i.e. it uses Arrays instead of Collection/Stream), but at least users of the Maven-API are used to it.

@kwin
Copy link
Member

kwin commented Oct 28, 2022

To give more context: In #981 there was the need to evaluate nested Mojo parameters and currently there is no support for that. I proposed the simpler approach https://github.com/eclipse-m2e/m2e-core/pull/981/files#diff-367681037e5adcf9592ed08e4e4ae7e8e7372a00b38d77e4d66bcb7f8e60b59dR733. Maybe there is a third alternative you have in mind @mickaelistria...

@laeubi
Copy link
Member

laeubi commented Oct 29, 2022

As mentioned elsewhere, I don't think Mojo Parameters are a concern of IMaven and we should get rid of it here, move it to the MavenToolbox or a dedicated place.

@kwin
Copy link
Member

kwin commented Oct 29, 2022

Mojo parameters can be evaluated with m2e 2.0 via IMaven already. I am fine with deprecating that method but please stay backwards compatible this time.

@laeubi
Copy link
Member

laeubi commented Oct 29, 2022

Mojo parameters can be evaluated with m2e 2.0 via IMaven already.

But this does not mean we should add new ones...

I am fine with deprecating that method but please stay backwards compatible this time.

There is no backward-compatible way for deprecation.

@kwin
Copy link
Member

kwin commented Oct 29, 2022

@laeubi It seems you don’t get the point about deprecation. It gives downstream consumers time to migrate and an indication where to migrate to. Final removal of deprecated items should only be done in m2e 3.0 earliest. And deprecating a method is fully backwards compatible!

@laeubi
Copy link
Member

laeubi commented Oct 29, 2022

Final removal of deprecated items should only be done in m2e 3.0 earliest

It should not, it will happen at 3.0 ...

@HannesWell
Copy link
Contributor Author

HannesWell commented Oct 29, 2022

Final removal of deprecated items should only be done in m2e 3.0 earliest

It should not, it will happen at 3.0 ...

Yes, with 3.0 (whenever this will be) not earlier and not later. And with #996 there will be a proper deprecation notice including the path for migration. So this time the migration should be clear. :)

@HannesWell
Copy link
Contributor Author

As mentioned elsewhere, I don't think Mojo Parameters are a concern of IMaven and we should get rid of it here, move it to the MavenToolbox or a dedicated place.

A note about the remarks in #981:

  • Plug-in executions are usually bound to a project, so the new methods could be part of the MavenProjectFacadade or in any other project bound api.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants