Skip to content

Commit

Permalink
TYCHO-570 Make published artifacts available in build
Browse files Browse the repository at this point in the history
- Register the p2 artifact repository with the published bundles in
  a central registry (the ArtifactRepositoryBlackboard). The
  blackboard implements the artifact repository factory extension
  point and therefore the registered artifact repositories can be
  loaded through the normal p2 APIs.
- The artifact repositories are registered under a special key (see
  RepositoryBlackboardKey) which is unique for each module.
- The p2 Mojos include the artifact repository with the published
  bundles of the current module by adding the special key as
  source/context p2 repository. Through this, POM dependency
  artifacts can for example be mirrored into an eclipse-repository.

This commit resolves TYCHO-570 aka bug 342851.

Bug: 342851 Artifacts from POM dependencies missing in eclipse-repository
  • Loading branch information
oberlies committed May 26, 2011
1 parent 7b6273b commit b005616
Show file tree
Hide file tree
Showing 20 changed files with 313 additions and 17 deletions.
@@ -0,0 +1 @@
bin.includes = feature.xml
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="pomDependencyConsider.p2Data.generate.feature"
label="Feature"
version="0.0.1.qualifier">

<description url="http://www.example.com/description">
[Enter Feature Description here.]
</description>

<copyright url="http://www.example.com/copyright">
[Enter Copyright Description here.]
</copyright>

<license url="http://www.example.com/license">
[Enter License Description here.]
</license>

<plugin
id="com.google.gson"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

</feature>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>tycho-its-project.pomDependencyConsider.p2Data.generate</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>pomDependencyConsider.p2Data.generate.feature</artifactId>
<packaging>eclipse-feature</packaging>

</project>
46 changes: 46 additions & 0 deletions tycho-its/projects/pomDependencyConsider.p2Data.generate/pom.xml
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>

<groupId>tycho-its-project.pomDependencyConsider.p2Data.generate</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
<module>feature</module>
<module>repository</module>
</modules>

<dependencies>
<!-- The test uses this artifact for the following reasons:
* The artifact is an OSGi bundle not built by Tycho. There is no p2 data deployed
with the artifact. Since the Tycho p2 Mojos expect that p2 data exists for all
external content in the target platform, that data needs to be generated on the
fly by the dependency resolver. -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.6</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<pomDependencies>consider</pomDependencies>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<site>
<feature
url="features/pomDependencyConsider.p2Data.generate.feature_0.0.0.jar"
id="pomDependencyConsider.p2Data.generate.feature" version="0.0.0" />
</site>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>tycho-its-project.pomDependencyConsider.p2Data.generate</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>repository</artifactId>
<packaging>eclipse-repository</packaging>

</project>
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2011 SAP AG 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:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.test.pomDependencyConsider.p2Data.generate;

import java.io.File;

import org.apache.maven.it.Verifier;
import org.eclipse.tycho.test.AbstractTychoIntegrationTest;
import org.eclipse.tycho.test.util.P2RepositoryTool;
import org.junit.Assert;
import org.junit.Test;

public class PomDependencyOnNonTychoArtifactTest extends AbstractTychoIntegrationTest {
private static final String POM_DEPENDENCY_BUNDLE_ID = "com.google.gson";
private static final String POM_DEPENDENCY_BUNDLE_VERSION = "1.6.0";

@Test
public void testP2DataGeneratedForPomDependency() throws Exception {
// project with a POM dependency on a bundle not built by Tycho
Verifier verifier = getVerifier("pomDependencyConsider.p2Data.generate", false);

verifier.executeGoal("verify");
verifier.verifyErrorFreeLog();

String testProjectRoot = verifier.getBasedir();
P2RepositoryTool p2Repo = P2RepositoryTool.forEclipseRepositoryModule(new File(testProjectRoot, "repository"));

// this was bug TYCHO-570: the build passed, but the POM dependency bundle was missing
File expectedBundle = p2Repo.getBundleArtifact(POM_DEPENDENCY_BUNDLE_ID, POM_DEPENDENCY_BUNDLE_VERSION);
Assert.assertTrue(expectedBundle.isFile());
}
}
Expand Up @@ -2,7 +2,8 @@ Manifest-Version: 1.0
Export-Package: org.eclipse.tycho.core.facade,
org.eclipse.tycho.p2.metadata,
org.eclipse.tycho.p2.repository,
org.eclipse.tycho.p2.resolver.facade
org.eclipse.tycho.p2.resolver.facade,
org.eclipse.tycho.repository.registry.facade
Bundle-Version: 0.13.0.qualifier
Bundle-Name: Tycho p2 Resolver Maven/OSGi Facade (Incubation)
Bundle-ManifestVersion: 2
Expand Down
@@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2011 SAP AG 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:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.repository.registry.facade;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;

