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

Cleanup and fix build failures in reserved project names PR #1

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/user/Installation.md
Expand Up @@ -28,6 +28,9 @@ For manual installation use one of the update sites below.

Eclipse Version | Type | Update Site
--------------- | ----------| ------------
2019-03 | snapshot | `http://download.eclipse.org/buildship/updates/e411/snapshots/3.x`
2019-03 | milestone | `http://download.eclipse.org/buildship/updates/e411/milestones/3.x`
2019-03 | release | `http://download.eclipse.org/buildship/updates/e411/releases/3.x`
2018-12 | snapshot | `http://download.eclipse.org/buildship/updates/e410/snapshots/3.x`
2018-12 | milestone | `http://download.eclipse.org/buildship/updates/e410/milestones/3.x`
2018-12 | release | `http://download.eclipse.org/buildship/updates/e410/releases/3.x`
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
@@ -1,5 +1,5 @@
# production library version numbers
toolingApiVersion=5.4
toolingApiVersion=5.5-20190430153457+0000

# testing library version numbers
slf4jLibVersion=1.7.2
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.buildship.branding/META-INF/MANIFEST.MF
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Buildship, Eclipse Plug-ins for Gradle
Bundle-SymbolicName: org.eclipse.buildship.branding;singleton:=true
Bundle-Version: 3.0.2.qualifier
Bundle-Version: 3.1.1.qualifier
Bundle-Vendor: Eclipse Buildship
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ClassPath: .
2 changes: 1 addition & 1 deletion org.eclipse.buildship.core.test/META-INF/MANIFEST.MF
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Buildship, Eclipse Plug-ins for Gradle - Core Test
Bundle-SymbolicName: org.eclipse.buildship.core.test;singleton:=true
Bundle-Version: 3.0.2.qualifier
Bundle-Version: 3.1.1.qualifier
Bundle-Vendor: Eclipse Buildship
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Fragment-Host: org.eclipse.buildship.core
Expand Down
Expand Up @@ -25,7 +25,7 @@ class ImportingMultipleBuildsWithClashingNames extends ProjectSynchronizationSpe

