diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java index aff03e05e0..ebbdeb9645 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java @@ -143,7 +143,7 @@ public TargetDefinitionContent resolveContentWithExceptions(TargetDefinition def } List locations = new ArrayList<>(); for (Repository repository : installableUnitLocation.getRepositories()) { - URI location = repository.getLocation(); + URI location = resolveRepositoryLocation(repository.getLocation()); String key = location.normalize().toASCIIString(); locations.add(uriRepositories.computeIfAbsent(key, s -> new URITargetDefinitionContent(provisioningAgent, location, repository.getId()))); @@ -274,6 +274,21 @@ 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 diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverService.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverService.java index c7c14db8d3..5d1b910f15 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverService.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverService.java @@ -16,6 +16,7 @@ *******************************************************************************/ package org.eclipse.tycho.p2resolver; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -117,6 +118,11 @@ 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; diff --git a/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionFileTest.java b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionFileTest.java index c92e35c658..cf8d55f4ce 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionFileTest.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionFileTest.java @@ -21,7 +21,6 @@ import java.io.File; import java.io.IOException; -import java.net.URI; import java.util.List; import org.eclipse.tycho.core.resolver.shared.IncludeSourceMode; @@ -44,7 +43,7 @@ public void testTarget() throws Exception { InstallableUnitLocation location = (InstallableUnitLocation) locations.get(0); assertEquals(1, location.getRepositories().size()); - assertEquals(URI.create("https://download.eclipse.org/eclipse/updates/3.5/"), + assertEquals("https://download.eclipse.org/eclipse/updates/3.5/", location.getRepositories().get(0).getLocation()); assertEquals(1, location.getUnits().size()); assertEquals("org.eclipse.platform.sdk", location.getUnits().get(0).getId()); @@ -53,9 +52,8 @@ public void testTarget() throws Exception { InstallableUnitLocation l02 = (InstallableUnitLocation) locations.get(1); assertEquals(5, l02.getUnits().size()); assertEquals(2, l02.getRepositories().size()); - assertEquals(URI.create("http://subclipse.tigris.org/update_1.6.x/"), - l02.getRepositories().get(0).getLocation()); - assertEquals(URI.create("https://download.eclipse.org/tools/mylyn/update/e3.4/"), + assertEquals("http://subclipse.tigris.org/update_1.6.x/", l02.getRepositories().get(0).getLocation()); + assertEquals("https://download.eclipse.org/tools/mylyn/update/e3.4/", l02.getRepositories().get(1).getLocation()); } diff --git a/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverTest.java b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverTest.java index 10bc92ed3f..b876bcfc20 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverTest.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolverTest.java @@ -40,13 +40,13 @@ import org.eclipse.tycho.core.resolver.target.TargetDefinitionContent; import org.eclipse.tycho.core.test.utils.ResourceUtil; import org.eclipse.tycho.targetplatform.TargetDefinition; -import org.eclipse.tycho.targetplatform.TargetDefinitionResolutionException; -import org.eclipse.tycho.targetplatform.TargetDefinitionSyntaxException; import org.eclipse.tycho.targetplatform.TargetDefinition.IncludeMode; import org.eclipse.tycho.targetplatform.TargetDefinition.InstallableUnitLocation; import org.eclipse.tycho.targetplatform.TargetDefinition.Location; import org.eclipse.tycho.targetplatform.TargetDefinition.Repository; import org.eclipse.tycho.targetplatform.TargetDefinition.Unit; +import org.eclipse.tycho.targetplatform.TargetDefinitionResolutionException; +import org.eclipse.tycho.targetplatform.TargetDefinitionSyntaxException; import org.eclipse.tycho.test.util.LogVerifier; import org.eclipse.tycho.test.util.MockMavenContext; import org.eclipse.tycho.testing.TychoPlexusTestCase; @@ -383,12 +383,12 @@ public RepositoryStub(String repository) { } @Override - public URI getLocation() { + public String getLocation() { if (repository != null) { File repo = ResourceUtil.resourceFile(basedir + repository + "/content.xml").getParentFile(); - return repo.toURI(); + return repo.toURI().toString(); } - return URI.create("invalid:hello"); + return URI.create("invalid:hello").toString(); } @Override diff --git a/tycho-extras/target-platform-validation-plugin/src/main/java/org/eclipse/tycho/extras/tpvalidator/TPValidationMojo.java b/tycho-extras/target-platform-validation-plugin/src/main/java/org/eclipse/tycho/extras/tpvalidator/TPValidationMojo.java index 4850a142d6..c8d8026312 100644 --- a/tycho-extras/target-platform-validation-plugin/src/main/java/org/eclipse/tycho/extras/tpvalidator/TPValidationMojo.java +++ b/tycho-extras/target-platform-validation-plugin/src/main/java/org/eclipse/tycho/extras/tpvalidator/TPValidationMojo.java @@ -45,6 +45,7 @@ import org.eclipse.tycho.p2.target.facade.TargetPlatformConfigurationStub; import org.eclipse.tycho.p2.tools.RepositoryReferences; import org.eclipse.tycho.p2.tools.director.shared.DirectorRuntime; +import org.eclipse.tycho.p2resolver.TargetDefinitionResolverService; import org.eclipse.tycho.targetplatform.TargetDefinition.InstallableUnitLocation; import org.eclipse.tycho.targetplatform.TargetDefinition.Location; import org.eclipse.tycho.targetplatform.TargetDefinition.Repository; @@ -117,6 +118,9 @@ public class TPValidationMojo extends AbstractMojo { @Component private P2ResolverFactory factory; + @Component(role = TargetDefinitionResolverService.class) + private TargetDefinitionResolverService definitionResolver; + public void execute() throws MojoExecutionException { List errors = new ArrayList<>(); @@ -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()); + ref.addArtifactRepository(repoUri); + ref.addMetadataRepository(repoUri); } for (Unit unit : p2Loc.getUnits()) { if (checkDependencies) { diff --git a/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java b/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java index afd9e99021..c76078c55b 100644 --- a/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java +++ b/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.tycho.versionbump; +import static java.util.stream.Collectors.toList; + import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -25,10 +27,12 @@ import javax.xml.parsers.ParserConfigurationException; +import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.eclipse.tycho.TargetEnvironment; import org.eclipse.tycho.core.resolver.P2ResolutionResult; +import org.eclipse.tycho.p2resolver.TargetDefinitionResolverService; import org.eclipse.tycho.targetplatform.TargetDefinition; import org.eclipse.tycho.targetplatform.TargetDefinition.IncludeMode; import org.eclipse.tycho.targetplatform.TargetDefinition.InstallableUnitLocation; @@ -49,6 +53,9 @@ public class UpdateTargetMojo extends AbstractUpdateMojo { @Parameter(property = "target") private File targetFile; + @Component(role = TargetDefinitionResolverService.class) + private TargetDefinitionResolverService definitionResolver; + @Override protected void doUpdate() throws IOException, URISyntaxException, ParserConfigurationException, SAXException { @@ -57,7 +64,7 @@ protected void doUpdate() throws IOException, URISyntaxException, ParserConfigur target = TargetDefinitionFile.parseDocument(input); TargetDefinitionFile parsedTarget = TargetDefinitionFile.parse(target, targetFile.getAbsolutePath()); resolutionContext.setEnvironments(Collections.singletonList(TargetEnvironment.getRunningEnvironment())); - resolutionContext.addTargetDefinition(new LatestVersionTarget(parsedTarget)); + resolutionContext.addTargetDefinition(new LatestVersionTarget(parsedTarget, definitionResolver)); P2ResolutionResult result = p2.getTargetPlatformAsResolutionResult(resolutionContext, executionEnvironment); Map ius = new HashMap<>(); @@ -90,16 +97,18 @@ protected File getFileToBeUpdated() { private static final class LatestVersionTarget implements TargetDefinition { private TargetDefinitionFile delegate; + private TargetDefinitionResolverService varResolver; - public LatestVersionTarget(TargetDefinitionFile delegate) { + public LatestVersionTarget(TargetDefinitionFile delegate, TargetDefinitionResolverService varResolver) { this.delegate = delegate; + this.varResolver = varResolver; } @Override public List getLocations() { return delegate.getLocations().stream().map(location -> { if (location instanceof InstallableUnitLocation iuLocation) { - return new LatestVersionLocation(iuLocation); + return new LatestVersionLocation(iuLocation, varResolver); } else { return location; } @@ -126,14 +135,19 @@ public String getTargetEE() { private static final class LatestVersionLocation implements InstallableUnitLocation { private InstallableUnitLocation delegate; + private TargetDefinitionResolverService varResolver; - public LatestVersionLocation(InstallableUnitLocation delegate) { + public LatestVersionLocation(InstallableUnitLocation delegate, TargetDefinitionResolverService varResolver) { this.delegate = delegate; + this.varResolver = varResolver; } @Override public List getRepositories() { - return delegate.getRepositories(); + return delegate.getRepositories().stream().map(repo -> { + var resolvedLocation = varResolver.resolveRepositoryLocation(repo.getLocation()); + return TargetDefinitionFile.repository(repo.getId(), resolvedLocation.toString()); + }).collect(toList()); } @Override diff --git a/tycho-its/projects/target.variables-env/pom.xml b/tycho-its/projects/target.variables-env/pom.xml new file mode 100644 index 0000000000..e1c0165ccb --- /dev/null +++ b/tycho-its/projects/target.variables-env/pom.xml @@ -0,0 +1,59 @@ + + 4.0.0 + tycho-its-project.variables.env + aggregator + 1.0.0 + pom + + + UTF-8 + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + p2 + consider + JavaSE-11 + + + tycho-its-project.variables.env + targetplatform + 1.0.0 + + + + + win32 + win32 + x86_64 + + + linux + gtk + x86_64 + + + + + + + + + targetplatform + project + + + diff --git a/tycho-its/projects/target.variables-env/project/META-INF/MANIFEST.MF b/tycho-its/projects/target.variables-env/project/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..14ac1927fc --- /dev/null +++ b/tycho-its/projects/target.variables-env/project/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: project +Bundle-Version: 1.0.0 +Automatic-Module-Name: project +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: javax.xml diff --git a/tycho-its/projects/target.variables-env/project/build.properties b/tycho-its/projects/target.variables-env/project/build.properties new file mode 100644 index 0000000000..e676b583e2 --- /dev/null +++ b/tycho-its/projects/target.variables-env/project/build.properties @@ -0,0 +1,2 @@ +source.. = src/ +bin.includes = META-INF/,. diff --git a/tycho-its/projects/target.variables-env/project/pom.xml b/tycho-its/projects/target.variables-env/project/pom.xml new file mode 100644 index 0000000000..53e619e00b --- /dev/null +++ b/tycho-its/projects/target.variables-env/project/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + project + 1.0.0 + eclipse-plugin + + tycho-its-project.variables.env + aggregator + 1.0.0 + + + \ No newline at end of file diff --git a/tycho-its/projects/target.variables-env/targetplatform/pom.xml b/tycho-its/projects/target.variables-env/targetplatform/pom.xml new file mode 100644 index 0000000000..ce84ea8f98 --- /dev/null +++ b/tycho-its/projects/target.variables-env/targetplatform/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + targetplatform + eclipse-target-definition + + tycho-its-project.variables.env + aggregator + 1.0.0 + + + + + + org.eclipse.tycho.extras + target-platform-validation-plugin + ${tycho-version} + + + + validate-target-platform + + + true + true + + + + + + + \ No newline at end of file diff --git a/tycho-its/projects/target.variables-env/targetplatform/targetplatform.target b/tycho-its/projects/target.variables-env/targetplatform/targetplatform.target new file mode 100644 index 0000000000..67ec2f856f --- /dev/null +++ b/tycho-its/projects/target.variables-env/targetplatform/targetplatform.target @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/tycho-its/projects/target.variables-sysprop/pom.xml b/tycho-its/projects/target.variables-sysprop/pom.xml new file mode 100644 index 0000000000..d06f2b79d5 --- /dev/null +++ b/tycho-its/projects/target.variables-sysprop/pom.xml @@ -0,0 +1,59 @@ + + 4.0.0 + tycho-its-project.variables.sysprop + aggregator + 1.0.0 + pom + + + UTF-8 + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + p2 + consider + JavaSE-11 + + + tycho-its-project.variables.sysprop + targetplatform + 1.0.0 + + + + + win32 + win32 + x86_64 + + + linux + gtk + x86_64 + + + + + + + + + targetplatform + project + + + diff --git a/tycho-its/projects/target.variables-sysprop/project/META-INF/MANIFEST.MF b/tycho-its/projects/target.variables-sysprop/project/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..14ac1927fc --- /dev/null +++ b/tycho-its/projects/target.variables-sysprop/project/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: project +Bundle-Version: 1.0.0 +Automatic-Module-Name: project +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: javax.xml diff --git a/tycho-its/projects/target.variables-sysprop/project/build.properties b/tycho-its/projects/target.variables-sysprop/project/build.properties new file mode 100644 index 0000000000..e676b583e2 --- /dev/null +++ b/tycho-its/projects/target.variables-sysprop/project/build.properties @@ -0,0 +1,2 @@ +source.. = src/ +bin.includes = META-INF/,. diff --git a/tycho-its/projects/target.variables-sysprop/project/pom.xml b/tycho-its/projects/target.variables-sysprop/project/pom.xml new file mode 100644 index 0000000000..c07fa9f753 --- /dev/null +++ b/tycho-its/projects/target.variables-sysprop/project/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + project + 1.0.0 + eclipse-plugin + + tycho-its-project.variables.sysprop + aggregator + 1.0.0 + + + \ No newline at end of file diff --git a/tycho-its/projects/target.variables-sysprop/targetplatform/pom.xml b/tycho-its/projects/target.variables-sysprop/targetplatform/pom.xml new file mode 100644 index 0000000000..538d31f3e9 --- /dev/null +++ b/tycho-its/projects/target.variables-sysprop/targetplatform/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + targetplatform + eclipse-target-definition + + tycho-its-project.variables.sysprop + aggregator + 1.0.0 + + + + + + org.eclipse.tycho.extras + target-platform-validation-plugin + ${tycho-version} + + + + validate-target-platform + + + true + true + + + + + + + \ No newline at end of file diff --git a/tycho-its/projects/target.variables-sysprop/targetplatform/targetplatform.target b/tycho-its/projects/target.variables-sysprop/targetplatform/targetplatform.target new file mode 100644 index 0000000000..c802356861 --- /dev/null +++ b/tycho-its/projects/target.variables-sysprop/targetplatform/targetplatform.target @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/target/TargetVariableResolutionTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/target/TargetVariableResolutionTest.java new file mode 100644 index 0000000000..1e60821f11 --- /dev/null +++ b/tycho-its/src/test/java/org/eclipse/tycho/test/target/TargetVariableResolutionTest.java @@ -0,0 +1,49 @@ +package org.eclipse.tycho.test.target; + +import java.util.Arrays; + +import org.apache.maven.it.Verifier; +import org.eclipse.tycho.test.AbstractTychoIntegrationTest; +import org.eclipse.tycho.test.util.HttpServer; +import org.eclipse.tycho.test.util.ResourceUtil; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class TargetVariableResolutionTest extends AbstractTychoIntegrationTest { + private HttpServer server; + private String baseurl; + + @Before + public void startServer() throws Exception { + server = HttpServer.startServer(); + server.addServer("repo", ResourceUtil.resolveTestResource("repositories/javax.xml")); + var urlWithContextPath = server.getUrl(""); + baseurl = urlWithContextPath.endsWith("/") // double slash causes trouble in RepositoryTransport.download + ? urlWithContextPath.substring(0, urlWithContextPath.length() - 1) + : urlWithContextPath; + } + + @After + public void stopServer() throws Exception { + server.stop(); + } + + @Test + public void repositoryUrlCanContainEnvVarVariable() throws Exception { + Verifier verifier = getVerifier("target.variables-env", false); + verifier.setEnvironmentVariable("MY_MIRROR", baseurl); + verifier.executeGoals(Arrays.asList("package")); + verifier.verifyErrorFreeLog(); + verifier.verifyTextInLog("validate-target-platform"); + } + + @Test + public void repositoryUrlCanContainSystemPropertyVariable() throws Exception { + Verifier verifier = getVerifier("target.variables-sysprop", false); + verifier.setSystemProperty("myMirror", baseurl); + verifier.executeGoals(Arrays.asList("package")); + verifier.verifyErrorFreeLog(); + verifier.verifyTextInLog("validate-target-platform"); + } +} diff --git a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java index d4d5467c43..0927557c78 100644 --- a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java +++ b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java @@ -185,7 +185,7 @@ public enum IncludeMode { } public interface Repository { - URI getLocation(); + String getLocation(); String getId(); } diff --git a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java index ff69848cc0..597e77b67f 100644 --- a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java +++ b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java @@ -407,9 +407,9 @@ public String getTypeDescription() { private static final class Repository implements TargetDefinition.Repository { private final String id; - private final URI uri; + private final String uri; - Repository(String id, URI uri) { + Repository(String id, String uri) { this.id = id; this.uri = uri; } @@ -421,7 +421,7 @@ public String getId() { } @Override - public URI getLocation() { + public String getLocation() { return uri; } @@ -563,6 +563,10 @@ public static boolean isTargetFile(File file) { && !file.getName().startsWith(".polyglot."); } + public static TargetDefinition.Repository repository(String id, String uri) { + return new Repository(id, uri); + } + private static List parseLocations(Element dom) { ArrayList locations = new ArrayList<>(); Element locationsDom = getChild(dom, "locations"); @@ -640,12 +644,7 @@ private static IULocation parseIULocation(Element dom) { final List repositories = new ArrayList<>(); for (Element node : getChildren(dom, "repository")) { String id = node.getAttribute("id"); - URI uri; - try { - uri = new URI(node.getAttribute("location")); - } catch (URISyntaxException e) { - throw new TargetDefinitionSyntaxException("invalid URI", e); - } + String uri = node.getAttribute("location"); repositories.add(new Repository(id, uri)); } return new IULocation(Collections.unmodifiableList(units), Collections.unmodifiableList(repositories),