diff --git a/pom.xml b/pom.xml index febaf481e4..beaabf19cb 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ - 3.6.3 + 3.8.6 org.eclipse.tycho @@ -84,7 +84,7 @@ 1.3 3.6.4 6.1.0.202203080745-r - 3.8.5 + 3.8.6 3.0.0-M5 diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/maven/TychoWorkspaceReader.java b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/TychoWorkspaceReader.java new file mode 100644 index 0000000000..a2b43a9098 --- /dev/null +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/TychoWorkspaceReader.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2022 Christoph Läubrich and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.core.maven; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.ModelWriter; +import org.apache.maven.plugin.LegacySupport; +import org.apache.maven.project.MavenProject; +import org.apache.maven.repository.internal.MavenWorkspaceReader; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.logging.Logger; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.WorkspaceReader; +import org.eclipse.aether.repository.WorkspaceRepository; +import org.eclipse.sisu.equinox.EquinoxServiceFactory; +import org.eclipse.tycho.ArtifactDescriptor; +import org.eclipse.tycho.ArtifactKey; +import org.eclipse.tycho.MavenDependencyDescriptor; +import org.eclipse.tycho.ReactorProject; +import org.eclipse.tycho.TychoConstants; +import org.eclipse.tycho.artifacts.DependencyArtifacts; +import org.eclipse.tycho.core.osgitools.DefaultReactorProject; +import org.eclipse.tycho.core.utils.TychoProjectUtils; +import org.eclipse.tycho.p2.resolver.facade.P2ResolverFactory; + +@Component(role = WorkspaceReader.class, hint = "TychoWorkspaceReader") +public class TychoWorkspaceReader implements WorkspaceReader, MavenWorkspaceReader { + + private WorkspaceRepository repository; + + @Requirement + private LegacySupport legacySupport; + + @Requirement + private EquinoxServiceFactory equinox; + + @Requirement + private Logger logger; + + @Requirement + private ModelWriter modelWriter; + + public TychoWorkspaceReader() { + repository = new WorkspaceRepository("tycho", null); + } + + @Override + public WorkspaceRepository getRepository() { + return repository; + } + + @Override + public File findArtifact(Artifact artifact) { + if ("pom".equals(artifact.getExtension())) { + if (artifact.getGroupId().startsWith(TychoConstants.P2_GROUPID_PREFIX)) { + //TODO Maven should actually call the findModel instead see: https://issues.apache.org/jira/browse/MNG-7496 + logger.debug("Find the pom for " + artifact); + File pomFile = getFileForArtifact(artifact); + if (pomFile.isFile()) { + return pomFile; + } + Model findModel = findModel(artifact); + if (findModel != null) { + try { + pomFile.getParentFile().mkdirs(); + modelWriter.write(pomFile, new HashMap(), findModel); + return pomFile; + } catch (IOException e) { + logger.debug("Can't write model!", e); + } + } + } + return null; + } + if (artifact.getGroupId().startsWith(TychoConstants.P2_GROUPID_PREFIX)) { + File cachedFile = getFileForArtifact(artifact); + if (cachedFile.isFile()) { + return cachedFile; + } + } + + MavenSession session = legacySupport.getSession(); + if (session != null) { + MavenProject currentProject = session.getCurrentProject(); + ReactorProject reactorProject = DefaultReactorProject.adapt(currentProject); + + Optional dependencyMetadata = TychoProjectUtils + .getOptionalDependencyArtifacts(reactorProject); + if (dependencyMetadata.isPresent()) { + P2ResolverFactory factory = this.equinox.getService(P2ResolverFactory.class); + logger.debug("Attempt to resolve " + artifact + " for project " + currentProject + " ..."); + for (ArtifactDescriptor descriptor : dependencyMetadata.get().getArtifacts()) { + MavenDependencyDescriptor dependencyDescriptor = factory.resolveDependencyDescriptor(descriptor); + if (dependencyDescriptor != null) { + if (dependencyDescriptor.getGroupId().equals(artifact.getGroupId()) + && dependencyDescriptor.getArtifactId().equals(artifact.getArtifactId())) { + ArtifactKey artifactKey = descriptor.getKey(); + if (dependencyDescriptor.getVersion().equals(artifact.getVersion()) + || artifactKey.getVersion().equals(artifact.getVersion())) { + //we have a match! + return descriptor.getLocation(true); + } + } + } + } + } + } + return null; + } + + protected File getFileForArtifact(Artifact artifact) { + RepositorySystemSession repositorySession = legacySupport.getRepositorySession(); + LocalRepository localRepository = repositorySession.getLocalRepository(); + File basedir = localRepository.getBasedir(); + File cachedFile = new File(basedir, "p2/osgi/bundle/" + artifact.getArtifactId() + "/" + artifact.getVersion() + + "/" + artifact.getArtifactId() + "-" + artifact.getVersion() + "." + artifact.getExtension()); + return cachedFile; + } + + @Override + public List findVersions(Artifact artifact) { + return Collections.emptyList(); + } + + @Override + public Model findModel(Artifact artifact) { + if (artifact.getGroupId().startsWith(TychoConstants.P2_GROUPID_PREFIX)) { + logger.debug("Find the model for: " + artifact); + Model model = new Model(); + model.setModelVersion("4.0.0"); + model.setArtifactId(artifact.getArtifactId()); + model.setGroupId(artifact.getGroupId()); + model.setVersion(artifact.getVersion()); + model.setPackaging(artifact.getProperty("packaging", null)); + if (model.getPackaging() == null) { + model.setPackaging( + artifact.getGroupId().substring(TychoConstants.P2_GROUPID_PREFIX.length()).replace('.', '-')); + } + return model; + } + return null; + } + +} diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/utils/TychoProjectUtils.java b/tycho-core/src/main/java/org/eclipse/tycho/core/utils/TychoProjectUtils.java index d85648a5b6..d66a9e5a82 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/utils/TychoProjectUtils.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/utils/TychoProjectUtils.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.eclipse.tycho.ReactorProject; import org.eclipse.tycho.TychoConstants; @@ -42,6 +43,12 @@ public static DependencyArtifacts getDependencyArtifacts(ReactorProject project) return resolvedDependencies; } + public static Optional getOptionalDependencyArtifacts(ReactorProject project) { + DependencyArtifacts resolvedDependencies = (DependencyArtifacts) project + .getContextValue(TychoConstants.CTX_DEPENDENCY_ARTIFACTS); + return Optional.ofNullable(resolvedDependencies); + } + /** * Returns the {@link TargetPlatformConfiguration} instance associated with the given project. * diff --git a/tycho-extras/tycho-p2-extras-plugin/src/test/java/org/eclipse/tycho/plugins/p2/extras/MirrorMojoTest.java b/tycho-extras/tycho-p2-extras-plugin/src/test/java/org/eclipse/tycho/plugins/p2/extras/MirrorMojoTest.java index 17b681602b..2ffaea5cd1 100644 --- a/tycho-extras/tycho-p2-extras-plugin/src/test/java/org/eclipse/tycho/plugins/p2/extras/MirrorMojoTest.java +++ b/tycho-extras/tycho-p2-extras-plugin/src/test/java/org/eclipse/tycho/plugins/p2/extras/MirrorMojoTest.java @@ -15,6 +15,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -22,7 +27,6 @@ import java.util.Map; import java.util.Properties; -import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; @@ -47,12 +51,38 @@ protected void setUp() throws Exception { MavenProject project = projects.get(0); initLegacySupport(projects, project); mirrorDestinationDir = new File(project.getFile().getParent(), "target/repository").getCanonicalFile(); - FileUtils.deleteDirectory(mirrorDestinationDir); + if (mirrorDestinationDir.exists()) { + deleteFolder(mirrorDestinationDir.toPath()); + } mirrorMojo = lookupMojo("mirror", project.getFile()); setVariableValueToObject(mirrorMojo, "destination", mirrorDestinationDir); setVariableValueToObject(mirrorMojo, "project", project); } + private static void deleteFolder(final Path path) throws IOException { + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException e) { + return FileVisitResult.TERMINATE; + } + + @Override + public FileVisitResult postVisitDirectory(final Path dir, final IOException e) throws IOException { + if (e != null) { + return FileVisitResult.TERMINATE; + } + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } + @Override protected void tearDown() throws Exception { // this is needed because the DefaultEquinoxEmbedder plexus component