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

Add support for TargetDefinition#implicitDependencies #4528

Merged
merged 1 commit into from
Dec 16, 2024
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
7 changes: 7 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@ If you are reading this in the browser, then you can quickly jump to specific ve

## 5.0.0 (under development)

## Support for implicit dependencies in target definitions

In target definitions Tycho now supports to use the `<implicitDependencies>`,
see [Eclipse Help](https://help.eclipse.org/latest/topic/org.eclipse.pde.doc.user/guide/tools/editors/target_editor/environment_page.htm)
for more details.

## Support for version ranges and no version for units in target definitions

In target definitions Tycho now supports to use a range as version of a unit or to skip the version entirely in `InstallableUnit` locations, just like Eclipse-PDE.
Specifying no version is equivalent to `0.0.0` which resolves to the latest version available.
All of the following variants to specify a version are now possible:

```
<target name="my-target">
<locations>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.DefaultArtifactKey;
import org.eclipse.tycho.OptionalResolutionAction;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.core.resolver.shared.IncludeSourceMode;
Expand Down Expand Up @@ -267,7 +270,9 @@ public DependencyResolverConfiguration getDependencyResolverConfiguration() {

@Override
public List<ArtifactKey> getAdditionalArtifacts() {
return extraRequirements;
Stream<DefaultArtifactKey> targetFiles = getTargets().stream().flatMap(tdf -> tdf.implicitDependencies())
.map(id -> new DefaultArtifactKey(ArtifactType.TYPE_ECLIPSE_PLUGIN, id.getId()));
return Stream.concat(extraRequirements.stream(), targetFiles).distinct().toList();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*******************************************************************************
* Copyright (c) 2024 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.core.osgitools.targetplatform;

import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.ClasspathEntry;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TargetPlatform;
import org.eclipse.tycho.classpath.ClasspathContributor;
import org.eclipse.tycho.core.TargetPlatformConfiguration;
import org.eclipse.tycho.core.TychoProjectManager;
import org.eclipse.tycho.targetplatform.TargetDefinition.ImplicitDependency;

@Component(role = ClasspathContributor.class, hint = "target-platform")
public class TargetPlatformClasspathContributor implements ClasspathContributor {

@Requirement
private Logger logger;

@Requirement
private TychoProjectManager projectManager;

@Override
public List<ClasspathEntry> getAdditionalClasspathEntries(MavenProject project, String scope) {

TargetPlatform platform = projectManager.getTargetPlatform(project).orElse(null);
if (platform == null) {
return List.of();
}
TargetPlatformConfiguration configuration = projectManager.getTargetPlatformConfiguration(project);
List<ImplicitDependency> dependencies = configuration.getTargets().stream()
.flatMap(tdf -> tdf.implicitDependencies()).distinct().toList();
return dependencies.stream().map(dependency -> getClasspathEntry(platform, dependency)).filter(Objects::nonNull)
.toList();
}

private ClasspathEntry getClasspathEntry(TargetPlatform targetPlatform, ImplicitDependency dependency) {
try {
ArtifactKey key = targetPlatform.resolveArtifact(ArtifactType.TYPE_ECLIPSE_PLUGIN, dependency.getId(),
null);

return new TargetPlatformClasspathEntry(targetPlatform, key);
} catch (Exception e) {
logger.warn("Can't resolve ImplicitDependency with id " + dependency.getId(), e);
return null;
}
}

private static final class TargetPlatformClasspathEntry implements ClasspathEntry {
private final TargetPlatform targetPlatform;
private final ArtifactKey key;
private List<File> files;

private TargetPlatformClasspathEntry(TargetPlatform targetPlatform, ArtifactKey key) {
this.targetPlatform = targetPlatform;
this.key = key;
}

@Override
public ReactorProject getMavenProject() {
return null;
}

@Override
public synchronized List<File> getLocations() {
if (files == null) {
File file = targetPlatform.getArtifactLocation(getArtifactKey());
if (file == null) {
files = List.of();
} else {
files = List.of(file);
}
}
return files;
}

@Override
public ArtifactKey getArtifactKey() {
return key;
}

@Override
public Collection<AccessRule> getAccessRules() {
return null;
}

@Override
public String toString() {
return "TargetPlatformClasspathEntry[" + key + "]";
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
Expand Down Expand Up @@ -303,6 +304,11 @@ public String getTargetEE() {
return null;
}

@Override
public Stream<ImplicitDependency> implicitDependencies() {
return Stream.empty();
}

}

enum TestRepositories {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;

import javax.inject.Inject;
import javax.inject.Named;
Expand Down Expand Up @@ -215,6 +216,11 @@ public String getTargetEE() {
return delegate.getTargetEE();
}

@Override
public Stream<ImplicitDependency> implicitDependencies() {
return delegate.implicitDependencies();
}

}

private static final class LatestVersionLocation implements InstallableUnitLocation {
Expand Down
11 changes: 10 additions & 1 deletion tycho-its/projects/compiler.annotations/annotations.target
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
<?pde version="3.8"?>
<target name="annotations">
<locations>
<location includeDependencyDepth="none" includeSource="true" missingManifest="error" type="Maven">
<location includeDependencyDepth="none" includeDependencyScopes="compile" missingManifest="error" type="Maven">
<dependencies>
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.annotation</artifactId>
<version>2.3.100</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.annotation.bundle</artifactId>
Expand All @@ -19,4 +25,7 @@
</dependencies>
</location>
</locations>
<implicitDependencies>
<plugin id="org.eclipse.jdt.annotation"/>
</implicitDependencies>
</target>
10 changes: 1 addition & 9 deletions tycho-its/projects/compiler.annotations/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,8 @@
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
<tycho-version>3.0.0-SNAPSHOT</tycho-version>
<repo-url>https://download.eclipse.org/releases/2022-03/</repo-url>
<tycho-version>5.0.0-SNAPSHOT</tycho-version>
</properties>
<repositories>
<repository>
<id>featureRepo</id>
<layout>p2</layout>
<url>${repo-url}</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package test.jdt.annotations;

import org.eclipse.jdt.annotation.Nullable;

public class TestJDT {

public void callMeWithNull(@Nullable Object obj) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,25 @@ public void testOSGiAnnotations() throws Exception {
assertTrue(dependencies.getAbsoluteFile() + " not found!", dependencies.isFile());
List<String> lines = Files.readAllLines(dependencies.toPath());
String collect = lines.stream().collect(Collectors.joining(",\r\n"));
// TODO we should possibly accept others that supply the ds annotations here?
assertTrue("org.eclipse.osgi.services not found in dependencies: " + collect,
lines.stream().anyMatch(s -> s.contains("org.eclipse.osgi.services")));
lines.stream().anyMatch(s -> s.contains("org.osgi.service.component.annotations")));
assertTrue("org.osgi.annotation.bundle not found in dependencies: " + collect,
lines.stream().anyMatch(s -> s.contains("org.osgi.annotation.bundle")));
assertTrue("org.osgi.annotation.versioning not found in dependencies: " + collect,
lines.stream().anyMatch(s -> s.contains("org.osgi.annotation.versioning")));
}

@Test
public void testImplicitJDTAnnotations() throws Exception {
Verifier verifier = getVerifier("compiler.annotations", false, true);
verifier.executeGoal("verify");
verifier.verifyErrorFreeLog();
File dependencies = new File(verifier.getBasedir(), "target/dependencies-list.txt");
assertTrue(dependencies.getAbsoluteFile() + " not found!", dependencies.isFile());
List<String> lines = Files.readAllLines(dependencies.toPath());
String collect = lines.stream().collect(Collectors.joining(",\r\n"));
assertTrue("org.eclipse.osgi.services not found in dependencies: " + collect,
lines.stream().anyMatch(s -> s.contains("org.eclipse.jdt.annotation")));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.stream.Stream;

import org.eclipse.tycho.IArtifactFacade;
import org.eclipse.tycho.MavenArtifactRepositoryReference;
Expand Down Expand Up @@ -54,9 +55,21 @@ public interface TargetDefinition {
@Override
public boolean equals(Object obj);

/**
*
* @return a stream of implicit dependencies defined in the target to add as an
* additional dependency to every project
*/
Stream<ImplicitDependency> implicitDependencies();

@Override
public int hashCode();

public interface ImplicitDependency {

String getId();
}

public interface Location {

/**
Expand Down
Loading
Loading