diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/BundlePublisher.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/BundlePublisher.java index 3b034242c2..5880bddbde 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/BundlePublisher.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/BundlePublisher.java @@ -19,15 +19,24 @@ import java.util.Map.Entry; import java.util.Optional; +import org.apache.commons.io.FileUtils; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactDescriptor; +import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepositoryFactory; +import org.eclipse.equinox.internal.p2.metadata.repository.SimpleMetadataRepositoryFactory; +import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.equinox.p2.metadata.IArtifactKey; import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.publisher.IPublisherAction; import org.eclipse.equinox.p2.publisher.IPublisherAdvice; import org.eclipse.equinox.p2.publisher.IPublisherInfo; +import org.eclipse.equinox.p2.publisher.Publisher; import org.eclipse.equinox.p2.publisher.PublisherInfo; import org.eclipse.equinox.p2.publisher.actions.IPropertyAdvice; import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction; import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; +import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.tycho.core.resolver.target.FileArtifactRepository; import org.osgi.framework.BundleException; @@ -81,4 +90,42 @@ public static IInstallableUnit publishBundle(BundleDescription bundleDescription return iu; } + /** + * Creates a new bundle repository at the given location, if the location already exits it is + * deleted before performing the operation. + * + * @param repositoryLocation + * the location where the repository should be stored + * @param name + * the name of the repository + * @param files + * the files to consider as bundles to be installed in the new repository + * @param monitor + * the monitor to use for the operation + * @throws ProvisionException + * if creation of the repository failed + */ + public static void createBundleRepository(File repositoryLocation, String name, File[] files, + IProgressMonitor monitor) throws ProvisionException { + if (repositoryLocation.exists()) { + FileUtils.deleteQuietly(repositoryLocation); + } + SimpleMetadataRepositoryFactory metadataRepositoryFactory = new SimpleMetadataRepositoryFactory(); + SimpleArtifactRepositoryFactory artifactRepositoryFactory = new SimpleArtifactRepositoryFactory(); + IArtifactRepository artifactRepository = artifactRepositoryFactory.create(repositoryLocation.toURI(), name, + null, Map.of()); + IMetadataRepository metadataRepository = metadataRepositoryFactory.create(repositoryLocation.toURI(), name, + null, Map.of()); + metadataRepository.executeBatch(m1 -> { + artifactRepository.executeBatch(m2 -> { + PublisherInfo publisherInfo = new PublisherInfo(); + publisherInfo.setArtifactOptions(IPublisherInfo.A_INDEX | IPublisherInfo.A_PUBLISH); + publisherInfo.setArtifactRepository(artifactRepository); + publisherInfo.setMetadataRepository(metadataRepository); + Publisher publisher = new Publisher(publisherInfo); + publisher.publish(new IPublisherAction[] { new BundlesAction(files) }, m2); + }, m1); + }, monitor); + } + } diff --git a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java index 5b0657ffee..ccc5e9d9b2 100644 --- a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java +++ b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java @@ -16,23 +16,29 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.LegacySupport; +import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.core.IProvisioningAgentProvider; -import org.eclipse.osgi.service.environment.EnvironmentInfo; -import org.eclipse.tycho.TargetEnvironment; +import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.tycho.p2.CommandLineArguments; +import org.eclipse.tycho.p2.resolver.BundlePublisher; import org.eclipse.tycho.p2tools.TychoDirectorApplication; /** @@ -69,7 +75,7 @@ * * */ -@Mojo(name = "director", defaultPhase = LifecyclePhase.NONE, threadSafe = true, requiresProject = true) +@Mojo(name = "director", defaultPhase = LifecyclePhase.NONE, threadSafe = true, requiresProject = false) public class DirectorMojo extends AbstractMojo { @Component @@ -78,6 +84,12 @@ public class DirectorMojo extends AbstractMojo { @Component private IProvisioningAgentProvider agentProvider; + @Component + private LegacySupport legacySupport; + + @Component + private MojoExecution execution; + /** * The folder in which the targeted product is located. */ @@ -326,13 +338,20 @@ public class DirectorMojo extends AbstractMojo { @Parameter(property = "trustedCertificates") private String trustedCertificates; + /** + * If specified, the current project and its artifacts are included as part of the repository + * that is used to install units + */ + @Parameter() + private boolean includeProjectRepository; + @Override public void execute() throws MojoExecutionException, MojoFailureException { CommandLineArguments args = new CommandLineArguments(); args.addNonNull("-destination", destination); args.addNonNull("-metadatarepository", metadatarepositories); args.addNonNull("-artifactrepository", artifactrepositories); - args.addNonNull("-repository", repositories); + args.addNonNull("-repository", getRepositories()); args.addNotEmpty("-installIU", getUnitParameterList(installIUs, install), ","); args.addNotEmpty("-uninstallIU", getUnitParameterList(uninstallIUs, uninstall), ","); args.addNonNull("-revert", revert); @@ -375,6 +394,52 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } + private String getRepositories() { + File projectRepository = getProjectRepository(); + if (projectRepository != null) { + if (repositories == null) { + return projectRepository.getAbsoluteFile().toURI().toASCIIString(); + } + List list = new ArrayList(); + for (String repo : repositories.split(",")) { + list.add(repo.trim()); + } + list.add(projectRepository.getAbsoluteFile().toURI().toASCIIString()); + return list.stream().collect(Collectors.joining(",")); + } + return repositories; + } + + private File getProjectRepository() { + if (includeProjectRepository) { + MavenSession session = legacySupport.getSession(); + if (session != null) { + MavenProject currentProject = session.getCurrentProject(); + if (currentProject != null) { + + File[] files = Stream + .concat(Stream.of(currentProject.getArtifact()), + Stream.concat(currentProject.getAttachedArtifacts().stream(), + currentProject.getArtifacts().stream())) + .filter(Objects::nonNull).distinct().map(Artifact::getFile).filter(Objects::nonNull) + .filter(File::isFile).toArray(File[]::new); + if (files.length > 0) { + try { + File projectRepository = new File(currentProject.getBuild().getDirectory(), + execution.getExecutionId() + "-repo"); + BundlePublisher.createBundleRepository(projectRepository, execution.getExecutionId(), files, + null); + return projectRepository; + } catch (ProvisionException e) { + getLog().warn("Can't create the project repository!", e); + } + } + } + } + } + return null; + } + private Map getPropertyMap(String csvPropertiesMap, Map properties) { LinkedHashMap map = new LinkedHashMap(); if (csvPropertiesMap != null) {