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

[MRESOLVER-494] The LOCAL_PATH system property is client app property #428

Merged
merged 7 commits into from
Feb 13, 2024

Conversation

cstamas
Copy link
Member

@cstamas cstamas commented Feb 10, 2024

This ArtifactProperty is specific to "system" scope, tied to it. Introduce a "system scope handler" that does all, and let client app control all. Also, this component belongs to session, so expose it via session.


https://issues.apache.org/jira/browse/MRESOLVER-494

This ArtifactProperty is specific to "system" scope, tied to it.
Introduce a "system scope handler" that does all, and let client
app control all. Also, this component belongs to session, so
expose it via session.

---

https://issues.apache.org/jira/browse/MRESOLVER-494
@cstamas cstamas self-assigned this Feb 10, 2024
protected static boolean isLackingDescriptor(Artifact artifact) {
return artifact.getProperty(ArtifactProperties.LOCAL_PATH, null) != null;
protected static boolean isLackingDescriptor(RepositorySystemSession session, Artifact artifact) {
return session.getSystemScopeHandler().getSystemPath(artifact.getProperties()) != null;
Copy link
Member Author

@cstamas cstamas Feb 10, 2024

Choose a reason for hiding this comment

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

This makes me think that "system" scope and an "artifact with LOCAL_PATH having set" are one and same (are same thing, synonyms so to say). We may want to handle that as one, instead to have them separated?
Still, especially in depMgt, there are cases where path is unset, but scope remains... so maybe this "handler" is still ok?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not really sure to understand what you're suggesting here...

Copy link
Member Author

@cstamas cstamas Feb 12, 2024

Choose a reason for hiding this comment

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

If you look at "system" scope definition, there is this sentence "Dependency in this scope does not have artifact descriptor either.". And this here is the check "does it have descriptor". And since Resolver 1.0 the actual check is done like this: artifact.getProperty( ArtifactProperties.LOCAL_PATH, null ) != null (presence of property and not actual scope).

@@ -43,7 +42,7 @@ public abstract class AbstractDependencyManager implements DependencyManager {
* @deprecated To be removed when deprecated constructors are removed.
*/
@Deprecated
protected static final SystemScopePredicate SYSTEM_PREDICATE = "system"::equals;
protected static final SystemScopeHandler SYSTEM_PREDICATE = SystemScopeHandler.LEGACY;
Copy link
Member

Choose a reason for hiding this comment

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

SYSTEM_PREDICATE -> SYSTEM_SCOPE_HANDLER

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

*
* @return the system path from passed in properties, or {@code null} if not present.
*/
String getSystemPath(Map<String, String> properties);
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we should abstract slightly more and have:

String getSystemPath(Artifact artifact);

* Sets system path in properties. The passed in {@code systemPath} can be {@code null}, in which case this is
* "remove" operation (or "unset").
*/
void setSystemPath(Map<String, String> properties, String systemPath);
Copy link
Contributor

Choose a reason for hiding this comment

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

This method does not make much sense to me. It should not be needed, as the code calling the resolver is now responsible for the system scope. The resolver should not alter what has been given.

Copy link
Member Author

Choose a reason for hiding this comment

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

Problem is how Artifact is immutable, so it does not have setProperty method. Also, due this, Artifact#setProperties returns new Artifact instance (as almost every mutator method in Resolver).

Copy link
Contributor

@gnodet gnodet Feb 13, 2024

Choose a reason for hiding this comment

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

I don't think we need this method. We can just delay until the very end of the resolution, then call SystemScopeManager#getSystemPath(Artifact) and put it as the resolved path of the artifact.
We don't need to carry the path for the duration of the resolution imho.

Copy link
Member Author

Choose a reason for hiding this comment

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

This method is used in two cases:

  • when dependency scope is managed, and is not "system", unset the LOCAL_PATH if set
  • when dependency scope is managed, and is "system", make sure LOCAL_PATH is set

Given this may happen on any (n-th level of depth), am again unsure from where would you get (and which) artifact to call with getSystemPath()? As now, especially with introduction of "transitive dep mgr", we should track introduced depMgr sections during construction of whole graph (unlike it was in Maven3, only 2 depths).

/**
* Returns {@code true} if given scope label is "system" scope.
*/
boolean isSystemScope(String scope);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is scope supposed to be nullable ? It seems the code is given null. If that's really expected we should indicate that on the 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 think javadoc is quite clear on this matter. If you consider null "system" scope, then yet, return true here.

* Returns {@code true} if given dependency is in "system" scope.
*/
default boolean isSystemScope(Dependency dependency) {
return isSystemScope(dependency.getScope());
Copy link
Contributor

Choose a reason for hiding this comment

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

Is dependency nullable or not ?
If yes, we should test for a null dependency and have:

    return dependency != null && isSystemScope(dependency.getScope());

* Returns {@code true} if given dependency node dependency is in "system" scope.
*/
default boolean isSystemScope(DependencyNode dependencyNode) {
return dependencyNode.getDependency() != null && isSystemScope(dependencyNode.getDependency());
Copy link
Contributor

Choose a reason for hiding this comment

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

dependencyNode may be null here too

Map<String, String> properties =
new HashMap<>(dependency.getArtifact().getProperties());
properties.remove(ArtifactProperties.LOCAL_PATH);
systemScopeHandler.setSystemPath(properties, null);
Copy link
Contributor

Choose a reason for hiding this comment

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

I fail to see how this code is relevant.
If this is really needed ? that would mean that the scope isn't solely determined by the dependency.getScope().

Copy link
Member Author

Choose a reason for hiding this comment

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

Obviously is not, that was my concern here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not needed or not only determined by the scope ?

if ((systemScopePredicate.test(scope))
|| (scope == null && systemScopePredicate.test(dependency.getScope()))) {
if ((systemScopeHandler.isSystemScope(scope))
|| (scope == null && systemScopeHandler.isSystemScope(dependency.getScope()))) {
String localPath = managedLocalPaths.get(key);
Copy link
Contributor

Choose a reason for hiding this comment

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

The managedLocalPaths should be integrated into the systemScopeHandler imho.

Copy link
Member Author

@cstamas cstamas Feb 13, 2024

Choose a reason for hiding this comment

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

systemScopeHandler is session scoped, while managedLocalPaths is per mgr, and mgr is created as needed (see "deriveChildManager") per collection invocation, so unsure how could we do that.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't really see a use case in the code where scope == "system" and localPath != null are not interchangeable. So I think we don't need to manage the local paths, they'll just be retrieved from the SystemScopeHandler when needed using getSystemPath(Artifact).

@gnodet
Copy link
Contributor

gnodet commented Feb 13, 2024

@cstamas Here's what I have in mind: gnodet@791c07e
The local path is only managed by the scope handler. The assumption is that for a given artifact, if it has a system scope, it also has a local path. Maybe I'm missing something though ...

@cstamas
Copy link
Member Author

cstamas commented Feb 13, 2024

@cstamas Here's what I have in mind: gnodet@791c07e The local path is only managed by the scope handler. The assumption is that for a given artifact, if it has a system scope, it also has a local path. Maybe I'm missing something though ...

You do: i.e. you have a dep w/o scope, but you define a depMgmt w/ system scope (and system path), who will apply then that mgmt onto dependency? Also, this may come from n-th level now, as we introduced "transitive depmgr" etc.

Your change merely removed management of "system" scope from depManager... that is wrong, and will probably explode in Maven ITs (but we should see).

@cstamas cstamas merged commit 7280c24 into apache:master Feb 13, 2024
4 checks passed
@cstamas cstamas deleted the MRESOLVER-494 branch February 13, 2024 14:30
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.

3 participants