Skip to content
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

[tycho-4.0.x] Make the repository format pluggable #2643

Merged
merged 1 commit into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions demo/osgi-repository/repository/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,24 @@
<version>${tycho-version}</version>
<!-- Extensions must be enabled for this mojo to work reliable and for using the custom package type-->
<extensions>true</extensions>
<configuration>
<!-- Another option would be using 'local' -->
<repositoryLayout>maven</repositoryLayout>
</configuration>
<!-- EVERYTHING BELOW IS OPTIONAL -->
<!-- This is just used to show different options of the configuration and can be ommited if only a bare maven-repository is desired with default settings -->
<executions>
<!-- Additionally we create another repository using the 'local' layout and place it in a deploy folder -->
<execution>
<id>local</id>
<phase>package</phase>
<goals>
<goal>package-repository</goal>
</goals>
<configuration>
<repositoryLayout>local</repositoryLayout>
<settings>
<repositoryFolderName>deploy</repositoryFolderName>
</settings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Expand Down
5 changes: 5 additions & 0 deletions tycho-repository-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-spi</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*******************************************************************************
* Copyright (c) 2023 Christoph Läubrich and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.repository.plugin;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.eclipse.tycho.MavenArtifactNamespace;
import org.eclipse.tycho.packaging.RepositoryGenerator;

import aQute.bnd.osgi.repository.XMLResourceGenerator;
import aQute.bnd.osgi.resource.CapReqBuilder;
import aQute.bnd.osgi.resource.ResourceBuilder;

