-
Notifications
You must be signed in to change notification settings - Fork 189
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
PR for issue 1711 - master #2425
PR for issue 1711 - master #2425
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine in general but some adjustments should be performed!
tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionFileTest.java
Show resolved
Hide resolved
@@ -117,6 +118,11 @@ private void debugCacheMiss(ResolutionArguments arguments) { | |||
} | |||
} | |||
|
|||
public URI resolveRepositoryLocation(String location) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we probably move the code for resolving variables from TargetDefinitionResolver
into TargetDefinitionResolverService
then? Also I think there should be exactly one method to replace variables, the parsing into an URL should happen at the relevant place, or we can have helper methods that call the generic one like resolveAsURI, resolveAsFile resolveAs...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we probably move the code for resolving variables from TargetDefinitionResolver into TargetDefinitionResolverService then?
Well yes, but then we have to pass TargetDefinitionResolverService
into TargetDefinitionResolver
as some sort of callback for resolving variables because the resolve*
methods are needed deep in the code of TargetDefinitionResolver
.
Maybe you had something like this in mind?
interface TargetDefinitionVariableResolver {
String resolveVariable(String raw);
}
class TargetDefinitionResolverService implements TargetDefinitionVariableResolver{
String resolveVariable(String raw){
// move code for env_var, systep_prop and project_loc here
}
CompletableFuture<TargetDefinitionContent> resolveFromArguments(ResolutionArguments arguments) {
...
var resolver = new TargetDefinitionResolver(this, arguments.environments, ...);
resolver.resolveContent(...)
}
class TargetDefinitionResolver {
final TargetDefinitionVariableResolver varResolver;
TargetDefinitionResolver(TargetDefinitionVariableResolver varResolver, ...){}
TargetDefinitionContent resolveContentWithExceptions(TargetDefinition definition, ...){
...
} else if (locationDefinition instanceof PathLocation pathLocation) {
String resolvePath = varResolver.resolvePath(pathLocation.getPath(), definition);
...
}
}
personally I prefer having the resolution in TargetDefinitionResolver
and delegating to it from TargetDefinitionResolverService
where necessary but it is your call
Also I think there should be exactly one method to replace variables,
ok I can do that, I did it as a separate method because I didn't want repository location to support project_loc
as that makes no sense to me but I guess there is no harm in having that option available and just never user rather than creating special value for it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having a TargetDefinitionVariableResolver
makes sense, maybe even as a separate component (it seems the mojos only reference TargetDefinitionResolverService
because the actually want to resolve variables).
I did it as a separate method because I didn't want repository location to support project_loc as that makes no sense to me but I guess there is no harm in having that option available and just never user rather than creating special value for it
Yes we should just support "variables" the user has to decide what is the best one to use...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the plexus way of doing @PostConstruct
?
I created the TargetDefinitionVariableResolver
but now I need to get the logger from mavenContext
after injecting it
@Component(role = TargetDefinitionVariableResolver.class)
public class TargetDefinitionVariableResolver {
@Requirement
private MavenContext mavenContext;
@Requirement // this does not work
private MavenLogger logger;
@PostConstruct // this does not work either
private void postConstruct(){
// I expect the DI framework to call this method after it injected all members
this.logger = mavenContext.getLogger();
}
of course I could get the logger at the start of the resolve
method (so it sets the logger the first time it is called and does effectively noop on each subsequent call) but that seems ugly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't use MavenLogger
(that legacy) but simply plexus logger you can inject directly in your component.
Also if not required by method definition MavenContext
should not be used, both things are from the old days where Tycho has slit into a maven and a mebedded osgi part.
beside that Plexus has "Initlizable" interface for post construct actions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well both org.eclipse.tycho.core.shared.MavenContext
and org.eclipse.tycho.core.shared.MavenLogger
were used in the original TargetDefinitionResolver
, I just moved the code from it into TargetDefinitionVariableResolver
without doing any further changes.
If you wish I can replace the logger
there by injected org.codehaus.plexus.logging.Logger
.
As for the mavenContext
it was used for
mavenContext.getSessionProperties()
and mavenContext.getProjects()
- what should I replace these by to avoid the MavenContext
?
thanks for the post construct hint
@@ -194,8 +198,9 @@ private void validateTarget(File targetFile) throws TPError { | |||
for (Location location : targetDefinition.getLocations()) { | |||
if (location instanceof InstallableUnitLocation p2Loc) { | |||
for (Repository repo : p2Loc.getRepositories()) { | |||
ref.addArtifactRepository(repo.getLocation()); | |||
ref.addMetadataRepository(repo.getLocation()); | |||
var repoUri = definitionResolver.resolveRepositoryLocation(repo.getLocation()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't use var
for trivial types.
|
||
@Test | ||
public void repositoryUrlCanContainEnvVarVariable() throws Exception { | ||
Verifier verifier = getVerifier("target.variables-env", false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use subfolders instead of dash to separate different use cases e.g.
Verifier verifier = getVerifier("target.variables-env", false); | |
Verifier verifier = getVerifier("target.variables/env", false); |
just in case more tests are added this is easier to manage.
|
||
@Test | ||
public void repositoryUrlCanContainSystemPropertyVariable() throws Exception { | ||
Verifier verifier = getVerifier("target.variables-sysprop", false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verifier verifier = getVerifier("target.variables-sysprop", false); | |
Verifier verifier = getVerifier("target.variables/sysprop", false); |
@@ -563,6 +563,10 @@ public static boolean isTargetFile(File file) { | |||
&& !file.getName().startsWith(".polyglot."); | |||
} | |||
|
|||
public static TargetDefinition.Repository repository(String id, String uri) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this required and one can not just call the constructor directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this less intrusive than making the private type public, but if you have no problem with that I'll just increase visibility on the Repository class and remove this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But where is this method actually used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in UpdateTargetMojo.LatestVersionLocation#getRepositories
when creating copy of repository with its location resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case it would be better to have a private implementation in UpdateTargetMojo
that can delegate everything to original item but return a different URL ...
@vaclavHala also please add an entry to the release notes so people are aware of that feature and link the Issue in your commit message. |
@laeubi I pushed new commits addressing all your comments and resolved conflicts with the latest master. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the adjustments I think it looks quite good now just some smaller adjustments/hints here.
tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionVariableResolver.java
Show resolved
Hide resolved
|
||
@Requirement | ||
private MavenContext mavenContext; | ||
private MavenLogger logger; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use org.codehaus.plexus.logging.Logger
like this
private MavenLogger logger; | |
@Requirement | |
private Logger logger; |
that way we don't need the Initializable
nor the MavenContext
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replaced the logger as you suggest, but we still do need the MavenContext. It was not used just to get to the logger, I also need it to mavenContext.getProjects()
and mavenContext.getSessionProperties()
. What are suitable replacements for these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can take a look at DefaultMavenContext
class,
mavenContext.getSessionProperties() --> Session.getProperties()
mavenContext.getProjects() --> Session.getProjects()
but if you like you can just retain this for now and only replace the logger, its just good to remove references to the MavenContext where it is easily possible (like loggers).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked there but if I understand you correctly that would mean instead of MavenContext
I'd have to inject LegacySupport
and copy/paste the get(Session|Propeties|Projects)
methods from DefaultMavenContext
into the TargetDefinitionVariableResolver
which hardly seems as an improvement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want access to the session, you can add @SessionScoped
to the component and add a constructor like this:
@Inject
public MySessionScopedComponent(MavenSession mavenSession) {
this.mavenSession = mavenSession;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should never need to use any mocks to test your changes, only test the user visible API and/or using real integration test projects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beside that, if you want to change the session values in a test you can override org.eclipse.tycho.testing.TychoPlexusTestCase.modifySession(MavenSession)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding failures like:
Caused by: java.lang.NullPointerException: Cannot invoke "java.io.File.getName()" because the return value of "org.eclipse.tycho.ReactorProject.getBasedir()" is null
one should simply add a null-check at that location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one should simply add a null-check at that location.
I don't think I agree here, these tests worked fine before but started breaking when I changed MavenContext
in the variable resolver for MavenSession
to look up current projects. The MavenSession
that gets injected provides different list of projects than MavenContext
. Projects provided by the MavenSession
(as shown in my comment above) do not have the basedir
set which causes these NPE failures.
I agree mocking is probably not the way to do here. However simply injecting the MavenSession
leads to the test failures for reasons I do not currently understand and don't think I could address in reasonable time. So since using MavenSession
instead of MavenContext
is not a matter of simple 1:1 replacement I suggest we do not go through with it in this PR and keep the MavenContext
for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So since using MavenSession instead of MavenContext is not a matter of simple 1:1 replacement I suggest we do not go through with it in this PR and keep the MavenContext for now
That would be okay.
@@ -178,4 +192,26 @@ public String getVersion() { | |||
|
|||
} | |||
|
|||
private static final class Repository implements TargetDefinition.Repository { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might want to choose a more descriptive name e.g.
private static final class Repository implements TargetDefinition.Repository { | |
private static final class ResolvedRepository implements TargetDefinition.Repository { |
8fcb6a8
to
80d4db0
Compare
@laeubi I pushed some new commits, I believe all your comments are now addressed. Please let me know if you need me to do anything more before this can be merged. Also, what needs to be done for this new feature to be backported into 2.7.x so it is included in 2.7.5 release? I can update #2421 to make it match changes in this PR as closely as possible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, some header adjustments for completeness required then its fine to merge.
@@ -0,0 +1,23 @@ | |||
/******************************************************************************* | |||
* Copyright (c) 2011, 2022 SAP SE and others. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Copyright (c) 2011, 2022 SAP SE and others. | |
* Copyright (c) 2023 Vaclav Hala and others. |
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* Contributors: | ||
* Vaclav Hala - initial API and implementation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Vaclav Hala - initial API and implementation | |
* Vaclav Hala - extraction code from TargetDefinitionResolver into dedicated component |
@@ -0,0 +1,61 @@ | |||
/******************************************************************************* | |||
* Copyright (c) 2011, 2022 SAP SE and others. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Copyright (c) 2011, 2022 SAP SE and others. | |
* Copyright (c) 2023 Vaclav Hala and others. |
@vaclavHala also please rebase/squash all changes into one commit if possible.
If code has diverged to much its most often easier to "start from scratch" and just try to insert the interesting parts accordingly also its most often good to not perform refactoring in backports, even though this might lead to duplication or not so clean code, but for a backport smaller local changes are usually better.
I fear a new release of the 2.7.5 is quite unlikely if we can get the CI working (again) there should be a SNAPSHOT to test at laest, but you might want to backport it to 3.x first there will be a release after the 2023-06 eclipse release (about two week from now on). |
…ar and system_property variables
f01fefa
to
87068d3
Compare
I pushed new commit with the header changes you wanted and everything squashed.
I meant next release in the 2.7.x line, I see I mistyped the exact version as 2.7.5 already exists, so 2.7.6. For now please let's just merge this into master and we will discuss internally how we want to proceed with the backporting/upgrading first |
3302ad0
to
87068d3
Compare
This looks good now and is ready to be merged.
Please note that you only need java 17 to run the maven build, the code can still be all java 11 (or 1.8 or ..) so if you see any problems regarding this usecase let us know! |
No description provided.