public class RepositoryBlackboardKey {

// TODO p2 bug 347319 prevents using a special scheme, that will ensure that only our p2 repository factory load the blackboard key URIs
//public static String SCHEME = "registry";
public static String SCHEME = "file";

private final URI uri;

private RepositoryBlackboardKey(URI uri) {
this.uri = uri;
}

public URI toURI() {
return uri;
}

/**
* Creates a key under which the POM dependency artifacts of the resolution context (which is a
* superset of the target platform) of a project are available as p2 repository.
*/
public static RepositoryBlackboardKey forResolutionContextArtifacts(File projectLocation) {
try {
return new RepositoryBlackboardKey(
new URI(SCHEME, "/resolution-context-artifacts@" + projectLocation, null));
} catch (URISyntaxException e) {
// the used constructor escapes invalid characters, so I don't see this happening
throw new RuntimeException(e);
}
}

@Override
public String toString() {
return getClass().getName() + "(uri=" + uri + ")";
}
}
Expand Up @@ -9,5 +9,6 @@ Export-Package: org.eclipse.tycho.p2.tools,
org.eclipse.tycho.p2.tools.director,
org.eclipse.tycho.p2.tools.mirroring,
org.eclipse.tycho.p2.tools.publisher
Import-Package: org.eclipse.tycho.p2.repository
Import-Package: org.eclipse.tycho.p2.repository,
org.eclipse.tycho.repository.registry.facade
Bundle-Vendor: %providerName
Expand Up @@ -16,6 +16,8 @@
import java.util.Collections;
import java.util.List;

import org.eclipse.tycho.repository.registry.facade.RepositoryBlackboardKey;

/**
* List of p2 repositories for a p2 operation. Instances of this class store a list of metadata and
* artifact repositories each, preserving the order in which the repositories were added.
Expand Down Expand Up @@ -46,6 +48,16 @@ public void addArtifactRepository(File artifactRepositoryLocation) {
artifactRepos.add(artifactRepositoryLocation.toURI());
}

/**
* Adds the artifact repository which is stored in memory under the given key.
*
* @param artifactRepositoryLocation
* A key identifying a repository registered on the artifact repository blackboard.
*/
public void addArtifactRepository(RepositoryBlackboardKey blackboardKey) {
artifactRepos.add(blackboardKey.toURI());
}