// TODO (donat) the test randomly imports subprojects from project 'second'
// ensure that the project synchronization is ordered
def "Same subproject names in different builds interrupt the project synchronization"() {
def "Same subproject names in different builds are deduplicated"() {
setup:
def firstProject = dir('first') {
dir 'sub/subsub'
Expand All @@ -49,7 +49,14 @@ class ImportingMultipleBuildsWithClashingNames extends ProjectSynchronizationSpe
SynchronizationResult result = tryImportAndWait(secondProject)

then:
result.status.severity == IStatus.WARNING
result.status.exception instanceof UnsupportedConfigurationException
result.status.severity == IStatus.OK
findProject('first')
findProject('sub')
findProject('subsub')

findProject('second')
findProject('second-sub')
findProject('sub-subsub')
}

}
@@ -0,0 +1,75 @@
package org.eclipse.buildship.core.internal.workspace

import org.eclipse.core.resources.IProject

import org.eclipse.buildship.core.internal.test.fixtures.ProjectSynchronizationSpecification

class ProjectNameDeduplicationTest extends ProjectSynchronizationSpecification {

def "Conflicts are resolved on import"() {
setup:
def location = dir('conflict-resolution-on-import') {
file 'settings.gradle', '''
rootProject.name = 'root'
include ':a'
'''
file 'build.gradle', ''
dir('a')
}
IProject project = newProject('a')

when:
importAndWait(location)

then:
findProject("root-a") != null
}

def "Conflicts are resolved on synchronization"() {
setup:
def location = dir('conflict-resolution-on-sync') {
file 'settings.gradle', '''
rootProject.name = 'root'
'''
file 'build.gradle', ''
dir('a')
}
IProject project = newProject('a')
importAndWait(location)

expect:
findProject("root-a") == null

when:
new File(location, 'settings.gradle') << "include ':a'"
synchronizeAndWait(location)

then:
findProject("root-a") != null
}

def "Names from model are deduplicated"() {
setup:
def location = dir('conflict-resolution-on-import') {
file 'settings.gradle', '''
rootProject.name = 'root'
include ':a'
'''
file 'build.gradle', '''
project(':a') {
apply plugin: 'eclipse'
eclipse.project.name='not-a'
}
'''
dir('a')
}
IProject project = newProject('not-a')

when:
importAndWait(location)

then:
findProject("root-not-a") != null
}

}
Expand Up @@ -11,6 +11,8 @@

package org.eclipse.buildship.core.internal.workspace

import org.gradle.tooling.BuildActionFailureException

import org.eclipse.buildship.core.SynchronizationResult
import org.eclipse.buildship.core.internal.UnsupportedConfigurationException
import org.eclipse.buildship.core.internal.test.fixtures.ProjectSynchronizationSpecification
Expand Down Expand Up @@ -47,7 +49,7 @@ class SynchronizingRenamedProject extends ProjectSynchronizationSpecification {
SynchronizationResult result = trySynchronizeAndWait(sample)

then:
result.status.exception instanceof UnsupportedConfigurationException
result.status.exception instanceof BuildActionFailureException
findProject('already-there') == alreadyThere
}

Expand Down
4 changes: 2 additions & 2 deletions org.eclipse.buildship.core/META-INF/MANIFEST.MF
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Buildship, Eclipse Plug-ins for Gradle - Core
Bundle-SymbolicName: org.eclipse.buildship.core;singleton:=true
Bundle-Version: 3.0.2.qualifier
Bundle-Version: 3.1.1.qualifier
Bundle-Vendor: Eclipse Buildship
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Activator: org.eclipse.buildship.core.internal.CorePlugin
Expand All @@ -16,7 +16,7 @@ Require-Bundle: org.eclipse.core.expressions,
org.eclipse.jdt.junit.core,
org.eclipse.jdt.launching,
org.eclipse.debug.core,
org.gradle.toolingapi;bundle-version="[5.4.0,5.5.0)";visibility:=reexport,
org.gradle.toolingapi;bundle-version="[5.5.0,5.6.0)";visibility:=reexport,
com.google.guava;bundle-version="[21.0.0,22.0.0)",
com.google.gson;bundle-version="[2.7.0,3.0.0)"
Bundle-ActivationPolicy: lazy
Expand Down
Expand Up @@ -9,10 +9,14 @@
package org.eclipse.buildship.core.internal.util.gradle;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collection;

import org.gradle.api.Action;
import org.gradle.tooling.BuildAction;
import org.gradle.tooling.ProjectConnection;

Expand All @@ -37,33 +41,71 @@ public class IdeFriendlyClassLoading {
private IdeFriendlyClassLoading() {
}

@SuppressWarnings("unchecked")
public static <T, U> BuildAction<Collection<T>> loadCompositeModelQuery(Class<T> model, Class<U> parameterType, Action<? super U> parameter) {
return (BuildAction<Collection<T>>) loadClass(CompositeModelQuery.class, new Object[] { model, parameterType, parameter });
}

@SuppressWarnings("unchecked")
public static <T> BuildAction<Collection<T>> loadCompositeModelQuery(Class<T> model) {
return (BuildAction<Collection<T>>) loadClass(CompositeModelQuery.class, model );
}

@SuppressWarnings("unchecked")
public static <T> T loadClass(Class<T> cls) {
try {
if (Platform.inDevelopmentMode()) {
Class<?> actionClass = loadClassWithIdeFriendlyClassLoader(CompositeModelQuery.class.getName());
return (BuildAction<Collection<T>>) actionClass.getConstructor(Class.class).newInstance(model);
return (T) loadClassWithIdeFriendlyClassLoader(cls.getName()).newInstance();
} else {
return new CompositeModelQuery<>(model);
return cls.newInstance();
}
} catch (Exception e) {
throw new GradlePluginsRuntimeException(e);
}
}

@SuppressWarnings("unchecked")
public static <T> T loadClass(Class<T> cls) {
public static <T> T loadClass(Class<T> cls, Object... arguments) {
try {
Class<T> theClass;
if (Platform.inDevelopmentMode()) {
return (T) loadClassWithIdeFriendlyClassLoader(cls.getName()).newInstance();
theClass = (Class<T>) loadClassWithIdeFriendlyClassLoader(cls.getName());
} else {
return cls.newInstance();
theClass = cls;
}
Class<?>[] parameterTypes = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) {
parameterTypes[i] = arguments[i].getClass();
}

Constructor<T> constructor = findConstructor(theClass, arguments);
return constructor.newInstance(arguments);
} catch (Exception e) {
throw new GradlePluginsRuntimeException(e);
}
}

@SuppressWarnings("unchecked")
private static <T> Constructor<T> findConstructor(Class<T> theClass, Object[] arguments) throws NoSuchMethodException {
for (Constructor<?> c : theClass.getConstructors()) {
if (c.getParameterCount() != arguments.length) {
continue;
}
Parameter[] parameters = c.getParameters();
boolean foundConstructor = true;
for (int i = 0; i < parameters.length; i++) {
if (!parameters[i].getType().isInstance(arguments[i])) {
foundConstructor = false;
break;
}
}
if (foundConstructor) {
return (Constructor<T>)c;
}
}
throw new NoSuchMethodException("Failed fo find constructor on " + theClass.getName() + " accepting " + Arrays.asList(arguments));
}

/**
* Closes IDE-friendly class loader.
* <p>
Expand Down
Expand Up @@ -33,17 +33,17 @@
import org.eclipse.buildship.core.ProjectConfigurator;
import org.eclipse.buildship.core.ProjectContext;
import org.eclipse.buildship.core.internal.CorePlugin;
import org.eclipse.buildship.core.internal.util.gradle.IdeFriendlyClassLoading;
import org.eclipse.buildship.core.internal.util.gradle.HierarchicalElementUtils;
public class BaseConfigurator implements ProjectConfigurator {

private Map<File, EclipseProject> locationToProject;

@Override
public void init(InitializationContext context, IProgressMonitor monitor) {
// TODO (donat) add required model declarations to the project configurator extension point
GradleBuild gradleBuild = context.getGradleBuild();
try {
Collection<EclipseProject> rootModels = gradleBuild.withConnection(connection -> connection.action(IdeFriendlyClassLoading.loadCompositeModelQuery(EclipseProject.class)).run(), monitor);
Collection<EclipseProject> rootModels = gradleBuild.withConnection(connection -> EclipseModelUtils.queryModels(connection), monitor);
this.locationToProject = rootModels.stream()
.flatMap(p -> HierarchicalElementUtils.getAll(p).stream())
.collect(Collectors.toMap(p -> p.getProjectDirectory(), p -> p));
Expand Down
Expand Up @@ -12,6 +12,7 @@
import java.util.Collection;
import java.util.Objects;

import org.gradle.api.Action;
import org.gradle.tooling.BuildAction;
import org.gradle.tooling.BuildController;
import org.gradle.tooling.model.gradle.GradleBuild;
Expand All @@ -22,14 +23,24 @@
* @param <T> The requested model type
* @author Donat Csikos
*/
public final class CompositeModelQuery<T> implements BuildAction<Collection<T>> {
public final class CompositeModelQuery<T, U> implements BuildAction<Collection<T>> {

private static final long serialVersionUID = 1L;

private final Class<T> modelType;

private final Action<? super U> parameter;

private Class<U> parameterType;

public CompositeModelQuery(Class<T> modelType) {
this(modelType, null, null);
}

public CompositeModelQuery(Class<T> modelType, Class<U> parameterType, Action<? super U> parameter) {
this.modelType = modelType;
this.parameterType = parameterType;
this.parameter = parameter;
}

@Override
Expand All @@ -40,7 +51,12 @@ public Collection<T> execute(BuildController controller) {
}

private void collectRootModels(BuildController controller, GradleBuild build, Collection<T> models) {
models.add(controller.getModel(build.getRootProject(), this.modelType));
if (this.parameter != null) {
models.add(controller.getModel(build.getRootProject(), this.modelType, this.parameterType, this.parameter));
} else {
models.add(controller.getModel(build.getRootProject(), this.modelType));

}

for (GradleBuild includedBuild : build.getIncludedBuilds()) {
collectRootModels(controller, includedBuild, models);
Expand All @@ -49,7 +65,7 @@ private void collectRootModels(BuildController controller, GradleBuild build, Co

@Override
public int hashCode() {
return Objects.hash(this.modelType);
return Objects.hash(this.modelType, this.parameter);
}

@Override
Expand All @@ -63,9 +79,8 @@ public boolean equals(Object obj) {
if (getClass() != obj.getClass()) {
return false;
}
CompositeModelQuery<?> other = (CompositeModelQuery<?>) obj;
return Objects.equals(this.modelType, other.modelType);
CompositeModelQuery<?, ?> other = (CompositeModelQuery<?, ?>) obj;
return Objects.equals(this.modelType, other.modelType) && Objects.equals(this.parameter, other.parameter);
}


}