@Component(role = RepositoryGenerator.class, hint = OSGiRepositoryGenerator.HINT)
public class OSGiRepositoryGenerator implements RepositoryGenerator {

static final String HINT = "osgi";

@Override
public File createRepository(List<MavenProject> projects, RepositoryConfiguration repoConfig)
throws IOException, MojoExecutionException, MojoFailureException {
XMLResourceGenerator resourceGenerator = new XMLResourceGenerator();
resourceGenerator.name(repoConfig.getRepositoryName());
File folder;
PlexusConfiguration generatorConfig = repoConfig.getConfiguration();
String repositoryFileName = generatorConfig.getChild("repositoryFileName")
.getValue("repository.xml");
if (repoConfig.getLayout() == RepositoryLayout.local) {
String folderName = generatorConfig.getChild("repositoryFolderName")
.getValue(FilenameUtils.getBaseName(repositoryFileName));
folder = new File(repoConfig.getDestination(), folderName);
folder.mkdirs();
resourceGenerator.base(folder.toURI());
} else {
folder = null;
}
Log log = repoConfig.getLog();
for (MavenProject project : projects) {
ResourceBuilder rb = new ResourceBuilder();
try {
URI uri;
File file = project.getArtifact().getFile();
if (folder == null) {
uri = new URI(
"mvn:" + project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion());
} else {
uri = new File(folder, file.getName()).toURI();
}
if (rb.addFile(project.getArtifact().getFile(), uri)) {
CapReqBuilder identity = new CapReqBuilder(MavenArtifactNamespace.MAVEN_ARTIFACT_NAMESPACE)
.addAttribute(MavenArtifactNamespace.CAPABILITY_GROUP_ATTRIBUTE, project.getGroupId())
.addAttribute(MavenArtifactNamespace.MAVEN_ARTIFACT_NAMESPACE, project.getArtifactId())
.addAttribute(MavenArtifactNamespace.CAPABILITY_VERSION_ATTRIBUTE, project.getVersion());
rb.addCapability(identity);
resourceGenerator.resource(rb.build());
log.info("Adding " + project.getId());
if (folder != null) {
FileUtils.copyFileToDirectory(file, folder);
}
} else {
log.info("Skip " + project.getId() + ": Not a bundle");
}
} catch (Exception e) {
log.warn("Ignoring " + project.getId() + ": " + e, log.isDebugEnabled() ? e : null);
}
}
if (folder != null) {
File location = new File(folder, repositoryFileName);
resourceGenerator.save(location);
return folder;
} else {
File location = new File(repoConfig.getDestination(), repositoryFileName);
resourceGenerator.save(location);
return location;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,44 @@

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.zip.ZipArchiver;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.MavenArtifactNamespace;

import aQute.bnd.osgi.repository.XMLResourceGenerator;
import aQute.bnd.osgi.resource.CapReqBuilder;
import aQute.bnd.osgi.resource.ResourceBuilder;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.eclipse.tycho.packaging.RepositoryGenerator;
import org.eclipse.tycho.packaging.RepositoryGenerator.RepositoryConfiguration;
import org.eclipse.tycho.packaging.RepositoryGenerator.RepositoryLayout;

/**
* Generates an OSGi repository from the current reactor projects
*
*/
@Mojo(name = "package-repository")
public class PackageRepositoryMojo extends AbstractMojo {
public class PackageRepositoryMojo extends AbstractMojo implements RepositoryConfiguration {

private static final XmlPlexusConfiguration NO_SETTINGS = new XmlPlexusConfiguration("settings");

static final String DEFAULT_REPOSITORY_TYPE = OSGiRepositoryGenerator.HINT;

static final String PARAMETER_REPOSITORY_TYPE = "repositoryType";

@Parameter(property = "session", readonly = true)
protected MavenSession session;
Expand All @@ -56,13 +64,6 @@ public class PackageRepositoryMojo extends AbstractMojo {
@Parameter(defaultValue = "${project.name}")
private String repositoryName;

/**
* Specify the filename of the additionally generated OSGi Repository (if
* enabled)
*/
@Parameter(defaultValue = "repository.xml")
private String repositoryFileName;

@Parameter(defaultValue = "${project.build.directory}")
private File destination;

Expand All @@ -82,82 +83,95 @@ public class PackageRepositoryMojo extends AbstractMojo {
@Parameter(defaultValue = "maven")
private RepositoryLayout repositoryLayout;

/**
* Configures the used repository type
*/
@Parameter(defaultValue = DEFAULT_REPOSITORY_TYPE, name = PARAMETER_REPOSITORY_TYPE)
private String repositoryType;

@Parameter(property = "mojoExecution", readonly = true)
MojoExecution execution;

/**
* Configures the repository type specific settings.
*/
@Parameter
private PlexusConfiguration settings;

@Component(role = Archiver.class, hint = "zip")
private ZipArchiver zipArchiver;

@Component(role = RepositoryGenerator.class)
private Map<String, RepositoryGenerator> generators;

@Component
private MavenProjectHelper mavenProjectHelper;

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
XMLResourceGenerator resourceGenerator = new XMLResourceGenerator();
resourceGenerator.name(repositoryName);
File folder;
if (repositoryLayout == RepositoryLayout.local) {
folder = new File(destination, FilenameUtils.getBaseName(repositoryFileName));
folder.mkdirs();
resourceGenerator.base(folder.toURI());
} else {
folder = null;
}
for (MavenProject project : session.getProjects()) {
if (isInteresting(project)) {
ResourceBuilder rb = new ResourceBuilder();
try {
URI uri;
File file = project.getArtifact().getFile();
if (folder == null) {
uri = new URI("mvn:" + project.getGroupId() + ":" + project.getArtifactId() + ":"
+ project.getVersion());
} else {
uri = new File(folder, file.getName()).toURI();
}
if (rb.addFile(project.getArtifact().getFile(), uri)) {
CapReqBuilder identity = new CapReqBuilder(MavenArtifactNamespace.MAVEN_ARTIFACT_NAMESPACE)
.addAttribute(MavenArtifactNamespace.CAPABILITY_GROUP_ATTRIBUTE, project.getGroupId())
.addAttribute(MavenArtifactNamespace.MAVEN_ARTIFACT_NAMESPACE, project.getArtifactId())
.addAttribute(MavenArtifactNamespace.CAPABILITY_VERSION_ATTRIBUTE,
project.getVersion());
rb.addCapability(identity);
resourceGenerator.resource(rb.build());
getLog().info("Adding " + project.getId());
if (folder != null) {
FileUtils.copyFileToDirectory(file, folder);
}
} else {
getLog().info("Skip " + project.getId() + ": Not a bundle");
}
} catch (Exception e) {
Log log = getLog();
log.warn("Ignoring " + project.getId() + ": " + e, log.isDebugEnabled() ? e : null);
}
}
RepositoryGenerator generator = generators.get(repositoryType);
if (generator == null) {
throw new MojoFailureException(
"No repository implementation of type " + repositoryType + " found, available ones are "
+ generators.keySet().stream().sorted().collect(Collectors.joining(", ")));
}
List<MavenProject> projects = session.getProjects().stream().filter(generator::isInteresting).toList();
try {
Artifact artifact = project.getArtifact();
if (folder != null) {
File location = new File(folder, repositoryFileName);
resourceGenerator.save(location);
File destFile = new File(destination, project.getArtifactId() + "-" + folder.getName() + ".zip");
zipArchiver.addDirectory(folder);
File repository = generator.createRepository(projects, this);
String executionId = execution.getExecutionId();
if (repository.isDirectory()) {
File destFile = new File(destination, project.getArtifactId() + "-" + repository.getName() + ".zip");
zipArchiver.addDirectory(repository);
zipArchiver.setDestFile(destFile);
zipArchiver.createArchive();
artifact.setFile(destFile);
artifact.setArtifactHandler(new DefaultArtifactHandler("zip"));
if (executionId.startsWith("default-")) {
Artifact artifact = project.getArtifact();
artifact.setFile(destFile);
artifact.setArtifactHandler(new DefaultArtifactHandler("zip"));
} else {
mavenProjectHelper.attachArtifact(project, "zip", executionId, destFile);
}
} else {
File location = new File(destination, repositoryFileName);
resourceGenerator.save(location);
artifact.setArtifactHandler(new DefaultArtifactHandler("xml"));
artifact.setFile(location);
String extension = FilenameUtils.getExtension(repository.getName());
if (executionId.startsWith("default-")) {
Artifact artifact = project.getArtifact();
artifact.setArtifactHandler(new DefaultArtifactHandler(extension));
artifact.setFile(repository);
} else {
mavenProjectHelper.attachArtifact(project, extension, executionId, repository);
}
}
} catch (IOException e) {
throw new MojoExecutionException("Could not write OSGi Repository!", e);
throw new MojoExecutionException("Could not write repository!", e);
}
}

public static boolean isInteresting(MavenProject other) {
String packaging = other.getPackaging();
return "jar".equalsIgnoreCase(packaging) || "bundle".equalsIgnoreCase(packaging)
|| ArtifactType.TYPE_ECLIPSE_PLUGIN.equals(packaging)
|| ArtifactType.TYPE_BUNDLE_FRAGMENT.equals(packaging)
|| ArtifactType.TYPE_ECLIPSE_TEST_PLUGIN.equals(packaging);
@Override
public File getDestination() {
return destination;
}

@Override
public RepositoryLayout getLayout() {
return repositoryLayout;
}

@Override
public String getRepositoryName() {
return repositoryName;
}

@Override
public Log getLog() {
return super.getLog();
}

@Override
public PlexusConfiguration getConfiguration() {
if (settings == null) {
return NO_SETTINGS;
}
return settings;
}

}

This file was deleted.

Loading