/**
* Returns the list of metadata repositories in the order in which they were added.
*
Expand Down
Expand Up @@ -14,8 +14,10 @@ Require-Bundle: org.eclipse.equinox.common;bundle-version="3.5.0",
org.eclipse.equinox.p2.artifact.repository;bundle-version="1.1.0"
Export-Package: org.eclipse.tycho.p2.maven.repository,
org.eclipse.tycho.p2.maven.repository.xmlio;x-friends:="org.eclipse.tycho.p2.maven.repository.tests",
org.eclipse.tycho.p2.util
org.eclipse.tycho.p2.util,
org.eclipse.tycho.repository.registry.impl
Import-Package: org.eclipse.osgi.util,
org.eclipse.tycho.p2.repository,
org.eclipse.tycho.repository.registry.facade,
org.osgi.framework
Bundle-Activator: org.eclipse.tycho.p2.maven.repository.Activator
Expand Up @@ -30,6 +30,15 @@
suffix="p2artifacts.xml">
</filter>
</extension>
<extension
id="org.eclipse.tycho.repository.registry.impl.ArtifactRepositoryBlackboard"
point="org.eclipse.equinox.p2.artifact.repository.artifactRepositories">
<factory
class="org.eclipse.tycho.repository.registry.impl.ArtifactRepositoryBlackboard">
</factory>
<filter
suffix="@memory"/>
</extension>
<extension
id="org.eclipse.tycho.p2.maven.repository.ModuleMetadataRepository"
point="org.eclipse.equinox.p2.metadata.repository.metadataRepositories">
Expand Down
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2011 SAP AG 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:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.repository.registry.impl;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactRepositoryFactory;
import org.eclipse.tycho.repository.registry.facade.RepositoryBlackboardKey;
import org.eclipse.tycho.repository.util.RepositoryFactoryTools;

public class ArtifactRepositoryBlackboard extends ArtifactRepositoryFactory {

private static HashMap<URI, IArtifactRepository> registry = new HashMap<URI, IArtifactRepository>();

public static synchronized void putRepository(RepositoryBlackboardKey key, IArtifactRepository repository) {
registry.put(key.toURI(), repository);
}

@Override
public IArtifactRepository create(URI location, String name, String type, Map<String, String> properties)
throws ProvisionException {
throw RepositoryFactoryTools.unsupportedCreation(getClass());
}

@Override
public IArtifactRepository load(URI location, int flags, IProgressMonitor monitor) throws ProvisionException {
if (RepositoryBlackboardKey.SCHEME.equals(location.getScheme())) {
return getRegisteredRepositoryOrNull(location, getAgent());
}
return null;
}

private static synchronized IArtifactRepository getRegisteredRepositoryOrNull(URI location, IProvisioningAgent agent)
throws ProvisionException {
return registry.get(location);
}

}
Expand Up @@ -41,10 +41,18 @@ public static void verifyModifiableNotRequested(int flags, String repositoryType
}

public static ProvisionException unsupportedCreation(String repositoryType) {
String message = "Cannot create repositories of type " + repositoryType;
return new ProvisionException(newUnsupportedCreationStatus(message));
}

public static ProvisionException unsupportedCreation(Class<?> factoryClass) {
String message = "The factory " + factoryClass.getName() + " cannot create repositories";
return new ProvisionException(newUnsupportedCreationStatus(message));
}

private static Status newUnsupportedCreationStatus(String message) {
// none of the codes defined in ProvisionException really fit
int errorCode = 0;
Status errorStatus = new Status(IStatus.ERROR, Activator.ID, errorCode, "Cannot create repositories of type "
+ repositoryType, null);
return new ProvisionException(errorStatus);
return new Status(IStatus.ERROR, Activator.ID, errorCode, message, null);
}
}
Expand Up @@ -32,7 +32,8 @@ Export-Package: org.eclipse.tycho.p2.impl;x-friends:="org.eclipse.tycho.p2.impl.
Import-Package: org.eclipse.tycho.core.facade,
org.eclipse.tycho.p2.metadata,
org.eclipse.tycho.p2.repository,
org.eclipse.tycho.p2.resolver.facade
org.eclipse.tycho.p2.resolver.facade,
org.eclipse.tycho.repository.registry.facade
Service-Component: OSGI-INF/generator.xml,
OSGI-INF/metadataserializable.xml,
OSGI-INF/proxyfacade.xml,
Expand Down
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.metadata.MetadataFactory;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
import org.eclipse.tycho.core.facade.MavenLogger;
import org.eclipse.tycho.p2.metadata.IArtifactFacade;
Expand All @@ -33,6 +34,8 @@
import org.eclipse.tycho.p2.resolver.facade.P2Resolver;
import org.eclipse.tycho.p2.resolver.facade.ResolutionContext;
import org.eclipse.tycho.p2.resolver.impl.ResolutionContextImpl;
import org.eclipse.tycho.repository.registry.facade.RepositoryBlackboardKey;
import org.eclipse.tycho.repository.registry.impl.ArtifactRepositoryBlackboard;

@SuppressWarnings("restriction")
public class P2ResolverImpl implements P2Resolver {
Expand Down Expand Up @@ -101,6 +104,12 @@ protected P2ResolutionResult resolveProject(File projectLocation, ResolutionStra

context.downloadArtifacts(newState);

// TODO check if needed by all callers
IArtifactRepository resolutionContextArtifactRepo = context.getSupplementaryArtifactRepository();
RepositoryBlackboardKey blackboardKey = RepositoryBlackboardKey.forResolutionContextArtifacts(projectLocation);
ArtifactRepositoryBlackboard.putRepository(blackboardKey, resolutionContextArtifactRepo);
logger.debug("Registered artifact repository " + blackboardKey);

return toResolutionResult(newState);
}

Expand All @@ -117,6 +126,7 @@ private P2ResolutionResult toResolutionResult(Collection<IInstallableUnit> newSt
}
}

// TODO instead of adding them to the TP, we could also register it in memory as metadata repo
collectNonReactorIUs(result, newState);
return result;
}
Expand Down

0 comments on commit b005616

Please sign in to comment.