Skip to content

Commit

Permalink
Issue eclipse-tycho#1711 refactor based on CR, Changelog entry
Browse files Browse the repository at this point in the history
  • Loading branch information
Vaclav Hala committed May 23, 2023
1 parent 298b9d1 commit 12fee83
Show file tree
Hide file tree
Showing 26 changed files with 189 additions and 118 deletions.
7 changes: 7 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,13 @@ This can be disabled with the following configuration in the pom:
</plugin>
```

### Variable resolution in target repository location

URI in `<repository location="...">` in `*.target` files can contain:
- Environment variable as `${env_var:MY_VARIABLE}`
- System variable as `${system_property:myProp}` passed at build time as `-DmyProp`
- Project location as `${project_loc:ProjectName}`

### Migration guide 3.x > 4.x

### New delayed target platform resolving
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
Expand All @@ -43,7 +40,6 @@
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.tycho.BuildFailureException;
import org.eclipse.tycho.ExecutionEnvironmentResolutionHints;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.core.resolver.MavenTargetDefinitionContent;
import org.eclipse.tycho.core.resolver.shared.IncludeSourceMode;
Expand Down Expand Up @@ -80,10 +76,6 @@
*/
public final class TargetDefinitionResolver {

private static final Pattern SYSTEM_PROPERTY_PATTERN = createVariablePatternArgument("system_property");
private static final Pattern PROJECT_LOC_PATTERN = createVariablePatternArgument("project_loc");
private static final Pattern ENV_VAR_PATTERN = createVariablePatternArgument("env_var");

private final MavenLogger logger;

private final List<TargetEnvironment> environments;
Expand All @@ -93,16 +85,19 @@ public final class TargetDefinitionResolver {
private MavenContext mavenContext;
private IncludeSourceMode includeSourceMode;
private MavenDependenciesResolver mavenDependenciesResolver;
private TargetDefinitionVariableResolver varResolver;

public TargetDefinitionResolver(List<TargetEnvironment> environments,
ExecutionEnvironmentResolutionHints executionEnvironment, IncludeSourceMode includeSourceMode,
MavenContext mavenContext, MavenDependenciesResolver mavenDependenciesResolver) {
MavenContext mavenContext, MavenDependenciesResolver mavenDependenciesResolver,
TargetDefinitionVariableResolver varResolver) {
this.environments = environments;
this.executionEnvironment = executionEnvironment;
this.includeSourceMode = includeSourceMode;
this.mavenContext = mavenContext;
this.mavenDependenciesResolver = mavenDependenciesResolver;
this.logger = mavenContext.getLogger();
this.varResolver = varResolver;
}

public TargetDefinitionContent resolveContent(TargetDefinition definition, IProvisioningAgent provisioningAgent) {
Expand Down Expand Up @@ -274,21 +269,6 @@ public IArtifactRepository getArtifactRepository() {
};
}

protected URI resolveRepositoryLocation(String location) {
location = resolvePattern(location, SYSTEM_PROPERTY_PATTERN,
key -> mavenContext.getSessionProperties().getProperty(key, ""));
location = resolvePattern(location, ENV_VAR_PATTERN, key -> {
String env = System.getenv(key);
return env == null ? "" : env;
});

try {
return new URI(location);
} catch (URISyntaxException e) {
throw new TargetDefinitionSyntaxException("Invalid URI: " + location);
}
}

/**
* Converts a "raw" URI string into one that can be used to parse it as an {@link URI}. The
* conversion is especially for converting file URIs constructed using maven properties that
Expand All @@ -314,62 +294,15 @@ public static String convertRawToUri(String raw) {
}

protected String resolvePath(String path, TargetDefinition definition) {
path = resolvePattern(path, SYSTEM_PROPERTY_PATTERN,
key -> mavenContext.getSessionProperties().getProperty(key, ""));
path = resolvePattern(path, ENV_VAR_PATTERN, key -> {
String env = System.getenv(key);
return env == null ? "" : env;
});
path = resolvePattern(path, PROJECT_LOC_PATTERN, this::findProjectLocation);
return path;
}

private String findProjectLocation(String projectName) {
if (projectName.startsWith("/")) {
projectName = projectName.substring(1);
}
logger.debug("Find project location for project " + projectName);
for (ReactorProject project : mavenContext.getProjects()) {
String name = project.getName();
logger.debug("check reactor project name: " + name);
if (name.equals(projectName)) {
return project.getBasedir().getAbsolutePath();
}
}
for (ReactorProject project : mavenContext.getProjects()) {
String artifactId = project.getArtifactId();
logger.debug("check reactor project artifact id: " + artifactId);
if (artifactId.equals(projectName)) {
return project.getBasedir().getAbsolutePath();
}
}
for (ReactorProject project : mavenContext.getProjects()) {
String name = project.getBasedir().getName();
logger.debug("check reactor project base directory: " + name);
if (name.equals(projectName)) {
return project.getBasedir().getAbsolutePath();
}
}
//if we can't resolve this, we will return the original one as this might be intentional to not include the project in the build
String defaultValue = "${project_loc:" + projectName + "}";
logger.warn("Cannot resolve " + defaultValue + " target resolution might be incomplete");
return defaultValue;
return varResolver.resolve(path);
}

private static String resolvePattern(String input, Pattern pattern, Function<String, String> parameterResolver) {
Matcher matcher = pattern.matcher(input);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String group = matcher.group(1);
String resolved = parameterResolver.apply(group);
matcher.appendReplacement(sb, Matcher.quoteReplacement(resolved));
protected URI resolveRepositoryLocation(String location) {
try {
return new URI(varResolver.resolve(location));
} catch (URISyntaxException e) {
throw new TargetDefinitionSyntaxException("Invalid URI: " + location);
}
matcher.appendTail(sb);
return sb.toString();
}

private static Pattern createVariablePatternArgument(String variableName) {
return Pattern.compile("\\$\\{" + variableName + ":([^}]+)\\}", Pattern.CASE_INSENSITIVE);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*******************************************************************************/
package org.eclipse.tycho.p2resolver;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -54,6 +53,9 @@ public class TargetDefinitionResolverService {
@Requirement
private MavenDependenciesResolver dependenciesResolver;

@Requirement
private TargetDefinitionVariableResolver varResolver;

// constructor for DS
public TargetDefinitionResolverService() {
}
Expand Down Expand Up @@ -86,7 +88,7 @@ private CompletableFuture<TargetDefinitionContent> resolveFromArguments(Resoluti
}

TargetDefinitionResolver resolver = new TargetDefinitionResolver(arguments.environments, arguments.jreIUs,
arguments.includeSourceMode, mavenContext, dependenciesResolver);
arguments.includeSourceMode, mavenContext, dependenciesResolver, varResolver);
try {
return CompletableFuture.completedFuture(resolver.resolveContent(arguments.definition, arguments.agent));
} catch (Exception e) {
Expand Down Expand Up @@ -118,11 +120,6 @@ private void debugCacheMiss(ResolutionArguments arguments) {
}
}

public URI resolveRepositoryLocation(String location) {
TargetDefinitionResolver resolver = new TargetDefinitionResolver(null, null, null, mavenContext, null);
return resolver.resolveRepositoryLocation(location);
}

// setter for DS
public void setMavenContext(MavenContext mavenContext) {
this.mavenContext = mavenContext;
Expand All @@ -133,6 +130,11 @@ public void setMavenDependenciesResolver(MavenDependenciesResolver mavenDependen
this.dependenciesResolver = mavenDependenciesResolver;
}

// setter for DS
public void setTargetDefinitionVariableResolver(TargetDefinitionVariableResolver varResolver) {
this.varResolver = varResolver;
}

private static final class ResolutionArguments {

final TargetDefinition definition;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.eclipse.tycho.p2resolver;

import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.core.shared.MavenContext;
import org.eclipse.tycho.core.shared.MavenLogger;

@Component(role = TargetDefinitionVariableResolver.class)
public class TargetDefinitionVariableResolver implements Initializable {

private static final Pattern SYSTEM_PROPERTY_PATTERN = createVariablePatternArgument("system_property");
private static final Pattern PROJECT_LOC_PATTERN = createVariablePatternArgument("project_loc");
private static final Pattern ENV_VAR_PATTERN = createVariablePatternArgument("env_var");

@Requirement
private MavenContext mavenContext;
private MavenLogger logger;

/** for test */
public TargetDefinitionVariableResolver(MavenContext mavenContext) {
this.mavenContext = mavenContext;
this.logger = mavenContext.getLogger();
}

/** for injection */
public TargetDefinitionVariableResolver() {
}

@Override
public void initialize() throws InitializationException {
this.logger = mavenContext.getLogger();
}

public String resolve(String path) {
path = resolvePattern(path, SYSTEM_PROPERTY_PATTERN,
key -> mavenContext.getSessionProperties().getProperty(key, ""));
path = resolvePattern(path, ENV_VAR_PATTERN, key -> {
String env = System.getenv(key);
return env == null ? "" : env;
});
path = resolvePattern(path, PROJECT_LOC_PATTERN, this::findProjectLocation);
return path;
}

private String findProjectLocation(String projectName) {
if (projectName.startsWith("/")) {
projectName = projectName.substring(1);
}
logger.debug("Find project location for project " + projectName);
for (ReactorProject project : mavenContext.getProjects()) {
String name = project.getName();
logger.debug("check reactor project name: " + name);
if (name.equals(projectName)) {
return project.getBasedir().getAbsolutePath();
}
}
for (ReactorProject project : mavenContext.getProjects()) {
String artifactId = project.getArtifactId();
logger.debug("check reactor project artifact id: " + artifactId);
if (artifactId.equals(projectName)) {
return project.getBasedir().getAbsolutePath();
}
}
for (ReactorProject project : mavenContext.getProjects()) {
String name = project.getBasedir().getName();
logger.debug("check reactor project base directory: " + name);
if (name.equals(projectName)) {
return project.getBasedir().getAbsolutePath();
}
}
//if we can't resolve this, we will return the original one as this might be intentional to not include the project in the build
String defaultValue = "${project_loc:" + projectName + "}";
logger.warn("Cannot resolve " + defaultValue + " target resolution might be incomplete");
return defaultValue;
}

private static String resolvePattern(String input, Pattern pattern, Function<String, String> parameterResolver) {
Matcher matcher = pattern.matcher(input);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String group = matcher.group(1);
String resolved = parameterResolver.apply(group);
matcher.appendReplacement(sb, Matcher.quoteReplacement(resolved));
}
matcher.appendTail(sb);
return sb.toString();
}

private static Pattern createVariablePatternArgument(String variableName) {
return Pattern.compile("\\$\\{" + variableName + ":([^}]+)\\}", Pattern.CASE_INSENSITIVE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.eclipse.tycho.core.ee.impl.StandardEEResolutionHints;
import org.eclipse.tycho.core.ee.shared.ExecutionEnvironmentStub;
import org.eclipse.tycho.core.resolver.shared.IncludeSourceMode;
import org.eclipse.tycho.core.shared.MavenContext;
import org.eclipse.tycho.p2resolver.TargetDefinitionResolverIncludeModeTest.PlannerLocationStub;
import org.eclipse.tycho.p2resolver.TargetDefinitionResolverTest.RepositoryStub;
import org.eclipse.tycho.targetplatform.TargetDefinition;
Expand All @@ -56,10 +57,10 @@ public class TargetDefinitionResolverExecutionEnvironmentTest extends TychoPlexu

private TargetDefinitionResolver targetResolverForEE(String executionEnvironmentName, String... systemPackages)
throws ProvisionException, IOException {
MavenContext mavenCtx = new MockMavenContext(tempManager.newFolder("localRepo"), logVerifier.getLogger());
return new TargetDefinitionResolver(defaultEnvironments(),
new StandardEEResolutionHints(new ExecutionEnvironmentStub(executionEnvironmentName, systemPackages)),
IncludeSourceMode.honor,
new MockMavenContext(tempManager.newFolder("localRepo"), logVerifier.getLogger()), null);
IncludeSourceMode.honor, mavenCtx, null, new TargetDefinitionVariableResolver(mavenCtx));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@
import org.eclipse.equinox.p2.metadata.IVersionedId;
import org.eclipse.tycho.core.resolver.shared.IncludeSourceMode;
import org.eclipse.tycho.core.resolver.target.TargetDefinitionContent;
import org.eclipse.tycho.core.shared.MavenContext;
import org.eclipse.tycho.p2.resolver.ResolverException;
import org.eclipse.tycho.p2resolver.TargetDefinitionResolverTest.LocationStub;
import org.eclipse.tycho.p2resolver.TargetDefinitionResolverTest.TestRepositories;
import org.eclipse.tycho.targetplatform.TargetDefinition;
import org.eclipse.tycho.targetplatform.TargetDefinitionResolutionException;
import org.eclipse.tycho.targetplatform.TargetDefinition.IncludeMode;
import org.eclipse.tycho.targetplatform.TargetDefinitionResolutionException;
import org.eclipse.tycho.test.util.LogVerifier;
import org.eclipse.tycho.test.util.MockMavenContext;
import org.eclipse.tycho.testing.TychoPlexusTestCase;
Expand All @@ -56,9 +57,10 @@ public class TargetDefinitionResolverIncludeModeTest extends TychoPlexusTestCase

@Before
public void initSubject() throws Exception {
MavenContext mavenCtx = new MockMavenContext(tempManager.newFolder("localRepo"), logVerifier.getLogger());
subject = new TargetDefinitionResolver(defaultEnvironments(),
ExecutionEnvironmentTestUtils.NOOP_EE_RESOLUTION_HINTS, IncludeSourceMode.honor,
new MockMavenContext(tempManager.newFolder("localRepo"), logVerifier.getLogger()), null);
ExecutionEnvironmentTestUtils.NOOP_EE_RESOLUTION_HINTS, IncludeSourceMode.honor, mavenCtx, null,
new TargetDefinitionVariableResolver(mavenCtx));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.tycho.core.resolver.shared.IncludeSourceMode;
import org.eclipse.tycho.core.resolver.target.TargetDefinitionContent;
import org.eclipse.tycho.core.shared.MavenContext;
import org.eclipse.tycho.p2resolver.TargetDefinitionResolverTest.LocationStub;
import org.eclipse.tycho.p2resolver.TargetDefinitionResolverTest.TestRepositories;
import org.eclipse.tycho.targetplatform.TargetDefinition;
import org.eclipse.tycho.targetplatform.TargetDefinitionResolutionException;
import org.eclipse.tycho.targetplatform.TargetDefinition.IncludeMode;
import org.eclipse.tycho.targetplatform.TargetDefinitionResolutionException;
import org.eclipse.tycho.test.util.LogVerifier;
import org.eclipse.tycho.test.util.MockMavenContext;
import org.eclipse.tycho.testing.TychoPlexusTestCase;
Expand All @@ -56,9 +57,10 @@ public class TargetDefinitionResolverIncludeSourceTest extends TychoPlexusTestCa

@Before
public void initSubject() throws Exception {
MavenContext mavenCtx = new MockMavenContext(tempManager.newFolder("localRepo"), logVerifier.getLogger());
subject = new TargetDefinitionResolver(defaultEnvironments(),
ExecutionEnvironmentTestUtils.NOOP_EE_RESOLUTION_HINTS, IncludeSourceMode.honor,
new MockMavenContext(tempManager.newFolder("localRepo"), logVerifier.getLogger()), null);
ExecutionEnvironmentTestUtils.NOOP_EE_RESOLUTION_HINTS, IncludeSourceMode.honor, mavenCtx, null,
new TargetDefinitionVariableResolver(mavenCtx));
}

@Test(expected = TargetDefinitionResolutionException.class)
Expand Down
Loading

0 comments on commit 12fee83

Please sign in to comment.